簡介
chroot牢籠(jail)概念綜述
Postfix精靈進程分析
一個禁锢(jail)HOWTO:icecast
第一步:把icecast安裝在牢籠(jail)環境中
第二步:配置牢籠(jail)環境
第三步:為這個精靈建立一個chroot包裝
那些地方不能用牢籠環境
結論
簡介
我們經常會聽說計算機遭到基於Internet的遠程攻擊。通常位於攻擊最前線的是一些服務器軟件,例如:WEB、郵件和DNS,這些服務通常是通過監控進程(daemon,也可以叫作精靈進程)來提供的。這些服務即使是位於防火牆之後,也需要面對各種探測和攻擊,以至讓攻擊者獲得系統訪問權限。大多數的惡意攻擊者都會在系統安裝rootkit,以便能夠進行通常的系統操作。
一般情況下,這些rootkit和病毒需要使用目標系統的可執行文件、動態連接庫以及配置文件。比如:一個安裝在Linux主機上的rootkit可能需要訪問/bin/sh或者能夠讀寫/etc目錄下的系統配置文件。而且一旦系統被攻擊者侵入,攻擊者獲得了root權限,就可以運行修改任何自己需要的文件。最近的lion、ramen蠕蟲對BIND的攻擊就可以證明以上觀點。
但是如果你對精靈進程(daemon)進行限制,只允許其訪問必要的文件,而不能訪問整個文件系統,又將如何呢?這樣就可以使我們的安全不再依賴於daemon軟件開發人員的安全水平。
幸運的是,UNIX系統能夠提供這樣一種機制實現上面這種想法。在最近的BIND攻擊中,Thaumaturgix, Inc的99v管理員William Cox提出了“在chrooted的環境中運行服務器進程,減小你的暴露程度(The best way to limit your eXPosure is to run the server in a 'chrooted' environment))。這種chrooted環境通常叫作一個chroot牢籠(jail),實際上這種概念已經存在了很長時間了,但是一直沒有被軟件開發人員和系統管理人員充分利用。
chroot牢籠(jail)概念綜述
實現一個chroot jail包括兩種方式:
限制進程只能訪問整個文件系統的一個子集。
以較低的權限運行服務進程。
這兩種方式是由一些標准的系統調用來提供的。首先,是chroot(),這個系統調用能夠限制進程對文件系統的訪問。即使某個進程是以root的權限運行的,它對文件/目錄的訪問也都是相對於chroot()系統調用限制的整個文件系統的子目錄。
例如,如果一個進程以/var/sample/jail為參數執行了chroot()系統調用,現在它要訪問一個文件:/etc/passwd,但是操作系統最後會把這個訪問請求替換為對 /var/sample/jail/etc/passwd的訪問。chroot系統調用只能以root權限調用。
降低進程權限的系統調用主要包括:setuid()、setgid()和setgroups()。setuid()指定進程的實際和有效用戶權限;而setgid()指定進程的實際和有效組權限。setuid()系統非常重要,一旦通過它進入較低的權限運行,進程將無法自己重新獲得root權限。setgroups()定義進程的追加組成員關系。除此之外,還有一些其它的相關系統調用,用戶可以從自己系統的手冊頁中獲得相關文檔。
其它種類的操作系統可能還有另外的進程束縛方法。例如在FreeBSD中就有一個jail()函數。為了使你更好地體會到jailing的好處,我將通過一個典型的rootkit加以說明,在不同的權限下以及有沒有被限制在jail環境中rootkit對系統的危害是不同的。在此,要時刻記住一件事情,當一個服務被侵入,攻擊者就能夠擁有服務進程所具有的權限。請看下面這個表格:
+-----------------+---------------------------------------\
running as root running non-root
+-----------------+-------------------+-------------------
entire fs (a) (c)
-----------------+-------------------+-------------------
jailed fs (b) (d)
+---------------------------------------------------------/
運行於(a)類(進程以root權限運行並且可以訪問整個文件系統)狀態下的進程是rootkit的首選目標,侵入這樣的服務,攻擊者可以修改二進制可執行文件,例如:/bin/ps、/bin/netstat等,打開特權網絡端口,讀取任意的系統文件包括:/etc/shadow文件。最糟糕的是,他們能夠對系統進行完全的破壞,比如:rm -rf /。運行於這種狀態,最為常見的一個例子就是sendmail(http://www.sendmail.org。
如果服務進程處於(b)類(root權限、牢籠環境)狀態下,一般的rootkit就可能無法正常操作,因為它們一般需要一個shell(/bin/sh)和一些基本的命令,例如:/bin/rm和/bin/cp。然而,在這種狀態下,rootkit照樣可以打破牢籠(jail)。因為服務進程以root權限運行,攻擊者可以通過攻擊代碼直接執行一些允許root執行的操作(例如:直接引用牢籠之外文件系統的索引節點)。因此,這種狀態雖然比(a)類狀態安全(門檻高的多),但是也無法對服務提供足夠的保護。
服務進程處於(c)類(非root權限,可以訪問整個文件系統)狀態下,對整個系統的威脅比(a)狀態小,因為畢竟攻擊者無法直接獲得root權限。但是,如果服務進程處於這種狀態下,攻擊者一旦侵入這個服務,就可以執行一些命令,獲得一個shell進行交互,然後很可能通過本地攻擊獲得root權限。即使攻擊者不能獲得root權限,也可以訪問到系統的絕大多數配置文件和其它信息,例如:用戶的電子郵件帳戶信息(大量的垃圾郵件將蜂擁而至)。
最後,處於(d)類(非root權限,jail環境)狀態下的服務進程受到的限制最為苛刻,這樣攻擊者根本沒有機會執行shell,也不可能獲得大量的系統信息。而且,對系統進行的所有破壞都被限制在jail環境中。在這種狀態下,最大的威脅就是攻擊者在這個jail環境中防止一個可以被jail環境之外的進程訪問的可執行文件,從而使攻擊代碼擴散出jail環境。因此,你應該經常監視你的牢籠,看一下裡面的囚犯是否逃出來了:P。
下面我們將舉一個現實的例子進行說明。
Postfix精靈進程分析
Postfix(http://www.postfix.org)是一個郵件傳輸代理(Mail Transfer Agent)。它允許用戶收/發SMTP郵件,把給本地用戶的郵件投遞到用戶主機。Postfix是sendmail的一個變通,作者Wietse Venema對安全問題傾注了很大的關注。這個軟件是一個非常典型的所謂守紀律精靈(disciplined daemon),可以安裝在一個chroot牢籠(jail)環境中。我相信理解了Postfix是如何工作的,你就可以實現一個簡單的安全精靈(daemon)。
Postfix從一個叫作master的程序開始執行,master以root權限啟動,然後繼續以root權限運行。不過,master本身非常小,其作用這是spawn進程,這些進程大部分會被放在一個chroot牢籠(jail)環境中執行實際的工作。通過這種方式,以root權限運行的代碼數量非常有限。
下面我們看一看master是怎樣和smtpd進行交互的。master一旦檢測到一個向25號端口(SMTP的監聽端口)的連接,它就會執行smtpd。下面我們就看一下postfix使用的一些jailing方法,這些代碼在src/util/chroot_uid.c文件中。在講述過程中,我們把/var/spool/postfix作為chroot牢籠(jail)環境的根目錄:
+-----------------------------+-----------------+--------------------\
user/group filesystem
+-----------------------------+-----------------+--------------------
master is run on startup root/root /
-----------------------------+-----------------+--------------------
master opens port 25 root/root /
-----------------------------+-----------------+--------------------
master detects connection root/root /
-----------------------------+-----------------+--------------------
master forks smtpd root/root /
-----------------------------+-----------------+--------------------
master continues execution root/root /
-----------------------------+-----------------+--------------------
smtpd inherits permissions root/root /
-----------------------------+-----------------+--------------------
smptd calls setgid() root/postfix /
-----------------------------+-----------------+--------------------
smptd calls initgroups()* root/postfix /
-----------------------------+-----------------+--------------------
smtpd calls chroot() root/postfix /var/spool/postfix
-----------------------------+-----------------+--------------------
smptd calls setuid() postfix/postfix /var/spool/postfix
-----------------------------+-----------------+--------------------
smtpd processes connection postfix/postfix /var/spool/postfix
-----------------------------+-----------------+--------------------
-----------------------------+-----------------+--------------------
smptd calls setgid() root/postfix /
-----------------------------+-----------------+--------------------
smptd calls initgroups()* root/postfix /
-----------------------------+-----------------+--------------------
smtpd calls chroot() root/postfix /var/spool/postfix
-----------------------------+-----------------+--------------------
smptd calls setuid() postfix/postfix /var/spool/postfix
-----------------------------+-----------------+--------------------
smtpd processes connection postfix/postfix /var/spool/postfix
-----------------------------+-----------------+--------------------