コンピュータ/ソフトウェア関連Tips

GEOM ELIによる暗号化とアタッチ

作成日: Jul 14, 2014
カテゴリー: FreeBSD タグ: FreeBSD

GEOM ELIによりハードディスクを暗号化して、それをアタッチするまでの手順です。4台のハードディスクでraidz1を構築する想定です。FreeBSDのバージョンは10.0 RELEASEです。

この記事は、FreeBSDセットアップメモの一部です。

前提事項

前提として、
1. キーファイルは4個のハードディスクで共通のものを用いる。
2. パスフレーズも同様。パスフレーズは、スクリプト中で1回入力すれば済むようにする。

ハードディスクの確認

さて、ハードディスクの確認は、http://www.freebsd.org/doc/en/books/handbook/disks-adding.htmlには、

Inspect /var/run/dmesg.boot to ensure the new disk was found.

と書いてあるので、実行してみます。

$ cat /var/run/dmesg.boot

ada0 at ahcich0 bus 0 scbus0 target 0 lun 0
ada0: <WDC WD30EZRX-00MMMB0 80.00A80> ATA-8 SATA 3.x device
ada0: Serial Number WD-WCAWZ2766207
ada0: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada0: Command Queueing enabled
ada0: 2861588MB (5860533168 512 byte sectors: 16H 63S/T 16383C)
ada0: quirks=0x1<4K>
ada0: Previously was known as ad4
(略)
ada3 at ahcich3 bus 0 scbus3 target 0 lun 0
ada3: <WDC WD30EZRX-00MMMB0 80.00A80> ATA-8 SATA 3.x device
ada3: Serial Number WD-WCAWZ2955765
ada3: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada3: Command Queueing enabled
ada3: 2861588MB (5860533168 512 byte sectors: 16H 63S/T 16383C)
ada3: quirks=0x1<4K>
ada3: Previously was known as ad10
ada4 at ahcich5 bus 0 scbus5 target 0 lun 0
ada4: <HDT722525DLA380 V44OA9BA> ATA-7 SATA 1.x device
ada4: Serial Number VDS41DT7CGNEKJ
ada4: 150.000MB/s transfers (SATA 1.x, UDMA6, PIO 8192bytes)
ada4: Command Queueing enabled
ada4: 238475MB (488397168 512 byte sectors: 16H 63S/T 16383C)
ada4: Previously was known as ad14

ada4は起動ドライブです。

ハードディスク初期化(必要に応じて)

パーティションを作成済の場合は、初期化します。

$ sudo gpart destroy -F ada0

このあと、gpart create -s GPT ada0などはしません。アタッチするときに、以下のような警告が表示されてしまいます。(筆者は3時間くらいはまって、泣きそうになりました。)

Jul 19 18:26:53 myhost kernel: GEOM: ada0: the secondary GPT table is corrupt or invalid.
Jul 19 18:26:53 myhost kernel: GEOM: ada0: using the primary only -- recovery suggested.
Jul 19 18:26:53 myhost kernel: GEOM: diskid/DISK-WD-WCAWZ2766207: the secondary GPT table is corrupt or invalid.
Jul 19 18:26:53 myhost kernel: GEOM: diskid/DISK-WD-WCAWZ2766207: using the primary only -- recovery suggested.

/boot/loader.confの設定

/boot/loader.confに以下を追加。

geom_eli_load="YES"

デバイスの確認

リブートします。

ls /dev/ada* を実行した結果は、

/dev/ada0       /dev/ada1.nop   /dev/ada3       /dev/ada4p1     /dev/ada4p4
/dev/ada0.nop   /dev/ada2       /dev/ada3.nop   /dev/ada4p2     /dev/ada4p5
/dev/ada1       /dev/ada2.nop   /dev/ada4       /dev/ada4p3

adaN.nopは、AFT対策したハードディスクです。

キーファイルの作成

http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/disks-encrypting.htmlを参考にして作業。

$ sudo mkdir /root/.geli
$ sudo dd if=/dev/random of=/root/.geli/geli.key bs=64 count=1
1+0 records in
1+0 records out
64 bytes transferred in 0.000109 secs (586104 bytes/sec)

キーファイルのバックアップ

USBメモリを刺す。デバイスは、例えば、/var/log/messagesで確認。

$ tail /var/log/messages
$ sudo mkdir /mnt/usbstick
$ sudo mount_msdosfs /dev/da1s1 /mnt/usbstick

da1p1ではない理由は、http://www.freebsd.org/doc/ja/books/handbook/disks-adding.htmlによれば、

FreeBSD では、従来の BSD パーティションと混乱しないように PC BIOS パーティションのことをスライスと呼びます。

ということらしい。

そして、以下のコマンドでコピー。

$ sudo cp /root/.geli/geli.key /mnt/usbstick

アンマウントするには、

$ sudo umount /mnt/usbstick

GELIによる初期化

$ sudo geli init -l 256 -s 4096 -K /root/.geli/geli.key /dev/ada0.nop

Enter new passphrase:
Reenter new passphrase:

Metadata backup can be found in /var/backups/ada0.nop.eli and
can be restored with the following command:

        # geli restore /var/backups/ada0.nop.eli /dev/ada0.nop

これを他のハードディスク分繰り返します。パスフレーズは、同じ文字列を入力します。(そうしないと、スクリプトで1回入力するだけで済むように出来ない。)

$ sudo geli init -l 256 -s 4096 -K /root/.geli/geli.key /dev/ada1.nop
$ sudo geli init -l 256 -s 4096 -K /root/.geli/geli.key /dev/ada2.nop
$ sudo geli init -l 256 -s 4096 -K /root/.geli/geli.key /dev/ada3.nop

手動アタッチ

暗号化したハードディスクをアタッチします。

$ sudo geli attach -k /root/.geli/geli.key /dev/ada0.nop
Enter passphrase:

これを他のディスク分繰り返します。

$ sudo geli attach -k /root/.geli/geli.key /dev/ada1.nop
$ sudo geli attach -k /root/.geli/geli.key /dev/ada2.nop
$ sudo geli attach -k /root/.geli/geli.key /dev/ada3.nop

無事アタッチされているか確認します。

$ ls /dev/ada*
/dev/ada0               /dev/ada2               /dev/ada4
/dev/ada0.nop           /dev/ada2.nop           /dev/ada4p1
/dev/ada0.nop.eli       /dev/ada2.nop.eli       /dev/ada4p2
/dev/ada1               /dev/ada3               /dev/ada4p3
/dev/ada1.nop           /dev/ada3.nop           /dev/ada4p4
/dev/ada1.nop.eli       /dev/ada3.nop.eli       /dev/ada4p5

/dev/ada0.nop.eli、/dev/ada1.nop.eli、/dev/ada2.nop.eli、/dev/ada3.nop.eliができています。

手動デタッチ

マウントしている場合は、umountしてからdetachでしょうが、まだマウントしていないので、そのままdetachしてみます。

$ sudo geli detach /dev/ada0.nop.eli
$ sudo geli detach /dev/ada1.nop.eli
$ sudo geli detach /dev/ada2.nop.eli
$ sudo geli detach /dev/ada3.nop.eli

デタッチされているか確認してみます。

$  ls /dev/ada*
/dev/ada0       /dev/ada1.nop   /dev/ada3       /dev/ada4p1     /dev/ada4p4
/dev/ada0.nop   /dev/ada2       /dev/ada3.nop   /dev/ada4p2     /dev/ada4p5
/dev/ada1       /dev/ada2.nop   /dev/ada4       /dev/ada4p3

/dev/ada0.nop.eli、/dev/ada1.nop.eli、/dev/ada2.nop.eli、/dev/ada3.nop.eliが消えています。

まとめてアタッチ/デタッチ

geli attach の-j オプションで、パスフレーズを記録したファイルを読み込むことが出来るのですが、ファイルを介することなくオプションを渡す方法が無いかな…と思ってネットを探したら、 http://forums.nas4free.org/viewtopic.php?f=67&t=2165にて、スクリプトでアタッチしている方がいらっしゃいました。その方は、スクリプト中で

echo $pword | /sbin/geli attach -j - /dev/da0

としていました。なるほどね。

これを真似して、以下のようなスクリプトを作成しました。

#!/usr/local/bin/bash
# Filename: /usr/local/bin/attach_disks.sh
# This script has two functions:
#  1. Attach the geli encrypted disks.
#  2. Detach the geli encrypted disks.
devicePrefix="/dev/ada"
deviceSuffix=".nop"
indexStart=0
indexEnd=3
keyFile="/root/.geli/geli.key"
function attach() {
  echo "Enter geli passphrase. Your entry would NOT be echobacked."
  stty -echo
  read passphrase
  stty echo
  for no in $(seq ${indexStart} ${indexEnd}); do
    drive=${devicePrefix}${no}${deviceSuffix}
    if [ -e ${drive}.eli ]; then
      echo "${drive}: Already attached."
    else
      echo "${drive}: Attaching ..."
      echo ${passphrase}|/sbin/geli attach -k ${keyFile} -j - ${drive}
    fi
  done
}

function detach() {
  for no in $(seq ${indexStart} ${indexEnd}); do
    drive=${devicePrefix}${no}${deviceSuffix}.eli
    if [ -e ${drive} ]; then
      echo "${drive}: Detaching ..."
      /sbin/geli detach ${drive}
    else
      echo "${drive}: Not attached."
    fi
  done
}

if [ $# -eq 0 ]; then
  attach
elif [ $1 == "-r" ]; then
  detach
fi

echo "Following is a result of \"ls ${devicePrefix}*.eli\" command."
ls ${devicePrefix}*.eli

環境に合わせて、冒頭の

devicePrefix="/dev/ada"
deviceSuffix=".nop"
indexStart=0
indexEnd=3
keyFile="/root/.geli/geli.key"

を変更します。実際に実行するとこんな感じ。

$ sudo attach_disks.sh
Enter geli passphrase. Your entry would NOT be echobacked.
/dev/ada0.nop: Attaching ...
/dev/ada1.nop: Attaching ...
/dev/ada2.nop: Attaching ...
/dev/ada3.nop: Attaching ...
Following is a result of "ls /dev/ada*.eli" command.
/dev/ada0.nop.eli       /dev/ada2.nop.eli
/dev/ada1.nop.eli       /dev/ada3.nop.eli

デタッチはこんな感じ。

$ sudo attach_disks.sh -r
/dev/ada0.nop.eli: Detaching ...
/dev/ada1.nop.eli: Detaching ...
/dev/ada2.nop.eli: Detaching ...
/dev/ada3.nop.eli: Detaching ...
Following is a result of "ls /dev/ada*.eli" command.
ls: /dev/ada*.eli: そのようなファイルまたはディレクトリはありません

実際のところは、アタッチ後にZFS Poolをマウントして、Samba serverを起動するようにしているのですが、それは別記事にて書きます。