ezjailを使ってFreeBSD jailを効率よく管理する

HP ProLiant ML115 G1を使ったFreeBSD 7.2-RELEASE boxは、jailを使っていろいろな環境を作ることにした。ついでに、jailを簡単に使うためのツールezjail - Jail administration frameworkも試してみることにした。

準備

まずは下ごしらえから。必要なものは以下の通り。

なにはともあれ、portsからezjailをインストールする。
${PREFIX}/etc/ezjail.conf.sampleがインストールされるので、ezjail.confにコピーして編集する。

jailを配置するディレクトリ
ezjail_jaildir=/home/jails

配布物をダウンロードするFTPサーバ
ezjail_ftphost=ftp.jp.freebsd.org

jailの配置場所と、FTPサーバの設定はやっておくほうがよい。
ezjail.confの編集が終わったら、basejailを作成する。basejailはezjailで管理するすべてのjailの元になるjail。

# ezjail-admin install

FTPでインストール配布物をダウンロードして、${ezjail_jaildir}/basejailにインストール、不要なものを削除してbasejailの完成となる。
インストールしたbasejailは、7.2-RELEASEになっている。SAが出てるバージョンなので、更新の必要がある。source treeを用意して自分でbuildしてもいいけど、イマドキならfreebsd-update使うよね?

# mkdir /home/jails/freebsd-update
# freebsd-update -b /home/jails/basejail -d /home/jails/freebsd-update fetch
# freebsd-update -b /home/jails/basejail -d /home/jails/freebsd-update install

これで、7.2-RELEASE最新相当まで更新される。

Host環境の準備

FreeBSDのjailは、jailに割り当てるIPアドレスをaliasで設定する。このIPアドレスはHostにも見えちゃうので、Hostでアドレス指定なしにbindしてると、jailでbindできなくなって困る。というわけで、HostではHostのIPアドレスを指定してbindするように、各アプリケーションを設定変更する必要がある。
sockstatしたところ、該当するのはsyslogd, named, ntpd, postfix, sshdの合計5つだった。一つ一つ片付けていこう。

syslogd

/etc/rc.confで-b "HostのIPアドレス"を設定する。

syslogd_flags="-s -b 192.168.0.xxx"
named

named.confでlistenするIPアドレスを指定する。

listen-on { 127.0.0.1; 192.168.0.xxx; };
ntpd

jail内でntpdを起動することはないので、無視することにする。ntpdのsourceを斜め読みした限りでは、設定する方法もなさそう。

postfix

jail内で動作させればいい気もするけど、とりあえずそのまま使うことにする。
bindしてるのはsmtpだけなので、master.cfでsmtpの設定をする。

127.0.0.1:smtp      inet  n       -       n       -       -       smtpd
192.168.0.xxx:smtp      inet  n       -       n       -       -       smtpd
sshd

/etc/ssh/sshd_configで設定する。

ListenAddress 192.168.0.xxx
ListenAddress 127.0.0.1

jailの起動

準備ができたので、いよいよjailを作成して起動してみる。

jail用のalias IPアドレスの付与

まずはjailで使用するIPアドレスを決める。ここでは192.168.0.130とした。理由は特になし。ifconfigを使って、aliasを設定する。

# ifconfig bge0 alias 192.168.0.130 netmask 255.255.255.255
jailの作成

ezjail-adminのcreateを使う。jailに付与するホスト名が必要。ここではjail.example.comとした。

# ezjail-admin create jail.example.com 192.168.0.130
jailの起動

ezjailの起動スクリプトを使って、今作成したjailを起動する。

# /usr/local/etc/rc.d/ezjail.sh forcestart jail.example.com

ps axしてSTATにJ付きのプロセスがいたら、jailの起動は成功。

設定の永続化

再起動してもjailが起動されるように、/etc/rc.confを設定しておこう。

ezjail_enable="YES"
ifconfig_bge0_alias0="inet 192.168.0.130 netmask 255.255.255.255"
jail_set_hostname_allow="NO"

jail_set_hostname_allowは、jail内からjailのホスト名変更を許可するかどうかの設定。jailを作成したときに適切なホスト名を付与するという考えで、NOにした。

devfs, procfs, fdecfs

デフォルトでは、jail用にdevfs, procfs, fdecfsがmountされる。今後も必要がない場合は、/usr/local/etc/ezjail.confで指定するとよい。ここら辺のコメントアウトされてる部分を有効にして、NOを設定すればOK。

# Default options for newly created jails
#
# Note: Be VERY careful about disabling ezjail_mount_enable. Mounting
# basejail via nullfs depends on this. You will have to find other
# ways to provide your jail with essential system files
# ezjail_mount_enable="YES"
# ezjail_devfs_enable="YES"
# ezjail_devfs_ruleset="devfsrules_jail"
# ezjail_procfs_enable="YES"
# ezjail_fdescfs_enable="YES"

すでに作成しちゃったjailについては、/usr/local/etc/ezjail配下に設定があるので、適宜書き換えればOK。

ezjailでFlavoursを使う

無事にjailは起動したけど、このままだといろいろと使い勝手が悪い。というわけで、細かい設定をつめていこう。

Flavour

ezjailにはFlavourという機能が存在する。jailの設定を雛形にしておくと、createのときにコピーしてくれる、というもの。デフォルトのFlavourが${ezjail_jaildir}/flavours/defaultに存在する。この下に存在するファイルが、createの際に作成したjailの中にコピーされる。
特にezjail.flavourというファイルは、/etc/rc.d/ezjail-config.shとしてjailの初回起動時に実行されるようにezjail-admin createが取り計らってくれる。うまく使うとかなり便利。

# If a config is found, make it auto run on jails startup
if [ -f ${ezjail_rootdir}/ezjail.flavour ]; then
  ln -s /ezjail.flavour ${ezjail_rootdir}/etc/rc.d/ezjail-config.sh
  chmod 0700 ${ezjail_rootdir}/ezjail.flavour
  echo "Note: Shell scripts installed, flavourizing on jails first startup."
fi

ただし、二回目以降の起動で実行されないように、ezjail.flavourスクリプトに自爆処理を付け加えることをお忘れなく。デフォルトのezjail.flavourだとこの辺。

# Hide
#######
#
# Prevent this script from being called over and over if something fails.

rm -f /etc/rc.d/ezjail-config.sh /ezjail.flavour
Flavourで設定するとうれしいもの

/etc配下だとmake.conf、periodic.conf、rc.conf、resolv.confは環境に合わせて設定すべし。
あとはCMOS ClockとTimezoneにあわせてwall\_cmos\_clockとlocaltimeを設定しよう。
flavours/default/etc/make.conf

WRKDIRPREFIX=		/var/ports
DISTDIR=		/var/ports/distfiles
PACKAGES=		/var/ports/packages

flavours/defualt/etc/rc.conf

network_interfaces=""
rpcbind_enable="NO"
cron_flags="$cron_flags -J 15"
syslogd_flags="-ss"

sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"

sshd_enable="YES"

flavours/default/etc/periodic.conf

daily_output="/var/log/daily.log"
weekly_output="/var/log/weekly.log"
monthly_output="/var/log/monthly.log"
daily_status_security_output="/var/log/daily_status_security.log"
daily_status_network_enable="NO"
daily_status_security_ipfwlimit_enable="NO"
daily_status_security_ipfwdenied_enable="NO"
weekly_whatis_enable="NO"       # our jails are read-only /usr

時計関係

# touch flavours/default/etc/wall_cmos_clock
# cp -p /usr/share/zoneinfo/Asia/Tokyo flavours/default/etc/localtime

ezjailでPortsを使う

最近のezjailはportsnapを使うようになってるので、portsを使うのはすごく簡単。basejailの/usr/portsports treeが展開されて、それぞれのjailからはread onlyで見えることになる。portsを使う際に書き込みが必要なディレクトリは、make.confで別途書き込み可能なディレクトリを指定する必要があることに注意。

# ezjail-admin update -P

portupgradeを使ってる人は、同時にportsdbも実行しておくと、INDEX.dbを何回も作らなくてもすむ。

# env PORTSDIR=/home/jails/basejail/usr/ports portsdb -u

まとめてaliasにするかshell scriptにしておくと面倒がなくてよいね。

tinderboxを使ってezjailで使うpackagesを作成する

ezjail Flavourでは、flavourのディレクトリ配下にpkgというディレクトリを作成しておくと、createの際にpkg配下のファイルをjailの/pkgにコピーしてくれる。ezjail.flavourスクリプトで、このディレクトリからpkg_addすれば、即座に使えるjailが完成して便利。
デフォルトのezjail.flavourスクリプトだとこんな感じ。

# Packages
###########
#
# Install all packages previously put to /pkg
# Remove package files afterwards

[ -d /pkg ] && PACKAGESITE=file:// pkg_add -r /pkg/*
rm -rf /pkg

ところで、このためにpackagesを用意するとして、ちゃんとpackages作成環境を作らないと、configureが変なところからライブラリを見つけてきたり、依存関係にあるすべてのpackagesを作れなかったりと、いろいろと不具合が発生する。かといって、自力でpackages作成環境を用意するのは面倒。
そんなあなたにtinderbox。きれいなpackages作成環境の準備から、packagesの作成まで全部面倒を見てくれる。portsのテスト以外にも使い道があるのですよ。