2007年7月21日 星期六

Jail in FreeBSD 5.3(上)

作者:evilc
什麼是 jail, 和 FreeBSD 有什麼關係?
Jail 是自 FreeBSD 4.0 起獨有的功能, 發展至今已 4 個年頭。和 chroot 有點像, 但又比 chroot 更強大。Jail 和 chroot 的相同的地方是, 皆會 將某個 process 及其 children 的根目錄 "/", 切換到某一個目錄下, 將 它們關起來。但 jail 可以關的就更多了, 除了可以在存取檔案系統方面做 限制, 在 process 這個層次也做了類似概念的隔離。TCP/IP stack 層次, 也有一定程度的限制。
Jail 的組成, 如同 chroot 般, 首先需要一個目錄, 再視用途, 把必要的 應用程式放進去。以往在建 chroot 環境的時候, 傾向於只把必要的東西放 進去。但在建 jail 的時候, 反而傾向把完整的系統放進 jail 裡。除了已 經裝好系統的目錄之外, jail 還需要有自己的 hostname, 以及自己的 IP。
運行中的 jail 亦是系統的一部份, 共享各種硬體資源, 如 CPU time, memory, disk space, network bandwidth 等等。一般將提供 jail 運行的 主系統稱之為 host。一個空的 jail (不包含 ports) 大約要佔用 150 MB 左右的磁碟空間。日後依 jail 利用方式的不同, 空間的使用也會有很大的 差異。而 CPU time, memory, network bandwidth 方面, 則視 jail 內提 供的服務, 以及執行的應用程式而定。故一個 host 能提供多少 jails, 乃 是依硬體規格及實際負載而定, 系統管理者需依情況評估及調整。
Jail 適合用來做什麼?
一個 jail 幾乎可以被視為一台獨立的 server。因此一般 server 能做的事, jail 幾乎都能做。例如 web server, mail server, shell server, database server... 都是可以 "養" 在 jail 裡面的。
Jail 仍不適合用來做什麼?
Jail 的概念是隔離, 而不是分割, 也不是模擬。某些系統資源, 像是 System V IPC (message queues, shared memory, semaphores) 目前也不 在目前 jail 能隔離的範圍內。又如在檔案系統層次, 雖然和主系統隔離了, 但所使用的磁碟空間, 卻是沒辦法強制限定只能用多少。在 TCP/IP 層次, jail 被限定只能有一個 IP, 連 lo0 127.0.0.1 都沒有。因此, 像是防火 牆, 路由器等等工作, jail 是無法勝任的。又如 BBS, PostgreSQL server 等等, 會使用到 System V shared memory, semaphores 的服務, 也得小心 調整。
FreeBSD 5.3 的 jail 有什麼新奇功能?
Jail 自 FreeBSD 5.0 起逐一修正了許多大大小小的問題, 也新增了如 jls, jexec 等等系統工具。但要說到讓人感到耳目一新, 有全新的感受, 就非得推 FreeBSD 5.3 了! Devfs 有了給 jail 專用的規則, df 能做到不 顯示 host 上其它的 mount point, 且 /etc/rc.d 已完全支援 jail! 如今 啟動 jail 時十分的乾淨, 沒有任何看了心煩的訊息。
安裝 jail
首先, 要把 jail 所需的資源先規劃好。假設 IP, hostname, path 如下:
jail IP: 127.0.0.115
jail hostname: conair
jail path: /usr/jails/conair
以上假設, 是每個 FreeBSD 系統都可以設定的。但在實際的應用上, 則依 客觀條件的不同而有所不同。 接著來把系統裝進去 jail 要使用的目錄。在安裝之前, 要先 buildworld。 這要花一點時間, 視機器的速度而定。
# cd /usr/src; make buildworld
Buildworld 做完後, 要 installworld 到上面規劃的目錄去, 還要把 jail 的 /etc 做出來。這些事有些瑣碎, 也有點危險 (不小心少打幾個字元, 會 reset 主系統的 /etc), 故建議自行寫 shell script 處理。下面是個簡單的範例: newjail.sh
------------------ newjail.sh -------------------------
#!/bin/sh
if [ -z $1 ]; then
echo "specify dest dir such as $0 /some/dir"
exit
fi
if [ ! -d $1 ]; then
echo "dest dir $1 does not exist, mkdir first"
exit
fi
echo "Install a new jail into $1"
D=$1
cd /usr/src
make installworld DESTDIR=$D
cd etc
make distribution DESTDIR=$D
cd $D/etc
ln -sf /var/named/etc/namedb
cd $D
ln -sf dev/null kernel
------------------ newjail.sh -------------------------
我把它放在 /usr/local/sbin/newjail
# cp newjail.sh /usr/local/sbin/newjail
# chmod +x /usr/local/sbin/newjail
安裝 jail base system
# mkdir -p /usr/jails/conair
# /usr/local/sbin/newjail /usr/jails/conair
接著要在主系統上設一個 IP 給它。
# ifconfig lo0 inet 127.0.0.115/32 alias
該有的都有了, 來試試 jail 的 "single user mode"
# jail /usr/jails/conair conair 127.0.0.115 /bin/sh
一些常用指令都可以拿來試試看, 例如 ps, df, top, sockstat, netstat 等等。可以再開一個窗同時比較看看, jail 內和 jail 外有什麼不一樣。

沒有留言: