Hatena::Diary

masakiの雑記帳

2008-03-11

LinuxでLVM領域を暗号化: 導入

ファイルサーバRAID暗号化したいなあと思案中。トラブルがない時はいいけど、故障したときに壊れたHDDをそのまま捨てるのはちょっといやだなあ、と。

てことでまずは手始めに、端末にしているPC-LinuxのLVM領域全体を暗号化してみることに。

変更前の構成は次のような感じ。

hda:
  /dev/hda1  Windows recovery
  /dev/hda2  Windows
  /dev/hda3  /boot
  /dev/hda5  swap
  /dev/hda6  /
  /dev/hda7  LVM PV - VG:vg0

LVM VG:vg0:
  /dev/vg0/lvusr       6G /usr
  /dev/vg0/lvvar       4G /var
  /dev/vg0/lvtmp       2G /tmp
  /dev/vg0/lvusrlocal  6G /usr/local
  /dev/vg0/lvhome      1G /home

このうち、hda7全体をdm-crypt+LUKSにて暗号化する。

カーネルなどの状態は次の通り。

必要なものは:

  • linux-2.6.xカーネル (2.6.4以降ならOKらしい by dm-crypt website)
  • cryptsetupコマンド

参考資料は:

方針は:

  • LVM領域全体を暗号化する
  • /、/boot、swap暗号化しない
  • LVM領域の暗号化鍵は、ファイル1つとパスフレーズ1つの2段構え。どちらか1つだけでも復号できる。ファイルな鍵は /etc/lvm/lvm.seckey として保管する

準備

hda7内の全データを外付けHDDなどに退避。

対象領域を乱数で埋める

暗号化前の領域が平文のまま未使用領域に残っていると意味がないので、まず対象領域を乱数で埋める。

single userモードで起動、hda7を使っていない状態にする。hda7全体を疑似乱数で塗りつぶす。

# dd if=/dev/urandom of=/dev/hda7 bs=`blockdev --getss /dev/hda7` count=`blockdev --getsize /dev/hda7`

手元のPCでは3Mbytes/secぐらい。相当待たされる。

横着したい場合は、swap領域あたりを使って適当な長さの乱数列を用意し、それを繰り返しコピーすることでお茶を濁してもよい。

ゼロ埋めで消すだけでも元の平文は消去できる。ただ、使用開始後に平文側を見ると、使用領域は非ゼロ・未使用領域はゼロとなるため、どこが使用領域なのかがわかってしまうという問題がある。

鍵の作成

後で出てくる通り鍵長は256ビット(= 32バイト)なので、32バイト長の鍵を作成。

# dd if=/dev/random of=/etc/lvm/lvm.seckey bs=1 count=32

LUKSパーティションの作成

まずパスフレーズで作成、続いてファイルな鍵を追加登録。
(順序は単なる好み。ファイルを先にした方が手数は少ない)

# cryptsetup --cipher aes-cbc-essiv:sha256 --key-size 256 luksFormat /dev/hda7
→ パスフレーズを2回入力する
# cryptsetup luksAddKey /dev/hda7 /etc/lvm/lvm.seckey
→ パスフレーズを1回入力する

状態確認。

# cryptsetup luksDump /dev/hda7
LUKS header information for /dev/hda7

Version:        1
Cipher name:    aes
Cipher mode:    cbc-essiv:sha256
...
Key Slot 0: ENABLED
        Iterations: ...
...
Key Slot 1: ENABLED
        Iterations: ...
...
Key Slot 2: DISABLED
Key Slot 3: DISABLED
...

dm-cryptデバイスの作成

/dev/hda7 を暗号化したブロックデバイスとして、/dev/mapper/crypt-hda7を作成する。
(マッピング後の名前には特に意味はない。お好みで)

# cryptsetup --key-file /etc/lvm/lvm.seckey luksOpen /dev/hda7 crypt-hda7

LVMとファイルシステムの構築

LVMのPV・VG・LVと各ファイルシステムを作成。構成は暗号化前のものと同一。

# pvcreate /dev/mapper/crypt-hda7
# vgcreate vg0 /dev/mapper/crypt-hda7
# lvcreate --size 6G --name lvusr vg0
# lvcreate --size 4G --name lvvar vg0
# lvcreate --size 2G --name lvtmp vg0
# lvcreate --size 6G --name lvusrlocal vg0
# lvcreate --size 1G --name lvhome vg0
# mkfs -t ext3 /dev/vg0/lvusr
# mkfs -t ext3 /dev/vg0/lvvar
# mkfs -t ext3 /dev/vg0/lvtmp
# mkfs -t ext3 /dev/vg0/lvusrlocal
# mkfs -t ext3 /dev/vg0/lvhome

起動時の設定

/etc/crypttabを編集。次の1行を追加。

crypt-hda7 /dev/hda7 /etc/lvm/lvm.seckey luks

再起動し、crypt-hda7上のLVM領域がちゃんと自動認識されることを確認。

なお、手元のDebian sid(この記事を書いている時点のもの)では、/etc/crypttabを読むのは/etc/rcS.d/S26cryptdisks-earlyで、/etc/rcS.d/S26lvm2よりも(僅差だが)先に起動されるようになっていた。

ファイルシステムの内容を復元

退避しておいた全データを復元。

動作確認

通常モードで再起動。元通り動作することを確認。

実に何事もなかったかのように動く。起動時のログにもうちょっと報告があっても良さそうなものだが... まあいいか。

課題とか諸々

鍵が2つなのはなぜ?
ファイルな鍵は人手を介さずにbootするため。パスフレーズな鍵はファイルな鍵を失ってもデータを読み出す手段を残しておくため
鍵が同一ストレージ上に生のまま入っていると意味ないのでは?
その通り。まああくまでテストなので。
対象が端末的なものなら、再起動時に対話的操作を伴ってもよいので、ファイルな鍵を削除して起動時にパスフレーズを入れさせるという運用もあり。
対象がサーバなら、人がいないと再起動できないようでは困るので、物理的に異なるストレージデバイスに鍵を入れるなどが現実的か
/とか/bootは暗号化しないの?
難しそうなのでパス。どのぐらいできるのかも調べていない
swap暗号化しないの?
同上。ハイバネーションとの兼ね合いも未調査
性能は?
これから測ってみる

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証