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

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

作成日: Jul 21, 2019
更新日: Jul 21, 2019
カテゴリー: FreeBSD タグ: FreeBSD

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

前提事項

前提として、

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

ハードディスクの確認

$ cat /var/run/dmesg.boot
ada0 at ahcich1 bus 0 scbus1 target 0 lun 0
ada0: <M4-CT064M4SSD2 0309> ACS-2 ATA SATA 3.x device
ada0: Serial Number 00000000111703069F93
ada0: 600.000MB/s transfers (SATA 3.x, UDMA5, PIO 8192bytes)
ada0: Command Queueing enabled
ada0: 61057MB (125045424 512 byte sectors)
ada0: quirks=0x1<4K>
uhub0: 2 ports with 2 removable, self powered
uhub1: 2 ports with 2 removable, self powered
uhub2: 2 ports with 2 removable, self powered
uhub3: 2 ports with 2 removable, self powered
ada1 at ahcich8 bus 0 scbus8 target 0 lun 0
ada1: <Hitachi HDS723020BLA642 MN6OA180> ATA8-ACS SATA 3.x device
ada1: Serial Number MN1221F3010YZA
ada1: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada1: Command Queueing enabled
ada1: 1907729MB (3907029168 512 byte sectors)
(略)
ada6 at ahcich13 bus 0 scbus13 target 0 lun 0
ada6: <Hitachi HDS723020BLA642 MN6OA180> ATA8-ACS SATA 3.x device
ada6: Serial Number MN1220F302Y0LD
ada6: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada6: Command Queueing enabled
ada6: 1907729MB (3907029168 512 byte sectors)

ada0は起動ドライブです。

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

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

$ sudo gpart destroy -F ada1

このあと、gpart create -s GPT ada0などはしません。

/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

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

GELIによる初期化

$ sudo geli init -l 256 -s 4096 -K /root/.geli/geli.key /dev/ada1.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/ada6.nop

手動アタッチ

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

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

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

$ sudo geli attach -k /root/.geli/geli.key /dev/ada1.nop
…
$ sudo geli attach -k /root/.geli/geli.key /dev/ada6.nop

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

$ ls /dev/*.eli
/dev/ada1.nop.eli       /dev/ada3.nop.eli       /dev/ada5.nop.eli
/dev/ada2.nop.eli       /dev/ada4.nop.eli       /dev/ada6.nop.eli

手動デタッチ

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

$ sudo geli detach /dev/ada1.nop.eli
…
$ sudo geli detach /dev/ada6.nop.eli

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

$  ls /dev/*.eli
ls: /dev/*.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=1
indexEnd=6
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=1
indexEnd=6
keyFile="/root/.geli/geli.key"

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

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

デタッチはこんな感じ。

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

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