如果我的應用程序從一開始就可以在較低級別執行,我為什麼要 chroot 進行沙盒以確保安全?
我正在用 C 語言編寫一個 HTTP 伺服器守護程序(這是有原因的),並使用 systemd 單元文件對其進行管理。
我正在重寫一個 20 年前設計的應用程序,大約在 1995 年。他們使用的系統是 chroot,然後是 setuid,以及標準程序。
現在,在我之前的工作中,通常的政策是您永遠不會以 root 身份執行任何程序。您為它創建一個使用者/組並從那裡執行。當然,系統確實以root身份執行了一些東西,但我們可以不以root身份完成所有業務邏輯處理。
現在對於 HTTP 守護程序,如果我不在應用程序中 chroot,我可以在沒有 root 的情況下執行它。那麼,應用程序永遠不會以 root 身份執行不是更安全嗎?
從一開始就以 mydaemon-user 身份執行它不是更安全嗎?而不是從 root 啟動它,chrooting,然後 setuid 到 mydaemon-user?
似乎其他人錯過了你的觀點,這不是為什麼要使用變根的原因,當然你已經清楚地知道了,也不是你可以做些什麼來限制守護程序,當你也清楚地知道在非特權使用者帳戶;但是為什麼要在應用程序內部做這些事情。實際上有一個相當恰當的例子來說明原因。
考慮
httpd
Daniel J. Bernstein 的 publicfile 包中守護程序的設計。它所做的第一件事是將 root 更改為它被告知要與命令參數一起使用的根目錄,然後將權限刪除到在兩個環境變數中傳遞的非特權使用者 ID 和組 ID。Dæmon 管理工具集具有專用工具,用於更改根目錄和刪除非特權使用者和組 ID。Gerrit Pape 的 runit 有
chpst
. 我的 nosh 工具集有chroot
和setuidgid-fromenv
. Laurent Bercot 的 s6 有s6-chroot
和s6-setuidgid
. 韋恩·馬歇爾 (Wayne Marshall) 的 Perp 有runtool
和runuid
. 等等。事實上,他們都有 M. Bernstein 自己的 daemontools 工具集setuidgid
作為先行詞。人們會認為可以從
httpd
這些專用工具中提取功能並使用它們。然後,正如您所設想的,伺服器程序的任何部分都不會以超級使用者權限執行。問題是,一個直接後果是必須做更多的工作來設置更改的根,這會暴露出新的問題。
就Bernstein而言
httpd
,根目錄樹中唯一的文件和目錄是要發佈到世界各地的文件和目錄。樹上什麼都沒有。此外,任何可執行程序映像文件都沒有理由存在於該樹中。但是將根目錄更改為鍊式載入程序(或 systemd),然後突然將程序映像文件
httpd
,它載入的任何共享庫,以及程序載入器或 C 執行時庫訪問的任何特殊文件/etc
,/run
以及/dev
在程序初始化期間(如果您truss
/strace
是 C 或 C++ 程序,您可能會發現這非常令人驚訝),也必須存在於更改的根目錄中。否則httpd
無法連結到並且不會載入/執行。請記住,這是一個 HTTP(S) 內容伺服器。它可能會在更改的根目錄中提供任何(世界可讀的)文件。這現在包括您的共享庫、程序載入器以及作業系統的各種載入器/CRTL 配置文件的副本。如果某些(意外)意味著內容伺服器有權寫入內容,則受感染的伺服器可能會獲得對
httpd
自身程序映像的寫入權限,甚至是您系統的程序載入器。(請記住,您現在有兩組平行的/usr
、/lib
、/etc
、/run
和/dev
目錄來保證安全。)這些都不是
httpd
更改 root 並自行刪除特權的情況。因此,您已經換取了少量特權程式碼,這些程式碼相當容易審計,並且在
httpd
程序開始時執行,以超級使用者權限執行;因為在更改的根目錄中具有極大擴展的文件和目錄的攻擊面。這就是為什麼它不像在服務程序外部做所有事情那麼簡單。
請注意,這仍然是其自身的最低限度的功能
httpd
。所有執行操作的程式碼,例如在作業系統的帳戶數據庫中查找使用者 ID 和組 ID 以首先放入這些環境變數中,都是程序外部的httpd
,在簡單的獨立可審計命令中,例如envuidgid
. (當然,它是一個 UCSPI 工具,因此它不包含任何用於偵聽相關 TCP 埠或接受連接的程式碼,這些程式碼是諸如tcpserver
、tcp-socket-listen
、tcp-socket-accept
、s6-tcpserver4-socketbinder
、等命令的域s6-tcpserver4d
。)進一步閱讀
- 丹尼爾 J. 伯恩斯坦 (1996)。
httpd
. 公共文件. cr.yp.to.httpd
. Daniel J. Bernstein 的軟體合二為一。軟體。喬納森·德博因·波拉德。2016 年。gopherd
. Daniel J. Bernstein 的軟體合二為一。軟體。喬納森·德博因·波拉德。2017 年。- https://unix.stackexchange.com/a/353698/5132
- https://github.com/janmojzis/httpfile/blob/master/droproot.c