目次
jail+zfs
jailとzfsと組み合わせて、種になるjailを作成して、そのスナップショットをテンプレートにしてzfs cloneで作成します。
設定周りのスクリプトがあればezjailとかなくても良いかも…
場所の確保
# zfs create -o mountpoint=/jail tank01/jail # zfs create tank01/jail/base
元となるjailの構築
入れるのはbaseとlib32でとりあえず大丈夫でしょう。
# bsdinstall jail /jail/base
※baseシステムをupdateしているとftpで10.0-RELEASE-p1ディレクトリにアクセスしようとして、失敗するので注意1)
2015.05.20 直った模様(10.1-RELEASE-p10で確認)
※最初のサイト選択で、<Other> を選択して、-pn (nはパッチレベル)を取り除くことでも対応可能
元となるjailのupdate
# freebsd-update -b /jail/base -d /jail/base/var/db/freebsd-update fetch # freebsd-update -b /jail/base -d /jail/base/var/db/freebsd-update install
jail環境で
# sysctl security.jail.param.allow.chflags=1
とすることで、jail環境内でも freebsd-update を利用できる模様。4)
設定
/etc/jail.conf
# common variables exec.prestart += "ifconfig ${nic} inet ${ip4.addr} add"; exec.start = "/bin/sh /etc/rc"; exec.stop = "/bin/sh /etc/rc.shutdown"; exec.poststop += "ifconfig ${nic} inet ${ip4.addr} -alias"; exec.clean; $nic = "xn0"; mount.devfs; path = "/jail/$name"; host.hostname = $name; # each jail base { ip4.addr = 192.168.0.128; }
この例では、ホストと同じネットワークに接続する設定で、起動時にIP alias を振ってる。
ホストと同じIPならこんな感じ
# common variables exec.start = "/bin/sh /etc/rc"; exec.stop = "/bin/sh /etc/rc.shutdown"; exec.clean; mount.devfs; path = "/jail/$name"; host.hostname = $name; # each jail base { ip4.addr = <ホストのIPアドレス>; allow.chflags; <= chflagsの使用許可(freebsd-updateが実行できるようにするため) allow.raw_sockets; <= RAW SOCKETの使用許可(ping等が使用できるようにするため) }
/etc/rc.conf
jail_enable="YES"
起動するjailを指定する場合
jail_list="jail01 jail02 jail05"
並列起動5)
jail_parallel_start="YES"
スナップショット
# zfs snapshot tank01/jail/base@10.0p1
スナップショットの一覧
# zfs list -t snapshot
新しい監獄をzfs cloneで作る
# zfs clone tank01/jail/base@10.0p1 tank01/jail/NewJail
/etc/jail.confを忘れないように
起動
# service jail start base
一覧
# service jail status OR # jls JID IP Address Hostname Path 1 - yourjail.localdomain /path/to/yourjail
jailに入る
# jexec 1 /bin/sh ↑ ↑ ログイン用シェル ↑ jail ID (jail名でも可)
止める
# service jail stop base
削除
# service jail stop base # chflags -R noschg /jail/base/* # rm -R /jail/base/*
pkgngの利用
pkgコマンドはjailの外から利用可能です
# pkg -j jail名|jailID info
ただし、先にjail内でpkgのインストールが必要です6)
jail# pkg
ちなみに、jail内でpkgコマンドを使う場合、updateもしておかないと、動かないので注意
jail# pkg update
Host側のディレクトリをマウント
nullfsを利用します。7)
例:/usr/ports を jailで共有する
/etc/fstabに以下のような記述
/usr/ports/ /jail/jail名/usr/ports nullfs ro,noauto 0 0
mountすればjail側で使えるようになります
# mount /jail/jail名/usr/ports
/etc/jail.confだとこんな感じで書けば、jailの起動時にマウントして停止時にumountしてくれるはず
jail名 { exec.prestart += "mount /jail/jail名/usr/ports"; exec.poststop += "umount /jail/jail名/usr/ports"; }
/etc/jail.confで完結させる場合8)
- /etc/jail.conf
exec.prestart += "mount_nullfs -o ro /usr/ports/ /jail/$name/usr/ports"; exec.prestart += "mount_nullfs /var/cache/pkg/ /jail/$name/var/cache/pkg"; exec.poststop += "umount /jail/$name/usr/ports"; exec.poststop += "umount /jail/$name/var/cache/pkg";
/usr/portsの場合
リードオンリーでマウントしてるので、このままではビルドが失敗します。以下のように /etc/make.conf で作業用のディレクトリを指定します。
WRKDIRPREFIX = /var/ports DISTDIR = /var/ports/distfiles PACKAGES = /var/ports/packages
共有メモリは推奨されない
PostgreSQLのように共有メモリを使用するものはJAILでの動作は推奨されない
http://www.jp.freebsd.org/QandA/HTML/1866.html9)
ListenポートとIPアドレスの調整
ホストとjailで別々のIPを振った場合、サーバソフトでもそれを意識した設定が必要
つまり、listenアドレスをきちんと指定しないとエラーを起こす。
ホストで待ち受けているポートを見る
# sockstat -l4 USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS root sendmail 1359 3 tcp4 127.0.0.1:25 *:* root sshd 1356 4 tcp4 *:22 *:* root syslogd 1293 7 udp4 *:514 *:*
apache
/usr/local/etc/apache/httpd.conf
Listen 192.168.1.jailアドレス:80 Listen 192.168.1.jailアドレス:443
Nginx
/usr/local/etc/nginx/nginx.conf10)
listen 192.168.1.jailアドレス:80
lighttpd
/usr/local/etc/lighttpd/lighttpd.conf
server.bind = "192.168.1.jailアドレス" ...... $SERVER["socket"] == "192.168.1.jailアドレス:80" { }
sshd
/etc/ssh/sshd_config11)
ListenAddress <ホストのIPアドレス>
# service sshd restart # sockstat -l4 USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS root sendmail 1359 3 tcp4 127.0.0.1:25 *:* root sshd 1356 4 tcp4 <ホストのIPアドレス>:22 *:* root syslogd 1293 7 udp4 *:514 *:*
syslogd
/etc/rc.confに以下を追記する
syslogd_flags="-ss"
# service syslogd restart # sockstat -l4 USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS root sendmail 1359 3 tcp4 127.0.0.1:25 *:* root sshd 1356 4 tcp4 <ホストのIPアドレス>:22 *:* root syslogd 1293 7 udp4 <ホストのIPアドレス>:514 *:*
inetd
/etc/rc.confに以下を追記する
inetd_flags="-wW -C 60 -a <ホストのIPアドレス>"
jail内のUID/GIDの範囲を指定する
jail内の/etc/pw.conf(/jail/jail名/etc/pw.conf)で指定
defaultpasswd no minuid 10000 maxuid 19999 mingid 10000 maxgid 19999
起動順
/etc/rc.confのjail_listを記述することで起動準を指定できる
jail_list="jail1 jail2 jail3"
依存
他のjialに依存してる場合、/etc/jail.confで depend で指定する
db64 { host.hostname = "db64.example.com"; path = "/home/jails/db64"; ip4.addr += "192.168.46.2/32"; allow.raw_sockets = 0; mount.fstab = "/etc/fstab.db64"; exec.consolelog = "/var/log/jail_db64_console.log"; } www64 { host.hostname = "www.example.com"; path = "/home/jails/www64"; ip4.addr += "192.168.46.4/32"; allow.raw_sockets = 0; mount.fstab = "/etc/fstab.www64"; exec.consolelog = "/var/log/jail_www64_console.log"; # depend db,db64; depend db64; }
Memo
デフォルトの状態では、traceroute、ping、bpfを利用したWIDE-DHCP等のraw socketを利用するプログラムが正常に動作しません。 これらを利用するためには、hostの「/etc/sysctl.conf」に以下の記述を追記
security.jail.allow_raw_sockets=1
/etc/resolv.confの直し忘れが多いので注意