bash寫作參考—設定檔異動檢查
在 linux 裡 /etc 這個目錄底下有很多設定檔都是擺在這兒。 /etc 這個目錄關乎整台 Server 運作的正常與否,設定好的話就沒事,若設定錯誤、或是你不小心改錯了設定檔…等等,都會造成 Server 無法正常運作,所以這個目錄的備份很重要。
怎麼備份呢?由於很多程式的設定檔都擱在 /etc 裡,所以我們每天都有可能動到一點這裡面的東西,所以我們就要寫個程式,檢查 /etc 底下的檔案有沒有異動,有就 copy 一份備份並在檔案的最後押上日期,這樣子做的話,我們每天改了什麼東西都會有跡可尋了 ,縱使一時失神改錯了東西,還能去歷史記錄查找以前修改過的記錄,或是被人入侵主機修改了某些設定檔,也能在歷史記錄檔查到修改的痕跡。
本程式需搭配 rsync 使用,沒有的話請自行安裝此程式吧。
本程式的運行環境為 LANG=zh_TW.UTF-8 中文語系,若你的系統為 ubuntu 8.04 以上或 debian 5 lenny 中文環境的話,則無需特殊設定即可運行。檢查方法請下指令 locale 看第一行的設定是否為 LANG=zh_TW.UTF-8
vim /root/backup/cfgchk.sh
#!/bin/bash # 程式說明:每日檢查/etc系統設定檔,若有異動則備份,並在檔名最後押上日期 # 版本: 2009/08/17 夢見草 # # 目錄設定說明 # /root/backup/config/compare/ 此為比對目錄,勿動 # /root/backup/config/history/ 此為存放歷史設定檔的目錄 # 第一次執行本程式,有以下設定要做 # 1.須建立一個比對清單,請下指令帶參數,例如: cfgchk.sh newlist # 2.依你的需求修改路徑變數 #路徑變數設定 compare=/root/backup/config/compare #請修改你比對目錄存放區,註意:此變數路徑的最後不要加 / 斜線 history=/root/backup/config/history # ↑ 設定存放歷史設定檔的目錄,註意:此變數路徑的最後不要加 / 斜線 date1=`date +%Y%m%d` #============ newlist ========================= #製作需備份(比對)清單 cfgBackup.list if [ "$1" == "newlist" ] ;then echo 開始產生新的比對清單... test -d $compare || mkdir -p $compare #cp /etc/* $compare -R # 以上指令為沒有裝 rsync 的備用方案 rsync /etc $compare -av -delete echo 新的比對清單產生完成! # ↓ 額外的比對清單 #cp `cat cfgBackup.list |grep -v '#'` /root/backup/config/compare/ -R # grep -v 為去除 # 為首的那一行 #echo `cat list |grep -v '_syscp_'` fi #============ newlist ========================= #################################以下開始為比對工作################################# # #1.比對工作:檢查目錄存在 #===========檢查 history 裡有沒有存在目錄,沒有的話,則建目錄============== # 比對 /etc 與 compare/etc 底下的檔案內容差異,若有差異則取出目錄變數後,建目錄 #diff -r /etc/ /root/backup/config/compare/etc/ |grep diff |awk '{printf $3 "\n"}' |sed 's/\(^\/.*\/\)\(.*\)/\1/' # 以上這行為測試指令,測試變數取得是否正確 for diffDir in `diff -r /etc/ $compare/etc/ |grep diff |awk '{printf $3 "\n"}' |sed 's/\(^\/.*\/\)\(.*\)/\1/'` do testExistDir=$history$diffDir # ↑ 將取出的目錄變數前面加上 要備份的路徑 #echo $OnlyExistDir #開始檢查目錄存在否,不存在則建目錄 test -d $testExistDir || mkdir -p $testExistDir done #比對 /etc 與 compare/etc 底下的檔案存在與否,若compare底下沒有此檔,則取出目錄變數後,建目錄 #適用於在 /etc/ppp/ 新建一個檔案 test.txt 而 compare/etc/ppp/ 沒有 test.txt 此檔的情況下 #diff -r /etc/ /root/backup/config/compare/etc/ |grep "只在" |sed 's/\(^只在 \)\(.*\)\(存在:\)/\2/'|grep ^/etc/ |awk '{printf $1 "\n"}' # ↑ 取出只在 /etc 的目錄變數 for existDir in `diff -r /etc/ $compare/etc/ |grep "只在" |sed 's/\(^只在 \)\(.*\)\(存在:\)/\2/'|grep ^/etc/ |awk '{printf $1 "\n"}'` do OnlyExistDir=$history$existDir # ↑ 將取出的目錄變數前面加上 要備份的路徑 #echo $testExistDir #開始檢查目錄存在否,不存在則建目錄 test -d $OnlyExistDir || mkdir -p $OnlyExistDir done #指令說明 # ↓ 取出比對後不存在目錄變數的指令 #diff -r /etc/ /root/backup/config/compare/etc/ |grep diff |awk '{printf $3 "\n"}' |sed 's/\(^\/.*\/\)\(.*\)/\1/' # |sed 's/\(^\/.*\/\)\(.*\)/\1/' →說明: 刪除第一個斜線/到最後一個/斜線以外的內容,以取出路徑名稱 #===========檢查 history 裡有沒有存在目錄,沒有的話,則建目錄============== #2.比對工作:檢查檔案存在否 #===========只存在於 /etc/ 而不在 $history 內的話,則 copy 一份到 history 裡去備份=========== #diff -r /etc/ /root/backup/config/compare/etc/ |grep "只在" |sed 's/\(^只在 \)\(.*\)\(存在:\)/\2/'|grep ^/etc/ |awk '{printf $1$2 "\n"}' # 以上這行為測試指令,測試變數取得是否正確 # | sed 's/\(^只在 \)\(.*\)\(存在:\)/\2/' →刪除變中帶的中文字串 # | grep ^/etc/ → 刪除變數中開動的字不是 /etc 的那幾行, for FileExist in `diff -r /etc/ $compare/etc/ |grep "只在" |sed 's/\(^只在 \)\(.*\)\(存在:\)/\2/'|grep ^/etc/ |awk '{printf $1"/"$2 "\n"}'` do cp $FileExist $history$FileExist done #===========只存在於 /etc/ 而不在 $history 內的話,則 copy 一份到 history 裡去備份=========== #3.比對工作:異動內容 #===========有異動,則備份並押上日期=================================== #diff -r /etc/ /root/backup/config/compare/etc/ |grep diff |awk '{printf $3 "\n"}' # 以上這行為測試指令,測試變數取得是否正確 for diffList in `diff -r /etc/ $compare/etc/ |grep diff |awk '{printf $3 "\n"}'` do cp -b -S .$date1 $diffList $history$diffList done #===========有異動,則備份並押上日期=================================== #echo 工作完成,更新比對目錄 rsync /etc /root/backup/config/compare/ -a -delete #rm -fr $compare/etc #cp /etc/* $compare -R # 以上指令為沒有裝 rsync 的備用方案 |
然後再此檔做一個連結放入 /etc/cron.daily 裡面去,它就會每天檢查一次了。
chmod 755 /root/backup/cfgchk.sh
ln -s /root/backup/cfgchk.sh /etc/cron.daily/cfgchk
注意:放到 /etc/cron.hourly cron.daily 等目錄裡的執行檔不能有附檔名 .sh 否則它不能正常的執行,這是 debian 系統的 bug
說明一下本程式的運作原理
(1).產生一份比對清單:
就是將現有的 /etc 內容整個 copy 一份到 /root/backup 底下,然後每次檢查時,都比對這兩個目錄的差異性。
(2). #1.比對工作:檢查目錄存在
取出路徑變數,並自動判斷是否要建目錄
由於我們在 /root/backup/config/history 這目錄裡,並不打算放上所有的 /etc 內容,只放有異動過的檔案。這樣在查記錄時才能一目瞭然。
因為在 copy 檔案時不能 copy 到一個不存在的目錄裡去,所以在 copy 前我們就要先檢查history裡的目錄是否存在,若沒有則建立。
(3). #2.比對工作:檢查檔案存在否
有時候我們不一定是修改某些設定檔的內容,而是直接新增一個設定檔。
所以要針對這情況做判斷。 (這種情況就會造成 diff 這個指令在比對差異時會回應不同的訊息)
簡單說就是: 若發現 /etc 底下多了一個檔案的話,則 copy 一份到 history 裡去
(4). #3.比對工作:異動內容
這個工作就是本程式的主要功能了,發現檔案有異動,則 copy 一份到 history 裡去,並在檔名的最後押上日期。
前面那麼多動作,都是為了要排除其它狀況,好讓這個主要的功能正常運行。
(5). 更新比對目錄
整個比對工作完成後,要將 compare 目錄更新到跟 /etc 一樣的狀態,才不會每次比對都不一樣。