ZFS root on geli

geliで暗号化したディスクの上にZFS rootを乗せようという試みです。
まぁ、ほぼ思っていた通りに出来ました。ちなみにFreeBSD 7.0-RELEASE/amd64という環境です。
ZFS rootについてはhttp://fragile-graciousness.net/svr_fbsd_zfs.htmlを参考にさせて頂きました。ありがとうございます。


インストール

ディストリビューションはMinimalにします。
自分はディスクを一台全部を使いました。パーティションは以下の通り。

ad4s1a
UFS 512M マウントポイントは「/」後の/boot。
ad4s1b
Swap メモリの2倍。
ad4s1d
残り全部。マウントポイントは一度付けてから削除。こうしないとパーティションが切れない。これにZFSが乗る。

Minimalでad4s1aにインストール。


暗号化ディスクの作成

インストールしたディスクからシングルユーザーモードで起動。まずは書き込みできるようにする。

# mount -w /

次に、ad4s1d(ZFSを乗せるディスク)をgeliで暗号化する。

# geli init -b -s 4096 /dev/ad4s1d
Enter new passphrase:    ←パスフレーズを聞かれるので入力
Reenter new passphrase:  ←再度入力

暗号化出来たら次はアタッチ。

# geli attach -d /dev/ad4s1d
Enter passphrase:    ←先ほどのパスフレーズを入力

以上で/dev以下にad4s1d.eliというデバイスファイルが出来ているハズ。確認。

# ls /dev/*.eli
/dev/ad4s1d.eli

暗号化ディスクにZFSを乗せる

まずはプールの作成。これが無くっちゃ始まらねぇ。

# zpool create tank /dev/ad4s1d.eli  ←geli化したデバイスを指定

お次はZFSファイルシステムの作成。各人の好みで適当に。

# zfs create -o reservation=10G tank/usr  ←領域予約をしてみたり
# zfs create tank/usr/local
# zfs create tank/usr/ports
# zfs create tank/usr/src
# zfs create tank/usr/obj
# zfs create -o compress=gzip tank/var    ←圧縮ファイルシステムにしたり
# zfs create -o quota=1G tank/var/log     ←容量制限掛けたり
# zfs create tank/home

/etc/rc.confの編集

起動時にgeliのアタッチとZFSの自動マウントをする為に以下の様に追加。

# echo 'geli_devices="ad4s1d"' >> /etc/rc.conf
# echo 'geli_default_flags="-d"' >> /etc/rc.conf
# echo 'zfs_enable="YES"' >> /etc/rc.conf

FreeBSDシステムのコピー

インストールしたシステムをZFSの上にコピーする。

# find -x / | cpio -pmd /tank

ブートの準備

まずはディレクトリの修正から。

# rm -rf /tank/boot
# mkdir /tank/bootdir
# cd /tank
# ln -s bootdir/boot boot

次はブートローダーの設定。geliとzfsのモジュールを読み込んで、ZFSの為のカーネルメモリを設定します。

# echo 'geom_eli_load="YES"' >> /boot/loader.conf
# echo 'zfs_load="YES"' >> /boot/loader.conf
# echo 'vfs.root.mountfrom="zfs:tank"' >> /boot/loader.conf
# echo 'vm.kmem_size="1073741824"' >> /boot/loader.conf

ちなみに、自分の環境ではカーネルメモリを1GにしないとZFS rootで起動しませんでした:P
次に/etc/fstabの編集です。

# vi /tank/etc/fstab
/dev/ad4s1a /        ufs rw 1 1  ←これを
              ↓
/dev/ad4s1a /bootdir ufs rw 0 0  ←こう変更

最後の二つは自分の好みです。


ZFSのマウントポイントを設定

最後の仕上げです。

# cd /
# zfs set mountpoint=/usr tank/usr
# zfs set mountpoint=/usr/local tank/usr/local
# zfs set mountpoint=/usr/ports tank/usr/ports
# zfs set mountpoint=/usr/src tank/usr/src
# zfs set mountpoint=/usr/obj tank/usr/obj
# zfs set mountpoint=/var tank/var
# zfs set mountpoint=/var/log tank/var/log
# zfs set mountpoint=/home tank/home
# zfs set mountpoint=legacy tank

リブート

ではでは、リブートしてZFS root on geliを起動しませう。


おまけ

このままでも使えるのですが、ad4s1a(/bootdir)に不要なファイルがごっそりあります。消していきます。

# cd /bootdir
# chflags noschg var/empty
# rm -rf `ls | grep '[^boot]'`

次にファイルをコピーします。

# cd /bootdir
# mv boot boot.old  ←バックアップは大事
# cp -Rp boot.old/* .
# mv boot boot.file
# ln -s . boot

次はブートローダーです。

# echo '/loader' >> /bootdir/boot.config

/bootのシンボリックリンクディレクトリに変えます。

# rm /boot
# mkdir /boot
# vi /etc/fstab
/dev/ad4s1a /bootdir ufs rw 0 0  ←これを
              ↓
/dev/ad4s1a /boot    ufs rw 0 0  ←こう変更

で、リブート。正常に立ち上がったら/bootdirを削除します。

# rm -rf /bootdir

めでたしめでたし

ようやくZFS root on geliが構築できました。これで、いつガサ入れが盗難にあってもディスクの中を見られるコトはありません。:-)


追記
2回目以降の起動が出来ません。パスフレーズまでは行くのですが、ZFS rootとして起動しませんでした。一回はうまくいったのになぁ。:-(

起動できました。8-CURRENTだったからか?