Login  |  繁體中文
感謝您對「自由軟體鑄造場」的支持與愛護,十多年來「自由軟體鑄造場」受中央研究院支持,並在資訊科學研究所以及資訊科技創新研究中心執行,現已完成階段性的任務。 本網站預計持續維運至 2021年底,網站內容基本上不會再更動。
也紀念我們永遠的朋友 李士傑先生(Shih-Chieh Ilya Li)。
Previous Issue

用開源方案打造網站保鑣

隨著 Internet 的興起,有越來越多的企業擁有自己的網站。但或許是管理人力不足或疏於管理,以至於常常成為駭客覬覦的對象,常被入侵篡改網頁或被放置惡意程式(在筆者的服務經驗中,網站的危安事件以放置惡意程式和釣魚網頁占最大宗),但不論是何種形式的入侵,都會對企業的形象和商譽造成莫大的傷害。

有鑑於網路入侵問題嚴重,本文結合開源碼社群中的「完整性分析」工具和「遠端備份」工具實作一套網站保護系統。當網站內的資料被不正常更動時能即時地監控並立即回復。而在本系統中希望能夠具備下列幾項功能:

●  能即時地偵測網站內的資料更動情形,例如新增(檔案或目錄)、刪除(檔案或目錄)及修改檔案等。

●  當偵測到網頁資料被不正常地更動時,會啟動回復(Restore)系統,自動至遠端備份主機取得相關的備份資料,來回復被不正常更動的網頁資料。

 

這裡會使用到的開源碼程式如下表所示:

軟體名稱

說明

官方網站

Fedora 11

作業系統

https://fedoraproject.org

rsync

遠端備份軟體

https://rsync.samba.org

integrit

完整性分析軟體

https://sourceforge.net/projects/integrit/



※  安裝 integrit 完整性分析軟體


說到完整性分析工具,很多人第一時間想到的可能是Tripwire,Tripwire 是一個知名且功能強大的分整性分析工具,但相對地,其系統資源消耗較多且設定複雜,況且 Tripwire 目前已成為商業化軟體,因此這裡將介紹另一套具有相同功能但較為精緻的完整性分析工具integrit,integrit主要功能在於比對檔案系統是否有不正常的更動情形。

integrit 的工作原理是,在系統剛建立完成時(在乾淨的情況下)先建立一個基準系統狀態資料庫(在此稱為 known database)。比對時,先建立目前系統狀態資料庫(在此稱為 current database),並與 known database 進行比對。

如果基準系統狀態資料庫與目前系統狀態資料庫比對不一致,即表示目前的系統狀態有被更動過,integrit將會顯示出被更動的檔案或目錄。

由於 integrit 並未提供如 rpm 等包裝檔,所以要利用原始檔直接編譯,請至「https://sourceforge.net/projects/integrit/」取得最新版本的 integrit。截至目前為止,筆者取得的版本為4.1。

下載完成後,利用指令「configure && make && make install」安裝 integrit。完裝完成後,將產生 integrit 主程式。

另外,integrit 在「utils」目錄下提供了工具程式 i-viewdb 來查看資料庫的內容。可至「utils」目錄下直接執行指令「make」,即可編譯出 i-viewdb 執行檔。編譯成功後,繼續設定integrit的設定檔(/etc/integrit.conf),設定檔內容如下表所示。

 

參數名稱 意義
known 基準系統狀態資料庫,比對即以此資料庫為基準點(Baseline)
current 目前系統狀態資料庫,記錄目前系統的狀態
root 比對啟始目錄,integrit 會從此目錄往下遞迴開始比對。如設定為「/usr」,即每次比對均只會從「/usr」目錄以下開始遞迴比對
[RULE]格式如下:
[prefix] [檔名或目錄][switch]
可針對個別檔案或目錄設定特別的比對規則。

[prefix]規則意義是:
!:不比對該目錄或檔案,例如「!/usr/local」即表示不比對「/usr/local」目錄。
=:僅比對該目錄或檔案,如果設定為目錄,代表僅比對該目錄而不遞迴的往下比對子目錄,如設定為「=/usr/local」,則僅比對「/usr/local」目錄,但不繼續往下比對「/usr/local」下的子目錄。

[switch]參數說明如下:
s:檢查checksum是否有改變
i:檢查inode是否有改變
p:檢查權限permissions是否有改變
l:檢查link的數量(number of links)是否有改變
u:檢查uid是否有改變
g:檢查gid是否有改變
z:檢查檔案大小是否有改變
a:檢查存取時間是否有改變
m:檢查更動時間是否有改變
c:檢查新建時間是否有改變

如果[switch]為大寫即表示關閉該檢查,小寫則表示使用該檢查。


以下將以 integrit 來檢查檔案系統變動的情況,假設在「/usr/local/apache2/htdocs/test/」目錄下有一個名叫index.html 的檔案,其內容如下:


<html>
<b>hello world!!!</b>
</html>


然後,在「/etc/integrit.conf」加入下列的設定:


known=/root/known.cdb           #基準系統狀態資料庫
current=/root/current.cdb             #目前系統狀態資料庫
root=/usr/local/apache2/htdocs/test     #比對啟始目錄


首先,使用 integrit 來建立基準資料庫(請自行查閱 integrit 用法),以下列指令建立基準系統狀態資料庫:


integrit  -u  -C /etc/integrit.conf   -N /root/known.cdb


其中-u 為 update,-C為使用「/etc/integrit.conf」設定檔,-N則為產生目前系統狀態資料庫,如果讀者參閱 integrit 的用法,會發現 -N 參數原意是用來產生目前系統狀態資料庫,而另一個參數 -O 才是用來產生基準系統資料庫,但筆者測試結果發現,使用 -O 參數並無任何作用,所以還是利用 -N 參數來建立基準系統狀態資料庫。

建立完成後,可利用 i-viewdb 來查看 integrit 的資料庫內容,並利用指令「i-viewdb /root/known.cdb」查看known.cdb 的內容。

建立好基準系統狀態資料庫後,將測試下列四種狀況:

檔案系統新增情況

先利用指令「touch/usr/local/apache2/htdocs/test/index2.html」新增一個檔案,接著執行指令「integrit -u -c-C /etc/integrit.conf」進行檢查(-c 的意思為 check,即為檢查):


integrit 一旦發現有新增檔案,就會以new來表示該新增檔案。

刪除情況

先利用指令「rm -f/usr/local/apache2/htdocs/test/index.html」刪除檔案,然後使用指令「integrit -u -c -C/etc/integrit.conf」進行檢查。integrit若發現有被刪除檔案,即以 missing 來表示該被刪除檔案。




修改情況

先執行指令「touch /usr/local/apache2/htdocs/test/index.html」,重新更動 index.html 的存取時間,接著使用指令「integrit -u -c -C /etc/integrit.conf」來檢查:



如果 integrit 發現檔案已經被修改過(在本例中為檔案存取時間被更動),就會以 changed 來表示該檔案已被修改。

特別選項(switch)情況

integrit 也提供可針對個別的檔案或目錄特別的檢查選項(switch)。若不在意檔案修改時間被改變,可利用設定switch 選項來達到此要求。切換到「/etc/integrit.conf」,然後加入以下的設定:

/usr/local/apache2/htdocs/test/index.html AMC 

該行設定表示不須對index.html的存取時間(A)、更動時間(M)和新建時間(C)做檢查(使用大寫字母即表示不對該選項做檢查)。

接著重新執行指令「integrit -u -c -C /etc/integrit.conf」進行檢查,會發現integrit不會認定index.html有變動的情形。其他更細緻的switch設定,請自行測試。


※  設定rsync遠端備份程式

rsync 是一種異地備份軟體,目前由 Samba 組織維護。一般備份軟體備份方式可分為「鏡像備份」(MirrorBackup)和「增量備份」(IncrementalBackup)兩種。「鏡像備份」就像鏡子一樣,將資料一對一的備份過去,就如同copy指令一樣。而「增量備份」每次備份前會先比較兩邊資料的不同,僅備份異動的資料。

rsync 軟體備份方式即屬於增量備份方式,每次備份之前會先比較來源端和目的端的檔案差異,僅將有差異的資料備份至目的端。在開始介紹 rsync 之前,先行定義下列名詞:


來源端:欲備份的主機
目的端:備份主機(存放被備份主機的資料)


而 rsync 的運作方式分成伺服器(Server)模式與客戶端(Client)模式。伺服器模式是以 daemon 方式運作,即rsync 伺服器;客戶端模式則是以一般程式方式運作,可視為 Client 端程式。此外,rsync 備份時可區分 Push 和 Pull兩種行為,Push 是從來源端將備份資料庫備份到目的端,而 Pull 是將目的端的備份資料備份至來源端。

安裝 rsync 軟體的方法很簡單,使用指令「yum install rsync*」即可安裝好相關相關的軟體。安裝完成後,首先必須設定目的端的 rsync 伺服器的設定檔(/etc/rsyncd.conf),內容設定如下:

[restore]                                                 #備份代號,名稱可自訂.
path = /restore                                #用來設定備份檔案要存放的目錄
auth users = restore_user           #可允許使用的帳號
uid = root                                          #設定 rsync 執行時,所使用的個人權限
gid = root                                          #設定 rsync 執行時,所使用的群組權限
secrets file = /etc/rsyncd.secrets  #認證用密碼檔,在此檔案設定 client 端的帳號及密碼
read only = no

接著,設定「/etc/rsyncd.secrets」檔案,此檔案格式為「帳號:密碼」,設定如下:

restore_user:passwd (請自行設定帳號及密碼)

這裡要特別要注意的是,須將「/etc/rsyncd.secrets」擁有者設為 root,並且將權限設定為 600,不然備份指令可能不會成功:

chown root:root /etc/rsyncd.secrets     #更動檔案擁有者為root
chmod 600 /etc/rsyncd.secrets            #重新設定檔案權限

然後,須設定來源端的密碼檔(/etc/rsyncd.secrets),此檔案僅須設定密碼 passwd,以本例而言即為 passwd。同樣地,此檔案也須設定擁有者為root以及將權限設為600:

chown root:root /etc/rsyncd.secrets
chmod 600 /etc/rsyncd.secrets

完成來源和目的端設定之後,在目的端上要先行啟動 rsync 伺服器,預設 rsync 會由 xinetd 所啟動。請開啟「/etc/xinetd.d/rsync」檔案並設定如下的組態資料:

service rsync
{
disable =  no        #將預設disable =yes 改為 disable=no
flags           = IPv6
socket_type     = stream
wait            = no
user            = root
server          = /usr/bin/rsync
server_args     = --daemon
log_on_failure  += USERID
}

設定完成後,利用指令「xinetd start」來啟動目的端的rsync伺服器。可利用指令「netstat -ant | grep LISTEM」來判別目的端rsync服務是否啟動(檢查服務埠873是否有開啟),如下圖所示。



在rsync伺服器啟動完成後,可先行測試下列狀況:

Push-從來源端將資料備份至目的端

先在來源端上下達下列的指令:

rsync -rvlHpogDtS  --password-file=/etc/rsyncd.secrets
/usr/local/apache2/htdocs/test/*  This e-mail address is being protected from spambots. You need JavaScript enabled to view it ::restore

執行上述指令是為了將來源端上的「/usr/local/apache2/htdocs/test」目錄資料備份至xxx.xxx.xxx.xxx的伺服主機,restore 為上例設定的備份代號,而 restore_user 是使用者名稱。其中 rsync 的參數用法說明如下:

-r:recursive,以遞迴的模式備份
-v:verbose,詳細模式輸出
-l:軟連結(Soft Link)的檔案也要備份過去
-H:保留硬連結(Hard Llink)
-p:保留文件權限
-o:保留文件擁有者資訊
-g:保留文件群組資訊
-D:devices,設備檔案也要備份過去
-t:times,保留文件時間
-S:進行特殊處理,以節省儲存空間

如果一切順利,來源端的「/usr/local/apache2/htdocs」目錄的資料,將會被備份至目的端的「/restore」目錄。

Pull-將資料從目的端下載至來源端

接著,在來源端上執行如下的指令:

rsync -rvlHpogDtS  --password-file=/etc/rsyncd.secrets   This e-mail address is being protected from spambots. You need JavaScript enabled to view it ::restore  /usr/local/apache2/htdocs/test

該指令的作用是,從xxx.xxx.xxx.xxx下載備份資料至本機,其中 restore 為設定的備份代號,restore_user 為使用者名稱,如果一切順利,來源端將從目的端上的「/restore」目錄內取回相關的備份資料並置於「/usr/local/apache2/htdocs/test」目錄下。其餘相關指令用法,請自行參閱rsync的說明。


※  實作網站保護系統

在這個系統中將包含觸發元件、還原及備份元件這兩個子元件。觸發元件利用 integrit 軟體來監控檔案系統,一旦發現有異動,即觸發還原元件來回復被異動的檔案。

至於還原及備份元件,則利用 rsync 軟體來進行還原或備份功能。還原功能是至遠端 rsync 伺服器取回(Pull)備份資料來回復被異動的檔案。而備份功能則是在製作系統基準資料庫的同時,須將相關的檔案備份(Push)到遠端的rsync 伺服器。

這裡將實作一個網站系統的保護系統,當網站內的檔案遭受到不正常的異動時,能自動至遠端 rsync 伺服器下載備份資料來回復。先假設已建立好網站伺服器,網站根目錄為「/usr/local/apache2/htdocs/test」,IP為「192.168.2.1」(在此稱為來源端),並參閱上述章節說明架設好 rsync 伺服器,IP為「192.168.2.2」(在此稱為目的端)。相關系統架構圖如下所示:




首先,在來源端先製作一份基準資料庫以供後續比對之用,並且將相關的網站資料備份至遠端備份伺服器(目的端)上(backup 機制),在來源端上鍵入下列指令:


integrit  -u  -C /etc/integrit.conf   -N  /root/known.cdb &&
rsync -rvlHpogDtS  --password-file=/etc/rsyncd.secrets /usr/local/apache2/htdocs/test   This e-mail address is being protected from spambots. You need JavaScript enabled to view it .2.2::restore


&& 意指前一個指令成功,才可執行下一個指令。本指令為新建一個基準資料庫,名稱為 known.cdb,當成功建立基準資料庫後,再將「/usr/local/apache2/htdocs/test」目錄的檔案備份至目的端的「/restore」目錄下。

在成功建立基準資料庫並將資料備份到遠端 rsync 伺服器(目的端)之後,還需要一個能「定時」監測網站根目錄且能自動至目的端下載回復資料的機制。

由上述 intergrit 的說明得知,異動情況可分為刪除(Missing)、修改(Changed)、新增(New),其中刪除情況直接至目的端取回備份資料(Pull)回復即可,而新增情況因直接下載備份資料並不會移除新增的檔案,所以須移除新增的檔案。至於修改情況,因 rsync 伺服器上備份的檔案時間,可能會比實際線上的檔案時間還要舊,所以不會覆蓋掉實際線上的檔案,因此當發生檔案被修改時,須要進行下列兩個步驟:

1. 移除被更動的檔案
2. 從遠端的 rsyn c主機下載(Pull)資料回復


筆者利用 perl 寫了一個小程式(webprotect.pl)來處理這些情況,請自行將 192.168.2.2 更改為自己主機的 IP,內容如下:


#!/usr/bin/perl
$result=`integrit -u -c -C /etc/integrit.conf`;   #檢查指令
@token = split(/\n/, $result);  #解析檢查指令的回傳字串
$dirtyflag=0;              #若有異動即須重新製作系統基準資料庫,0為無異動,1為異動
foreach (@token)
{
if($_=~/(missing\:)/)        #檔案系統有刪除情況,直接從遠端rsync伺服器取得資料回復
{
`rsync -rvlHpogDtS  --password-file=/etc/rsyncd.secrets restore_user\@192.168.2.2::restore /usr/ 
local/apache2/htdocs/test`;  
#回復,從遠端rsync伺服器取得資料回復
$dirtyflag=1;                  #系統有異動的情況
}
elsif($_=~/(new\:)/)     #檔案系統有新增情況        
{
$line=$_;
$line=~s/  / /g;
@parse = split(/ /, $line);
`rm -f $parse[3]`;#刪除該檔
$dirtyflag=1;        
}
elsif($_=~/(changed\:)/)    #檔案系統有修改情況
{       
$line=$_;
$line=~s/  / /g;
@parse = split(/ /, $_);
`rm -f $parse[1]`;        #刪除該檔
`rsync -rvlHpogDtS p;nbsp; --password-file=/etc/rsyncd.      secretsrestore_user\@192.168.2.2::restore  /usr/local/apache2/htdocs/test`;
$dirtyflag=1;
}

} #foreach
if($dirtyflag==1)    #系統有異動即重新製作系統基準資料庫
{
`integrit -u -C /etc/integrit.conf -N /root/known.cdb `;
}


接著,可以將此程式加入到 cron 排程之中,設定內容如下:


*/1 * * * * /usr/bin/perl   /usr/bin/webprotect.pl


如此一來,程式就會每分鐘定時地監控網站根目錄,一旦發現不正常的異動,即會自動至目的端下載備份資料回復,為網站系統提供完整性的保護。


◎ 作者:吳惠麟
多年資安相關工作經驗,專長整合開源碼資源及資訊安全;合著有「資訊安全實驗與原理」一書,現任職於中山大學「台灣電腦網路危機處理中心」。

◎ 本文經《網管人》同意,轉載自第 51 期文章內容。




OSSF Newsletter : 第 149 期 OIN 低調努力,專利交互授權保障商用自由軟體的未來發展

Category: Tech Column