パッケージで入れようとして、pkg_addすると「Broken pipe」って言われた。
# pkg_add ftp://ftp8.jp.freebsd.org/pub/FreeBSD/ports/i386/packages-8.0-release/All/libiconv-1.13.1.tbz
Fetching ftp://ftp8.jp.freebsd.org/pub/FreeBSD/ports/i386/packages-8.0-release/All/libiconv-1.13.1.tbz...Broken pipe
原因を調べるためにとりあえずファイルを取得する。
fetch ftp://ftp8.jp.freebsd.org/pub/FreeBSD/ports/i386/packages-8.0-release/All/libiconv-1.13.1.tbz
んで、原因を調べるために直接pkg_addしてみる。
# pkg_add ./libiconv-1.13.1.tbz
/usr/bin/tar: not found
pkg_add: tar extract of /root/libiconv-1.13.1.tbz failed!
pkg_add: unable to extract table of contents file from '/root/libiconv-1.13.1.tbz' - not a package?
ヽ(´A`)ノ?
tar がないってどういうことよ。
この間のJail内のサーバでした。んーなんだかなぁ。
フルツリーjail(Fat Jail)の構築方法をできるだけ簡単に書きます。

簡単に書くだけで、決して簡単にできるように書くわけではないのであしからずうんち

  1. ソースの準備
  2. システムのビルド
  3. システムのインストール
  4. デバイスファイルの作成
  5. jailに不要なファイルの削除
  6. jail環境のroot設定
  7. Host側のJail設定
  8. Jailの起動

ソースの準備

cvs-supfileの用意。
*default host=cvsup4.jp.freebsd.org
*default base=/usr/local/etc/cvsup
*default prefix=/usr
*default release=cvs tag=RELENG_8_0
*default delete use-rel-suffix
*default compress
src-all
viとかで適当に作成します。
ファイルの置き場所はどこでも構いません。ちなみに名前も何でもありデス。
今回はcvs-supfileとしました。
baseはどこでもいいのですが、一応/usr/local/以下に作成することを念頭に置いています。
mkdir /usr/local/etc/cvsup
cvsup cvs-supfile
baseは恐らくないので作成しておきます。
あとはcvsupするだけですが、もしcvsupが使えなければパッケージからインストールしておきます。
without-gui版がいいでしょう。
一例:
pkg_add ftp://ftp.jp.freebsd.org/pub/FreeBSD/ports/i386/packages-8.0-release/All/cvsup-without-gui-16.1h_4.tbz

システムのビルド

ソースの場所に移動してまずシステムをビルドしてやるわけですが、UPDATEを読むなり注意点には気を付けましょう。
cd /usr/src
(make buildworld >& buildworld.log) &
こうすればバックグラウンドで動作させながらログを取ることができます。
MakeWorldをやったことがあるならここまでの流れはそれと同じかと思います。
そして、jail環境にシステムをインストールします。
mkdir -p /usr/local/jail/01
前述どおり、/usr/local/以下に適当にjail環境をインストールするための領域を作ります。
ここはjailの一番目ということで/usr/local/jail/01としました。

システムのインストール

jail領域にシステムをインストールする
( make installworld DESTDIR=/usr/local/jail/01 > & installworld.log ) &

デバイスファイルの作成

/etc以下のファイルと/dev以下のデバイスファイルを作ります。
cd /usr/src/etc
make distribution DESTDIR=/usr/local/jail/01
mount_devfs devfs /usr/local/jail/01/dev
mount_devfs: Command not found.
と出てコマンドがない場合。
cd /usr/src/sbin/mount_std
make && make install
とすれば、mount_devfs がインストされるはず。
間違った場合は以下のようにして削除可能
umount /usr/local/jail/01/dev
chflags -R noschg /usr/local/jail/01
rm -rf /usr/local/jail/01
こんな感じで処理。
めんどくさいやり方をする理由は以前書いたものを参照

jailに不要なファイルの削除

jail環境では不必要なファイルを削除する。
リストは以下URLのデータを使うと楽。
http://memberwebs.com/nielsen/freebsd/jails/docs/jail_remove.html
FreeBSDの6系までしかないが、とりあえず利用する。
取ってきたファイルはどこでもいいが、/usr/local/jail/01 あたりに置いておく。
※以下、jail環境下とhost側の処理が並行するので、分けて表示する。
host# chroot /usr/local/jail/01
jail# chflags noschg /sbin/init
8系以外は /usr/sbin/sliploginもフラグを消さないといけない。
そして取ってきたファイルを適当に編集してから削除。
jail# cat jail-6.x-remove.txt | xargs rm -rf
一部コマンドを/usr/bin/trueにリンクする。
理由は削除リストで消したファイルの中に/etc/rc*の起動ファイルから使用されているコマンドがあるらしいので、jail環境が起動するときのエラーになるから、それらのコマンドを/usr/bin/trueにハードリンクしておきます。
jail# ln /usr/bin/true /sbin/init
fstabがないと起動時にエラーが出たかもなので、空のファイルでも置いとく。
jail# touch /etc/fstab
sendmailのwarningがでるので、/etc/mail/aliases.dbを作っておきます。
jail# newaliases
Hostのすでに解決している/etc/resolv.confをjail環境に写しておきます。
host# cp /etc/resolv.conf /usr/local/jail/01/etc/

jail環境のroot設定

jail環境のrootのパスワードを設定します。
jail# passwd root
Changing local password for root
New Password:
Retype New Password:
マシンのコンピューターの内蔵時計をローカルタイムに変更します。
jail# touch /etc/wall_cmos_clock
jail# ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
jail環境の/etc/syslog.confの/dev/consoleへの出力をコメントアウトしてエラーが表示されないようにします。
#*.err;kern.warning;auth.notice;mail.crit /dev/console
/etc/crontabの編集。
/usr/libexec/atrunとadjkerntz -aの行はコメントアウト。
#*/5 * * * * root /usr/libexec/atrun
#1,31 0-5 * * * root adjkerntz -a

Host側のJail設定

Jail環境下でもpingやtraceroute 等を利用できるようにしておきたいので、起動時に反映するよう、sysctl.confに記載しておく。
/etc/sysctl.confの中身の例
security.jail.allow_raw_sockets=1
security.jail.set_hostname_allowed=0
security.jail.sysvipc_allowed=0
上から、
# jail環境下でping,tracerouteを使えるようにする。
# jail環境下でホスト名の変更を出来ないようにする。
# jail環境下でシェアードメモリを使えるようにする。※通常は設定しない。例外はpostgres等一部のアプリケーションを利用するときのみ
rc.confの中身の例
# JAIL
jail_enable="YES"
jail_list="jail01 jail02"
jail_set_hostname_allow="NO"
jail_socket_unixiproute_only="YES"
jail_sysvipc_allow="NO"
jail_stop_jailer="NO"

# 01
jail_jail01_rootdir="/usr/local/jail/01"
jail_jail01_hostname="example.net"
jail_jail01_ip="192.168.0.xxx"
jail_jail01_exec="/bin/sh /etc/rc"
jail_jail01_devfs_enable="YES"
jail_jail01_fdescfs_enable="NO"
jail_jail01_procfs_enable="YES"
# 02
jail_jail02_rootdir="/usr/local/jail/02"
jail_jail02_hostname="example.com"
jail_jail02_ip="192.168.0.xxx"
jail_jail02_exec="/bin/sh /etc/rc"
jail_jail02_devfs_enable="YES"
jail_jail02_fdescfs_enable="NO"
jail_jail02_procfs_enable="YES"
jail_list="jail01" は、起動したいjailをスペース区切りで並べることで利用が可能。
jail_xxxx_rootdir 等はxxxxに上記で指定したリストを入れる。
jail環境に/etc/rc.confを設定することも可能。任意で。

あと、pingとtracerouteはリストをそのまま使うと削除されているはずなので、もし削除していたらHostからコピーしておく。

Jailの起動

起動方法はrc.confに書いておけば自動的に立ち上がる。
動的に立ち上げる場合や停止方法は以下。
/etc/rc.d/jail start
/etc/rc.d/jail stop
特定のJailだけ起動する場合も下記で可能。
/etc/rc.d/jail start jail01
また、現在の状態を確認するには
# jls
JID IP Address Hostname Path
1 192.168.0.xxx www.example.jp /usr/local/jail/02
JailにHostから直接ログインするには以下のようにすればよい。
# jexec 13 /bin/csh

今回はこちらのサイトを参照させてもらいました。ありがたいです。

[24時間365日] サーバ/インフラを支える技術 ‾スケーラビリティ、ハイパフォーマンス、省.../安井 真伸

¥2,919
BSDカーネルの設計と実装―FreeBSD詳解/マーシャル・カーク マキュージック

¥6,300
Amazon.co.jp