設定主系統
體驗完單人模式 jail, 那麼來把多使用者模式 jail 也跑起來吧。還有些
設定要做:
在主系統的 /etc/rc.conf 放一行:
ifconfig_lo0_alias0="inet 127.0.0.115/32"
這行是設定 jail 要用的 IP。一般是用 alias 的方式。
再加上這幾行:
jail_enable="YES"
jail_list="conair"
jail_conair_hostname="conair"
jail_conair_ip="127.0.0.115"
jail_conair_rootdir="/usr/jails/conair"
jail_conair_exec="/bin/sh /etc/rc"
jail_conair_devfs_enable="YES"
jail_conair_devfs_ruleset="devfsrules_jail"
上面這幾行是 FreeBSD 5.3 之後才有的設定。jail_list 是設定系統裡面
有那些 jail(s)。jail_xyz_hostname, jail_xyz_ip, jail_xyz_rootdir
是每個 jail (上述範例的 xyz 以 conair 代入) 單獨的相關設定, 依實際
情況而有所不同。jail_xyz_exec, jail_xyz_devfs_enable, 以及
jail_xyz_devfs_ruleset, 基本上是固定的, 不用更動。
Jail 設定
多使用者模式 jail, 就當一般的 FreeBSD 系統來設定吧! 照上述的方法進
入 jail 單人模式, 把以下幾個檔案設定好:
/etc/hosts
第 13 和 14 行, 該 jail 的 IP 和 hostname 要設好。
/etc/resolv.conf
至少放 DNS server。
/etc/master.passwd
這就是系統帳號存放的地方了。重點就是, 要新增一個可以遠端登入的
帳號。最簡單的方法是用 adduser 或者 sysinstall 開好就行了。
root 的密碼也要設好。
/etc/group
別忘了把自己的帳號加進 wheel。
/etc/rc.conf
sshd_enable="YES"
開啟 sshd 才能遠端登入, 因為 jail 是沒有 console 的。
/etc/ssh/ssh_host_*key
自 5.3 起, 第一次啟動 sshd 的時候, 會要求使用者打一些資料進去,
幫助系統產生 ssh key。不過呢, jail 啟動的時候是沒有 terminal
的, 這會導致第一次啟動 jail 的時候有 5 分鐘的停頓。有以下兩個
方法, 可以避開這 5 分鐘的延遲:
1. 手動執行 /etc/rc.d/sshd start, 亂打一些東西進去。
2. 手動執行下列三行指令:
/usr/bin/ssh-keygen -t rsa1 -b 1024 -f /etc/ssh/ssh_host_key -N ''
/usr/bin/ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N ''
/usr/bin/ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ''
/etc/crontab
在 jail 裡面 adjkerntz 要特別關掉。至於其它的 periodic jobs,
依各人需要自行調整。
以上是基本的設定, 接下來看 jail 裡其它的設定檔:
/etc/periodic.conf
peridoc daily 有些事 jail 裡面不用做:
daily_status_security_chksetuid_enable="NO"
daily_status_security_chkmounts_enable="NO"
daily_status_disks_enable="NO"
daily_status_security_kernelmsg_enable="NO"
daily_status_network_enable="NO"
關於 mail, 因為 jail 沒有 127.0.0.1, 所以它無法像一般的 sendmail
只聽 127.0.0.1, 反而會直接聽某某 IP。因此 sendmail 要整個關掉。
/etc/rc.conf
sendmail_enable="NONE"
這時候在 /etc/periodic.conf 也要做相對應的修改, 叫它不要寄信出來:
/etc/periodic.conf
daily_output="/var/log/daily.output"
daily_status_security_output="/var/log/security.output"
weekly_output="/var/log/weekly.output"
monthly_output="/var/log/monthly.output"
沒有閱讀 periodic output 習慣的人, 可以將它們都改成 /dev/null。
啟動 jail
到此在 host 上以及 jail 內, 該設定的都差不多了。自 5.3 起, FreeBSD
提供了非常方便的 jail 管理機制, 可以任意的啟動, 關閉任一個 jail。
現在來試一試。
在主系統上
# /etc/rc.d/jail start conair
接著 ssh 127.0.0.115, 用剛剛的新加的帳號登入。到目前都沒問題的話,
恭禧你, 已經成功的安裝好一個 jail 了! 接下來就依一般使用 FreeBSD
的方式來使用該 jail 吧。
/etc/rc.d/jail 用法
# /etc/rc.d/jail stop
停止列在 /etc/rc.conf jail_list 中的所有 jails
# /etc/rc.d/jail start
啟動列在 /etc/rc.conf jail_list 中的所有 jails
# /etc/rc.d/jail stop jail1
停止列在 /etc/rc.conf jail_list 中的特定 jail
# /etc/rc.d/jail start jail1
啟動列在 /etc/rc.conf jail_list 中的特定 jail
進階議題
- 網路連通問題
Host 上若同時設有對內及對外的 IP, 且設給 jail 內部的 private IP,
那麼 jail 設定好後, 還需在 host 上設定 NAT, jail 才能對外連線。在
其它場合, 例如 jail 是對 public IP, 或 jail 及 host 同為 private
IP, 已外有執行 NAT 的主機, 則無此限制。
- Share ports tree among jails
幾乎所有人使用 jail 的第一個疑問就是, 要怎麼共享 ports tree? 有很
多方法, 例如 nullfs, unionfs, hardlink, NFS 等。mount_nullfs(8) 和
mount_unionfs(8) 看起來很嚇人 (see BUGS), hardlink 也不是好主意。
比較通用的方式是用 nfs。
如何設定 NFS server 和 NFS client 不在本文的討論範圍內, 故將焦點集
中在如何在 jail 內正常使用 NFS mount 進來的 ports tree。
首先, 為了效率, 以及 jails 之間不互相干擾 make ports 程序, 要將
work 目錄調開。設定的方法是把 WRKDIRPREFIX 設定到一個不在 ports
tree 裡面的地方。設定的地方是 jail 的 /etc/make.conf, 例如:
WRKDIRPREFIX=/tmp
另外還有一個常用的工具程式, portupgrade, 也會寫東西進 /usr/ports,
這也要調開。可以設定的地方之一是 jail 的/etc/login.conf, 裡面多設
一個環境變數, 把 PORTS_DBDIR 改到 /var/db/pkg。除此之外, jail 內的
/etc/csh.login, /etc/profile 也都可以設定這個環境變數。
- 在 jail 中跑 DNS server
FreeBSD 5.3 內建的 bind 已經昇級到 bind 9, 而且預設是以 chroot (不
是 jail!) 方式執行。於 jail 中再 chroot 是沒有問題的, 不過由於 5.3
還有 devfs, 而預設 bind 9 在執行的時候還會再 mount devfs, 這在
jail 內會造成問題。因此要對這點要做點特別調整。把 mount devfs 以及
停止 devfs 相關動作的方式, 是在 jail 內的 /etc/rc.conf 中, 加入
named_chroot_autoupdate="NO"
不過目前為止 named 尚不能正確啟動。接下來解析由 /etc/rc.d/named 啟
動 bind 時需要那些元素:
- 配置完成的 named_chrootdir (預設是 /var/named)
- 需要 /dev/null 和 /dev/random
- /etc/namedb symbolic link 到 /var/named/etc/namedb
目前欠的就是第 2 點提到的兩個 device nodes。建立它的方式是由 host
中去建立:
cd /usr/jails/conair/var/named/dev
mknod random c 245 0; mknod null c 2 2
這樣就可以了。
好了, 接下來一切照舊。:) 在新裝好的 jail 中啟動 bind 的話, 建議先
跑一下 make-localhost, 還有調整一下 named.conf。在 FreeBSD 5.3 裡
面, bind 預設也只有聽 localhost, 不對外服務。而 jail 裡面是沒有
127.0.0.1 的, 所以要把
listen-on { 127.0.0.1; };
這裡的 127.0.0.1 換成配給 jail 的 IP。
Jail 管理基本知識及工具
以下以列舉在 FreeBSD 5.3 上, 系統提供的 jail 相關訊息以及工具, 及實際應用。
ps
利用 ps 指令可以得知某 process 是在 host 或是某一 jail 內運行。在 jail 內的 process, 於 ps 顯示時, 會在 STAT 欄位顯示 J
# ps ax | grep J
這個指令可以列出目前處於 jail 內的 process。但儘止於此, 要得知是屬於那一個 jail 則要用到 procfs。
/proc
在 host 上, 要得知某 process 是屬於何 jail, 可以利用 /proc。但是 5.3 預設並沒有把 /proc 掛上系統, 所以得在 /etc/fstab 加上這一行:
/proc /proc procfs rw 0 0
把 /proc 掛上系統
# mount /proc
把 /proc mount 上來後, 以如下方式觀看該 process 的 status:
# cat /proc/<pid>/status
在最後會得知該 process 位於那一個 jail (以 hostname 表示)
jls
列出正在運行的 jail
# jls
jls 會列出下列幾個欄位 JID, IP Address, Hostname, Path。其中的
JID 是系統配的, 接下來會經常用到它。
killall
FreeBSD 5.3 的 killall 多了個 -j option, 接 jls 看到的 JID。用
途是將屬於某個 jail 的 process 都砍光。
jexec 相關的應用
jexec 的用途是, 將 process 由 jail 外送入 jail 內執行。
看某 jail 內的 process 列表
# jexec <JID> ps axwww
看某 jail 內的 top
# jexec <JID> top
看某 jail 內的使用者
# jexec <JID> w
使用 jexec 把 ps / top 送進 jail 內看 process, 有一個很大的好
處是, uid : username 的對照, 會以該 jail 內的為準。
sysctl
以下是幾個和 jail 有關的 kernel state 的說明
security.jail.set_hostname_allowed
可於 host 環境中設定, 為 1 的時候在 jail 中可以更改該 jail
的 hostname。預設為 1。
security.jail.socket_unixiproute_only
可於 host 環境中設定, 為 1 的時候表示 host 只幫 jail 把 IP
封包往外送(FreeBSD 還支援 Netware, Appletalk 等等通訊協定)。
預設為 1。
security.jail.sysvipc_allowed
可於 host 環境中設定, 為 1 的時候表示可以在 jail 中使用
shared memory, message queues, 還有 semaphores。預設為 0。
要在 jail 中提供用到上述三者的服務, 如 BBS, 或者
PostgreSQL 時, 要將它設為 1。
security.jail.getfsstatroot_only
可於 host 環境中設定, 為 1 的時候表示在 jail 裡面可以看到
其它 mount point, 反之則只能看到 jail 所在的 mount point。
預設為 1。
security.jail.allow_raw_sockets
可於 host 環境中設定, 為 1 的時候表示在 jail 裡面可以產生
raw sockets。最大的用處是允許在 jail 中使用 ping 指令。預
設為 0。
security.jail.jailed
在 host 和 jail 環境中都是唯讀的, 用途在於幫助 /etc/rc.d
的 shell scripts 判斷是不是身處 jail 之中。
可以直接使用 sysctl 指令, 亦可在 /etc/sysctl.conf 或
/boot/loader.conf 中, 設定上述的 kernel state。
Jail 昇級
Jail 內的 FreeBSD 系統, 和一般的 FreeBSD 系統一樣, 也是要昇級的。
不過手續稍微不一樣。其一, 要先在 host 上 buildworld 好。其二, 在
installworld 的時候要指定 DESTDIR。其三, mergemaster 時要多接一個
-D 的參數。以 conair 為例, 在 host 上執行下列指令:
# cd /usr/src
# make installworld DESTDIR=/usr/jails/conair
# mergemaster -D /usr/jails/conair
這些過程比較複雜且煩瑣, 處理的時候要花點耐心。
結語
自 FreeBSD 4.0 起, jail 為 FreeBSD 提供了良好的資訊安全機制, 更佳
的硬體資源利用方式, 以及更方便的系統管理模式。圍繞著 jail 所衍生的
資安機制, 系統工具, 及管理技巧, 也一直持續的在發展。除了 FreeBSD
5.3 本身之外, 於 ports 中還有許多本文尚未提及的 jail 管理工具, 有
興趣的人可以嘗試看看。如今 jail 已是被廣泛應用, 以及持續發展的技術,
如果您尚未使用過 jail, 何不從現在開始?
延伸閱讀
ps(1), killall(1), jail(2), login.conf(5), sysctl.conf(5),
loader.conf(5), jail(8), jexec(8), jls(8), sysctl(8)
<<< Page 1 :
<<
第 2 頁