Jail

FreeBSDにはJailという技術がある。

Jailとは、OSレベルの仮想化技術だ。
Jailを使うと、FreeBSDマシン上にいくつもの独立したシステムを構築できる。

たとえば、一つのFreeBSDのうえに、Samba, Apacheをそれぞれ独立させて構築させることができる。
独立、というのは、Apache側のシステムで何が起こっても、Samba側のシステム、ホストのFreeBSDには何の影響もないということ。

もっと深いところで仮想化するESXiやらXenやらと比べると、オーバーヘッドが小さいという利点がある(と思ってます)。
これらの方法だと、各サービスを独立させたいときには、OSごとインストールする必要があるから。
(仮にあるマシン上でDHCPサーバ, DNS, Samba, Apacheを動かすとして、それぞれ向けにOSをインストール、というのはさすがに辛い。)

詳しくは下記。

http://ja.wikipedia.org/wiki/FreeBSD_jail

Jailの利点
仮想化: 各jailはホストマシン上で動く仮想機械であり、独自のファイルシステムやプロセス空間、ユーザーアカウントを持つ。jailの中のプロセスからは実際のシステムなのかjailの中なのかはほぼ区別できない。
安全性: 各jailは他のjailにアクセスできないようになっており、安全性が高まっている。
権限委譲の簡素化: 管理者権限のスコープがjail内に制限されているため、システムの管理者は本来管理者権限が必要な仕事を、計算機全体を操作する権限を渡すことなく行わせることが出来る。

Jail…でなくezjailにしよう。

FreeBSD Handbookより抜粋する。

Jailのセットアップには、FreeBSDとその使用方法についての高度な経験が必要である。
下記に示す手順が複雑と感じるならば、sysutils/ezjailなどの、より簡単なシステムを検討せよ
16.6.1.1. Design
http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/jails-application.html

ひとめ見てウンザリしたのでezjailにする。

ezjailたったこれだけ(インストールと設定)。

チュートリアルはここにある。
http://erdgeist.org/arts/software/ezjail/

インストールはpkgから。

# pkg_add ezjail

そして最低限の前準備。
/etc/rc.confへの追加。

# ezjail
ezjail_enable="YES"

ezjail.confへの追記。

ezjail_ftphost=ftp2.jp.freebsd.org

ezjailはFreeBSDの各種データをftpサーバからダウンロードする。
デフォルトだと本家のftpサーバに繋がってしまうので、最寄りのftpサーバを指定する。

Jailたったこれだけ(Jail環境の構築)

ここまで来たら、Jail環境そのものの初期設定をする。

ezjail-admin installが初回設定用のコマンドで、使用するのは原則、一回だけでよい。
このコマンドで、Jail関連のディレクトリやらベース環境が作られる。

$ sudo ezjail-admin install
Your system is 9.2-RC3. Normally FTP-servers don't provide non-RELEASE-builds.
Querying your ftp-server... The ftp server you specified (ftp2.jp.freebsd.org) seems to provide the following builds:
drwxr-xr-x 2 ftp ftp 4096 Sep 13 15:43 10.0-ALPHA1
lrwxrwxrwx 1 ftp ftp 14 Feb 16 2013 8.3-RELEASE -> ../8.3-RELEASE
drwxr-xr-x 2 ftp ftp 4096 May 22 12:59 9.1-RELEASE
drwxr-xr-x 2 ftp ftp 4096 Aug 16 20:47 9.2-RC2
drwxr-xr-x 2 ftp ftp 4096 Sep 11 22:14 9.2-RC4
drwxr-xr-x 6 ftp ftp 4096 Sep 13 16:35 ISO-IMAGES
Release [ 9.2-RC3 ]:

ezjailはホストOSと同じバージョンで環境を作ろうとする。
しかしホストOSがRELEASEビルドでない場合、言い換えるとホストOSのバージョンがftpサーバに存在しない場合には、上記の通り自分で指定をしなければならない。

この状態なら9.2-RC4でしょうなあ。

なお、バージョンをどのように判定しているかというと、ホストOSでuname -rを実行したときの出力と、ftpサーバのディレクトリとのマッチングである。

Release [ 9.2-RC3 ]:9.2-RC4
(中略)
/usr/jails/basejail/usr/lib32/libalias_pptp.a
/usr/jails/basejail/usr/lib32/libusb_p.a
/usr/jails/basejail/usr/lib32/libalias_ftp.so
110276 blocks
Note: a non-standard /etc/make.conf was copied to the template jail in order to get the ports collection running inside jails.
$

デフォルト設定では、/usr/jailsに各種ファイルが作られる。

$ ls /usr/jails/
basejail flavours newjail

Jailたったこれだけ(Jailホストの構築と起動)

たったこれだけと言いつつJailホストの構築までが長かった。
ezjail-admin createでjailホストを作り、ezjail-admin startでjailホストを起動する。
ezjail-admin consoleでjailホストのコンソールにアクセスする。
と言う流れ。

Jailホストに192.168.1.199というIPアドレスを付与するとし、また、ホストマシンのネットワークIFがem0であるとして、以下のように。

$ sudo ezjail-admin create example 'em0|192.168.1.199'
(中略)
/usr/jails/example/./sys
/usr/jails/example/./basejail
3146 blocks
Warning: IP em0|192.168.100.201 not configured on a local interface.
$

/usr/jailsの下にexampleとして作られたことが分かる。

$ ls /usr/jails
basejail example flavours newjail

そして起動

$ sudo ezjail-admin start example
Configuring jails:.
Starting jails: example.
$

コンソールへ

$ sudo ezjail-admin console example
FreeBSD 9.2-RC3 (GENERIC) #0 r254795: Sat Aug 24 20:25:04 UTC 2013
Welcome to FreeBSD!
(中略)
root@example:~ #
root@example:~# uname -a
FreeBSD example 9.2-RC3 FreeBSD 9.2-RC3 #0 r254795: Sat Aug 24 20:25:04 UTC 2013 root@bake.isc.freebsd.org:/usr/obj/usr/src/sys/GENERIC amd64

Jailたったこれだけ、とは言うけれど。

jailホストは起動したけれども、ご覧のようにネットには出ていけない。これはresolv.confがないから。
時刻もUTCになっている。
また、驚くことにrc.confもない。

root@example:~ # ftp ftp2.jp.freebsd.org
ftp: Can't lookup `ftp2.jp.freebsd.org:ftp': hostname nor servname provided, or not known
ftp> bye
root@example:~ # date
Sun Sep 15 13:51:21 UTC 2013
root@example:~ # cat /etc/rc.conf
cat: /etc/rc.conf: No such file or directory
root@example:~ #

Listenポートを調べてみると、あーあ、sendmailやsyslogdがListenしてしまっている。

root@example:~ # sockstat -l4
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
root sendmail 1322 3 tcp4 192.168.100.201:25 *:*
root syslogd 1268 6 udp4 192.168.100.201:514 *:*
root@example:~ #

先述のチュートリアルにあるQuickStartは早いものの、かように設定が足りません。
そのため、けっこう基本的なところから自分で構築していかなければならない。
ということで、ezjailの設定を詰めることにして、試しに作ったjailホストは消してしまおう。

jailホストからlogoutし、ezjail-adminでstopし、deleteすればOK。

root@example:~ # logout
$ sudo ezjail-admin stop example
パスワード:
Stopping jails: example.
$ sudo ezjail-admin delete -w example
$ ls /usr/jails
basejail flavours newjail
$

deleteのときに-wを付け忘れると、/usr/jails/exampleが残る。
もちろん手動で消すこともできるが、schgフラグが立っているので簡単には消せない。

$ sudo ezjail-admin delete example
$ ls
basejail example flavours newjail
$ sudo rm -Rf ./example
rm: ./example/var/empty: Operation not permitted
rm: ./example/var: Directory not empty
rm: ./example: Directory not empty
$

こういう場合には、schgフラグを消してからrmすること。

$ sudo chflags -R noschg ./example
$ sudo rm -Rf ./example
$ ls
basejail flavours newjail
$

また、deleteの際に-wfとすると、jailを止めてから削除してくれる。

ezjail-admin delete -wf example

ezjailの設定は記事を改めてまとめる。