Jail について
皆さん chroot ってご存知でしょうか。 Linux を使った事がある方、もしくは BIND を運営している方などは苦い思い出などあるかと思います。;-)
FreeBSD の jail(8) は chroot(8) を更に強化したようなもので、 jail(8) 内からはホストのプロセスなどは一切見えません。
機能的に言えば、最近の仮想化技術などをイメージすると分かりやすいと思います。
ezjail について
ezjail は実は単なるシェルスクリプトで、その本質は mount_nullfs(8) にあります。
jail(8) 自体は FreeBSD 独自の実装ですが、例えば full jail を一から構築すると、システム一台の容量まるまる占有する事になります。
日本語に訳すと jail(8) は監獄という意味ですが、その言葉の意味通り、必要なだけ監獄がある事に越した事はありませんが、増やした分だけ占有されるのは些か問題があります。
そこで ezjail の出番です。
最初に mount_nullfs(8) について少し話しましたが、これはイメージ的にはシンボリックリンクやハードリンクと言えば分かりやすいと思います。
突っ込んだ事を言うと mount_nullfs(8) はシンボリックリンクやハードリンクとはまったく違う実装方法なのですが、システムの深いところと関わっているので、私もはっきりとこういう実装方法だよ、とは言えません。
なので、今回は mount_nullfs(8) の実装方法について触れませんが、いつか紹介したいと思います。
パッチの適用
ezjail 3.0 のパッチを通りすがりさんが作成して下さいました。
この場を借りてお礼申し上げます。
ezjail では make.conf や src.conf ( FreeBSD 7.0-RELEASE から導入されました ) がデフォルトの位置のものしか使えませんが、以下のパッチを適用すれば、任意の make.conf や src.conf が指定できます。
上記のファイルを任意のディレクトリにダウンロードし、 ${PORTSDIR}/sysutils/ezjail/files/patch-ezjail-admin として配置してください。
% sudo fetch http://cocelo.s201.xrea.com/patch/ezjail-3.0-ezjail-admin.patch
% sudo mkdir /usr/ports/sysutils/ezjail/files
% sudo mv ezjail-3.0-ezjail-admin.patch /usr/ports/sysutils/ezjail/files/patch-ezjail-admin
ezjail の導入
ezjail の導入はとても早く終わります。
ものの数分ないし、数十秒で終わります。
% sudo portinstall sysutils/ezjail
設定ファイルのコピー
設定ファイルをコピーします。
% sudo cp /usr/local/etc/ezjail.conf.sample /usr/local/etc/ezjail.conf
ezjail.conf の編集
以下は設定箇所の簡単な説明です。
- ezjail のルートディレクトリ
# Location of jail root directories
#
# Note: If you have spread your jails to multiple locations, use softlinks
# to collect them in this directory
ezjail_jaildir=/usr/jails
- ディレクトリのテンプレート
# Location of the tiny skeleton jail template
ezjail_jailtemplate=${ezjail_jaildir}/newjail
- installworld のターゲットディレクトリ
# Location of the huge base jail
ezjail_jailbase=${ezjail_jaildir}/basejail
- FreeBSD のソースツリー
# Location of your copy of FreeBSD's source tree
ezjail_sourcetree=/usr/src
- ( パッチを適用している場合は新規に書き足す ) make.conf の位置
# Location of make.conf
ezjail_makeconf=/etc/make.conf.jails
- ( パッチを適用している場合で、FreeBSD 7.0-RELEASE 以上の場合は新規に書き足す ) src.conf の位置
# Location of src.conf
ezjail_srcconf=/etc/src.conf.jails
make.conf 及び src.conf の作成
jail 環境に必要のないものを指定した make.conf を作成します。
以下は6系リリースまでのものです。
% sudoedit /etc/make.conf.jails
NO_ACPI=YES
NO_ATM=YES
NO_AUTHPF=YES
NO_BLUETOOTH=YES
NO_BOOT=YES
NO_DICT=YES
NO_FORTRAN=YES
NO_GAMES=YES
NO_GDB=YES
NO_GPIB=YES
NO_I4B=YES
NO_INET6=YES
NO_INFO=YES
NO_IPFILTER=YES
NO_KERBEROS=YES
NO_LPR=YES
NO_MAN=YES
NO_MODULES=YES
NO_NETCAT=YES
NO_NIS=YES
NO_PF=YES
NO_PROFILE=YES
NO_RCMDS=YES
NO_SHAREDOCS=YES
NO_USB=YES
NO_BIND=YES
NO_BIND_DNSSEC=YES
NO_BIND_ETC=YES
NO_BIND_LIBS_LWRES=YES
NO_BIND_MTREE=YES
NO_BIND_NAMED=YES
NO_BIND_UTILS=YES
以下は7.0-RELEASE以降のものです。
% sudoedit /etc/src.conf.jails
WITHOUT_ACPI=yes
WITHOUT_ATM=yes
WITHOUT_AUDIT=yes
WITHOUT_AUTHPF=yes
WITHOUT_BIND=yes
WITHOUT_BLUETOOTH=yes
WITHOUT_BOOT=yes
WITHOUT_CALENDAR=yes
WITHOUT_DICT=yes
WITHOUT_EXAMPLES=yes
WITHOUT_FORTH=yes
WITHOUT_FORTRAN=yes
WITHOUT_GAMES=yes
WITHOUT_GCOV=yes
WITHOUT_GDB=yes
WITHOUT_GPIB=yes
WITHOUT_GROFF=yes
WITHOUT_GSSAPI=yes
WITHOUT_HTML=yes
WITHOUT_I4B=yes
WITHOUT_INET6=yes
WITHOUT_IPFILTER=yes
WITHOUT_IPX=yes
WITHOUT_KERBEROS=yes
WITHOUT_LPR=yes
WITHOUT_MAN=yes
WITHOUT_NCP=yes
WITHOUT_NETCAT=yes
WITHOUT_NIS=yes
WITHOUT_OBJC=yes
WITHOUT_PF=yes
WITHOUT_PROFILE=yes
WITHOUT_RCMDS=yes
WITHOUT_RCS=yes
WITHOUT_RESCUE=yes
WITHOUT_SENDMAIL=yes
WITHOUT_SETUID_LOGIN=yes
WITHOUT_SHAREDOCS=yes
WITHOUT_SYSCONS=yes
WITHOUT_USB=yes
WITHOUT_ZFS=yes
world の実行
ezjail-admin update を実行します。
暫く時間がかかるので注意しましょう。
% sudo ezjail-admin update
ディレクトリ構成について
上記項目の ezjail.conf でいくつか設定しましたが、各ディレクトリの役割について解説します。
ezjail_jaildir
全て ezjail はこのルートディレクトリ以下に jail(8) を作成します。
また、 mount_nullfs(8) されるディレクトリも、このルートディレクトリ以下になります。
デフォルトは /usr/jails です。
ezjail_jailtemplate
将来的に編集するかもしれないファイルが格納されています。
例えば /etc/make.conf や /etc/rc.conf など。
デフォルトは ${ezjail_jaildir}/newjail です。
ezjail_jailbase
新しく jail(8) を作った際に必要な shell や実行ファイル、ライブラリなど、 jail(8) で編集する必要ないファイルが格納されており、ここのディレクトリから mount_nullfs(8) されます。
ファイルが作られる ( 更新される ) タイミングは ezjail-admin update ( buildworld installworld ) 実行時です。
デフォルトは ${ezjail_jaildir}/basejail です。
Flavours ( Option )
このディレクトリはオプションで使用する事が出来ます。
例えば localtime などはどの jail(8) でも共通なので /etc/localtime を予めコピーしておくなどです。
サンプルファイルが /usr/local/share/examples/ezjail/default に格納されています。
また、デフォルトは ${ezjail_jaildir}/flavours です。
jail 環境で不要なファイルを削除する
jail で不要なファイルを削除する為に Files to Remove from Jails から 6.x 用のファイルをダウンロードします。
% cd ~
% fetch http://memberwebs.com/stef/freebsd/jails/docs/6.x/jail-remove.txt
% sudo sed "s#^/#/usr/jails/newjail/#" < jail-remove.txt | xargs rm -rfv
% sudo sed "s#^/#/usr/jails/basejail/#" < jail-remove.txt | xargs rm -rfv
一部コマンドを /usr/bin/true にリンクする
一部のコマンドでエラーが出るので 一部のコマンドを /usr/sbin/true にシンボリックリンクを貼ります。
% cd /usr/jails/basejail
% sudo ln usr/bin/true sbin/init
Flavours について
まずはサンプルの設定ファイルと、その他必要なファイルをコピーします。
なお、後述の jail の作成の際の -f default を変えれば /usr/jails/flavours/ の default 以外のディレクトリに変更出来ます。
例えば Web サーバ用の設定 ( -f http ) と SMTP サーバ ( -f smtp ) の設定を分けたりする事も出来ます。
/etc/localtime
% sudo mkdir -p /usr/jails/flavours/default/etc
% sudo cp -p /usr/share/zoneinfo/Asia/Tokyo /usr/jails/flavours/default/etc/localtime
/etc/wall_cmos_clock
% sudo touch /usr/jails/flavours/default/etc/wall_cmos_clock
/etc/fstab
% sudo touch /usr/jails/flavours/default/etc/fstab
/etc/resolv.conf
% sudo sh -c 'grep nameserver /etc/resolv.conf > /usr/jails/flavours/default/etc/resolv.conf'
/etc/make.conf
% sudoedit /usr/jails/flavours/default/etc/make.conf
WRKDIRPREFIX= /var/ports
DISTDIR= /var/ports/distfiles
PACKAGES= /var/ports/packages
CPUTYPE?=athlon64
WITHOUT_X11= yes
WITHOUT_IPV6= yes
/etc/rc.conf
% sudoedit /usr/jails/flavours/default/etc/rc.conf
# Pretuned by German Engineers
# No network interfaces in jails
network_interfaces=""
# Prevent rpc
rpcbind_enable="NO"
# Prevent loads of jails doing their cron jobs at the same time
cron_flags="$cron_flags -J 15"
# Prevent syslog to open sockets
syslogd_flags="-ss"
# Prevent sendmail to try to connect to localhost
sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
/etc/periodic.conf
% sudoedit /usr/jails/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_disks_enable="NO"
daily_status_network_enable="NO"
daily_status_security_noamd="YES"
daily_status_security_chkmounts_enable="NO"
daily_status_security_ipfdenied_enable="NO"
daily_status_security_ipfwdenied_enable="NO"
daily_status_security_ipfwlimit_enable="NO"
daily_status_security_ip6fwdenied_enable="NO"
daily_status_security_ip6fwlimit_enable="NO"
weekly_whatis_enable="NO"
/etc/crontab
% sudoedit /usr/jails/flavours/default/etc/crontab
SHELL=/bin/sh
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin
HOME=/var/log
0 * * * * root newsyslog
1 3 * * * root periodic daily
15 4 * * 6 root periodic weekly
30 5 1 * * root periodic monthly
/etc/syslog.conf
% sudo cp /etc/syslog.conf /usr/jails/flavours/default/etc/syslog.conf
/var/log/all.log
% sudo mkdir -p /usr/jails/flavours/default/var/log
% sudo touch /usr/jails/flavours/default/var/log/all.log
% sudo chmod 600 /usr/jails/flavours/default/var/log/all.log
/etc/newsyslog.conf
% sudo cp /etc/newsyslog.conf /usr/jails/flavours/default/etc/newsyslog.conf
jail の作成
jail を作成します。
hoge.example.com と IP アドレスは各自の環境に合わせてください。
% sudo ezjail-admin create -f default jailname 192.168.0.2
ifconfig で alias を振ります。
% sudo ifconfig fxp0 inet 192.168.0.2 netmask 255.255.255.255 alias
自動起動の設定
自動起動の設定を行います。
% sudoedit /etc/rc.conf
ezjail_enable="YES"
jail_set_hostname_allow="NO"
jail_socket_unixiproute_only="YES"
jail_sysvipc_allow="NO"
ifconfig_fxp0_alias0="inet 192.168.0.2 netmask 255.255.255.255"
ezjail の起動
ezjail を起動します。
% sudo /usr/local/etc/rc.d/ezjail.sh start jailname
動作確認
ezjail-admin list で作成したホストが立ち上がっているかどうか確認します。
% ezjail-admin list
ports を使う
ports が使えないと何かと不便なので ports を使えるようにします。
% sudo ezjail-admin update -P
portsnap を使って ports を取得してきてくれます。
更新の場合も上記コマンドを打てば更新してくれます。
また、同時に INDEX.db の更新をしておけば後々楽かと思います。
% sudo env PORTSDIR=/usr/jails/basejail/usr/ports portsdb -u
ホストと共有しても良い場合はfstabに以下を書き足します。
% sudoedit /etc/fstab.jailname
/usr/ports /usr/jails/jailname/basejail/usr/ports nullfs ro 0 0
/usr/src /usr/jails/jailname/basejail/usr/src nullfs ro 0 0
NFS を使用する場合は以下のようになります。
% sudoedit /etc/fstab.jailname
192.168.1.100:/usr/ports /usr/jails/jailname/basejail/usr/ports nfs ro 0 0
192.168.1.100:/usr/src /usr/jails/jailname/basejail/usr/src nfs ro 0 0
jail にインストールされている ports で更新されたものを調べるには下記のようにします。
% env PKG_DBDIR=/usr/jails/JAILNAME/var/db/pkg pkg_version -l '<'
jailaudit
ports を導入した場合はホスト環境に jailaudit を導入すると良いです。
これは jail 用の portaudit で、個々の jail に portaudit を導入しないで、ホスト環境から一元管理する事が出来ます。
% sudo portinstall ports-mgmt/jailaudit
jail にログイン
jail 環境にログインします。
% sudo ezjail-admin console jailname
jail のパスワードの設定
jail 環境にログインしたらパスワードの設定を行います。
# passwd
jail の削除の仕方
jail を削除する時は下記のようにコマンドを入力すれば削除出来ます。
% sudo /usr/local/etc/rc.d/ezjail.sh stop jailname
% sudo ezjail-admin delete -w jailname
付録: jail 構築の際に使えそうな Ports
- ports-mgmt/jailaudit
- jail 環境下にインストールされている Ports の脆弱性をホスト環境からチェック出来る
- jail 環境下にインストールされている Ports の脆弱性をホスト環境からチェック出来る
- ports-mgmt/pkg_replace
- portupgrade 互換。依存関係がない
- portupgrade 互換。依存関係がない
- ports-mgmt/portconf
- portupgrade portmaster ‘make install’ 時に MAKE ARGS を指定出来る。上記の pkg_replace と合わせて使用すれば jail 内の Ports 管理が楽になるかも
- portupgrade portmaster ‘make install’ 時に MAKE ARGS を指定出来る。上記の pkg_replace と合わせて使用すれば jail 内の Ports 管理が楽になるかも
リンク
ezjail - Jail administration framework
jailaudit
pkg_replace
FreeBSD Jail Software and Docs
ezjail - otsune FreeStyleWiki
otsune’s FreeBSD memo :: jailの作り方
コンパクトなJail環境の構築