FreeBSD Jails是FreeBSD平台上的一種基於容器的虛擬化技術,是對Unix傳統的chroot機制的一種擴展。Unix傳統的安全模型高效簡單,適用於很多應用場景。但是它是基於系統只有沒有管理權限的普通用戶和有管理權限的根用戶這兩類用戶的情況設計的,它無法很好地處理把一部分管理權限授權給不被信任的用戶的情況。Unix后來引入了chroot機制,提供了一種簡單的系統隔離功能,但是僅限於文件系統,進程和網絡空間都沒得到相應的處理。FreeBSD Jails正是在這種情況下出現的,它提供了一種很強的隔離能力,將chroot等已有的機制進行了擴展,可以為進程提供一個虛擬運行環境。[4]在FreeBSD Jails中,一個Jail就是一個容器。在Jail中,進程有自己的文件系統,進程和網絡空間。Jail中的進程既不能訪問也不可能看到Jail之外的文件、進程和網絡資源。
FreeBSD Jails是通過jail系統調用來供用戶使用的。Jail在進程調用jail后創建,調用進程自動被置於Jail內,而且不能脫離。進程的后代進程也自動被置於Jail之內。在Jail之內,進程所能訪問的文件系統跟chroot機制類似,所能使用的網絡資源也僅限於特定的IP地址,進程間通信也僅限於Jail內部的進程。
FreeBSD Jails的實現通過修改FreeBSD 內核相關的代碼實現的。主要有以下幾個方面[4]
(一)引入struct prison,實現jail系統調用。
Jail系統調用實現比較簡單:分配一個prison結構,然后填充相應的參數,將其附加到進程的struct proc上,設置prison的引用數為1,最后調用chroot系統調用完成剩下的工作。
(二)增強chroot機制
傳統的chroot機制有一些安全漏洞,在FreeBSD Jails的實現中,增強了chroot機制,以保證Jail內的進程的文件系統視圖是正確和可控的。
(三)限制進程間的可見性和通信
FreeBSD中進程的可見性通過兩個機制來實現,一個是procfs文件系統,另一個是sysctl樹的子樹。這兩個機制都為Jail做了相應的修改,使得只有同一個jail內的進程可見。FreeBSD中進程之間是否可以相應影響由p_trespass(p1,p2)的返回值決定,在Jails的實現中該函數已經增加了額外的jail檢查代碼,使得不同jail之間的進程不能相互影響。
(四)限制進程可訪問的網絡資源
FreeBSD Jails中的進程網絡資源的限制,不是通過給jail中的進程創建一個獨立的網絡空間實現的,而是通過將jail內的進程所能使用的網絡資源限定到一個特定的IP地址實現。當jail中的進程試圖綁定到socket時,進程的提供的IP地址不會被使用,而是使用預先為該jail配置的IP地址。
(五)讓特定的設備驅動知道Jail的存在
一些特定的設備驅動需要Jail的存在,比如pty驅動。Pty提供虛擬終端到ssh、telnet等服務。Jail需要使用pty,所以額外的代碼必須被添加使得同一個虛擬終端不會被多個jail使用。
(六)限制Jail內的超級用戶的權限
Jail內也有擁護管理員權限的超級用戶,但是該用戶的權限必須受到限制。該用戶的權限應該是系統超級用戶權限的一個子集,而該用戶的管理權限也只應該僅限於該Jail內。Jail內的超級用戶默認沒有特權,不能使用mknod系統調用創建設備,因此Jail內的進程只能使用系統管理員分配的設備。
FreeBSD Jails 的使用
Jails的使用請參見Jails的man page:http://www.freebsd.org/cgi/man.cgi?query=jail&format=html和FreeBSD 使用手冊:http://www.kuqin.com/docs/freebsd-handbook/jails.html