jail
投稿日: | |
---|---|
修正日: | |
タグ: |
FreeBSDのjailの構築の度に「【FreeBSD】FreeBSDサーバ上に仮想サーバを構築する(jail)」に依存しているので、それを回避するためのメモ。なおメモの途中で"man jail.conf"のEXAMPLESに手順が書いてあることに気づいた。
構築の手順は大雑把には次の通りである。
なお本稿ではパスや名前に以下の環境変数を使用する。
環境変数 | 値の例 | 用途 |
---|---|---|
JAIL_NAME | myjail1 | jailの名前 |
JROOT_PATH | /usr/jail/myjail | jailのルートディレクトリ |
カーネルのインストール
FreeBSDのカーネルのソースは/usr/srcにある。
user% cd /usr/src
カーネルのビルドにはmakeコマンドを使用する。makeに与えるターゲット名や変数はMakefileを参照されたし。特にターゲットについては丁寧に記述されている。
- カーネルのビルド
user% make buildworld
- カーネルのインストール
user% make installworld DESTDIR=${JROOT_PATH}
- カーネルの設定ファイルのインストール
user% cd /usr/src/etc user% make distribution DESTDIR=${JROOT_PATH}
- jailのdevfsをマウント
user% mount -t devfs devfs ${JROOT_PATH}/dev
カーネルのビルドとインストールは以下のようにまとめて行うこともできる。
user% make world DESTDIR=${JROOT_PATH}
また、一度カーネルのビルドを行えば、2つ目以降のjailの生成では省略できる。なおビルドの際の設定はmake.confを使用する。詳細は"man make.conf"を参照されたし。
${JROOT_PATH}/etc以下のファイルの修正
"make distribution"でインストールした設定ファイルは、そのままではjail用でない。それでも実行するのに支障はないが、ホストと複数のjail間での競合によるトラブルを回避したいならば、いくつかの設定ファイルを修正する必要がある。以下にいくつか紹介する。
- カーネルのログ出力を抑止。syslogdの設定ファイル(${JROOT_PATH}/etc/syslog.conf)を修正(コメントアウト)。
- before
*.err;kern.warning;auth.notice;mail.crit /dev/console
- after
#*.err;kern.warning;auth.notice;mail.crit /dev/console
- カーネルの時間を制御するための時間同期(adjkerntz)を抑止。crontabの設定ファイル(${JROOT_PATH}/etc/crontab)を修正。
- before
1,31 0-5 * * * root adjkerntz -a
- after
#1,31 0-5 * * * root adjkerntz -a
- OS全体で使用するユーザidとグループidを重複させないように設定。jailの設定ファイル(${JROOT_PATH}/etc/pw.conf)及びホストの設定ファイル(/etc/pw.conf)を修正(コメントアウト)。以下に記述例を示す。
このように設定すれば、ユーザIDとグループIDは1000から1999の範囲に限定される。同じ要領で他の環境も設定すれば、重複しないようにできる。pw.confの詳細は"man pw.conf"を参照されたし。minuid 1000 maxuid 1999 mingid 1000 maxgid 1999
- ホスト名のローカルデータベースの設定。自分が使用するホスト情報が/etc/hostsにあるならば、それをコピーした方が早い。
user% cp /etc/hosts ${JROOT_PATH}/etc/.
ネットワークインタフェース
ネットワークインタフェースがホストやjail間で共有している場合(例えばホストでエイリアスしたものを使用している場合)、意図した相手と異なる相手にアクセスしてしまうことがありうる。それを回避する方法をいくつか紹介する。
- sshサーバが受信する宛先IPアドレスを設定(${JROOT_PATH}/etc/ssh/sshd_configを修正)。以下に例を示す。
- before
#ListenAddress 0.0.0.0
- after
ListenAddress 192.168.1.2
jailはデフォルトでは、raw socketを利用したプログラムが正常に機能しない。これを回避するためには/etc/sysctl.confに次の行を追加する必要がある。
security.jail.allow_raw_sockets=1
jailの設定
jailの構築が終わったら、jailのルート以下のファイルの設定を行う。なお以下で紹介する処理のほとんどは、jailを動かすために必要不可欠という訳ではない。以下のいくつかについては"man jail.conf"のConfiguring the Jailを参照されたし。
jailのルートディレクトリ以下で作業をする場合、chrootを使えばルートディレクトリを変更できる。
user% chroot ${JROOT_PATH}
ルートディレクトリを元に戻すにはexitで終了すれば良い。
- DNSサーバの設定。エディタを起動して手動で設定するか、後述のようにホストのものをコピーするかすれば良い。
ホストのresolv.confをコピーするには、ルートディレクトリを通常に戻った後に、次のように行えば良い。user% vi /etc/resolv.conf
user% cp /etc/resolv.conf ${JROOT_PATH}/etc/.
- jailのrootパスワードの設定
passwd root
- タイムゾーンの設定
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
- 警告を防ぐために空の/etc/fstabを生成。
touch /etc/fstab
- adjkerntzは/etc/wall_cmos_clockがある場合、 CMOSクロックは(MS-DOSやMS-Windows互換モードの)ローカル時間を保持していることを意味する。
このファイルが無い場合、CMOSクロックはUTC時間を保持していることになる。touch /etc/wall_cmos_clock
- sendmailの警告を防ぐために次のコマンドを実行
newaliases
- 警告を防ぐためにインタフェースを無効化。
エディタを起動し、
次のパラメータを設定。vi /etc/rc.conf
network_interfaces=""
- ポートマッパー(rpcbind)を無効化。rc.confに次のパラメータを設定。
rpcbind_enable="NO"
- デフォルトではrootしかいないので、必要であれば更にユーザの追加が必要。
user% pw useradd -n user1
- jailに導入したいパッケージをインストール
- SSHサーバが受信する宛先IPアドレスを設定(前述の処理と同じようにすれば良い)。
- FreeBSDではカーネルのようないくつかの重要なファイルのフラグがschg(システムの変更禁止フラグ)である。これがあると移動や削除ができない。これを解除するためには次のようなフラグの変更が必要。
chflags noschg /sbin/init
- dumpユーティリティというファイルシステムのバックアップのためのユーティリティがある。jailにとってファイルシステムの管理は不要であり、/etc/rmtのリンクを解除する。
unlink /etc/rmt
jailの実行
jail機能を有効にするためには、/etc/rc.d/jailという起動スクリプトを使用する。しかしそのためには、rc.confの設定が必要である。
rc.conf
ホスト側のrc.confにはいくつかの設定が必要である。設定にはjail機能の設定と各jailの設定の2種類がある。 また、各jailが使用するネットワークインタフェースをホストのネットワークインタフェースのエイリアスしたものを使用するならばその設定も必要である。
使用するネットワークインタフェースが"re0"ならば次のようなコマンドを実行すれば良い。
user% ifconfig re0 alias 192.168.101 netmask 255.255.255.0
この処理を起動時に自動的に行うならば、以下のようにrc.confに記述すれば良い。
ifconfig_re0_alias0="inet 192.168.1.101 netmask 255.255.255.0"
ifconfig_re0_alias1="inet 192.168.1.102 netmask 255.255.255.0"
そしてjail機能や各jailの設定は次のように記述すれば良い。
jail_enable="YES"
jail_list="myjail1 myjail2"
jail_set_hostname_allow="NO"
jail_socket_unixiproute_only="YES"
jail_sysvipc_allow="YES"
jail_stop_jailer="NO"
jail_myjail1_rootdir="/home/jail/myjail1"
jail_myjail1_hostname="myjail1"
jail_myjail1_ip="192.168.1.101"
jail_myjail1_exec="/bin/sh /etc/rc"
jail_myjail1_devfs_enable="YES"
jail_myjail1_fdescfs_enable="NO"
jail_myjail1_procfs_enable="YES"
jail_myjail2_rootdir="/home/jail/myjail2"
jail_myjail2_hostname="myjail2"
jail_myjail2_ip="192.168.1.102"
jail_myjail2_exec="/bin/sh /etc/rc"
jail_myjail2_devfs_enable="YES"
jail_myjail2_fdescfs_enable="NO"
jail_myjail2_procfs_enable="YES"
rc.confの設定が完了すれば、起動スクリプトで実行できる。
user% /etc/rc.d/jail start myjail1
jail.conf
jail.confで使用するパラメータ名はrc.confで使用したものと異なる場合が多い。それらの情報はmanで閲覧できる。
jail.confは次の2種類の文からなる。
- 全てのjailの基となる設定
- 各jail個別の設定
# shared rule
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
mount.devfs;
# myjail1's rule
myjail1 {
path = "/home/jail/myjail1";
host.hostname = "myjail1";
ip4.addr = 192.168.1.101;
}
# myjail2's rule
myjail2 {
path = "/home/jail/myjail2";
host.hostname = "myjail2";
ip4.addr = 192.168.1.102;
}
jail.confには変数が利用できる。変数には特別なものがありjail名などはnameという変数に格納される。それゆえ、前述のpathやhost.hostnameのように一部だけ違う場合は次のように記述できる。
# shared rule
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
mount.devfs;
path = "/home/jail/${name}";
host.hostname = "${name}";
# myjail1's rule
myjail1 {
ip4.addr = 192.168.1.101;
}
# myjail2's rule
myjail2 {
ip4.addr = 192.168.1.102;
}
jail関連コマンド
jailの制御には次のようなコマンドがある。
コマンド | 機能 | 使用例 |
---|---|---|
jls | jailの一覧を表示 |
|
jexec | JIDを指定し、そのjailで指定したコマンドを実行 |
jexecでシェルを指定すればjail内で作業ができる。
なおFreeBSD10では前述の引数ではエラーが返され、次のように名前を指定しなければならなかった。
|