2014年12月14日日曜日

luksによるルートパーティションの暗号化 (1枚目SoftLayer Advent Calendar 2014第14日目)

1枚目 SoftLayer Advent Calendar 2014 (http://qiita.com/advent-calendar/2014/softlayer) の第14日目になります。

クラウドでセキュリティを考え始めると、ファイルシステム暗号化の話を避けて通れなくなります。気軽にシステムバックアップを取得して、複製して、持ち運んでということが今までよりも頻繁になります。そのセキュリティ対策として、ファイルシステム丸ごとパーティション単位で暗号化しておく、という考えた方が増えてくるものと思われます。

SoftLayer にはコンソールが提供されており、luks による暗号化の仕組みとフィットします。ルートパーティションを暗号化するところまで Linux の luks 関連ツールではサポートされています。OS 起動時にルートパーティションをマウントする前、復号化する前にコンソールを通じてパスフレーズを渡す仕組みが用意されています。

まず初めに、できないことを確認しておきます。
BIOS が対応していないので、/boot パーティションは暗号化できません。/boot パーティションには圧縮されたカーネルやルートパーティションをマウントするためのものしか置かれていないはずなので、問題にならないはずです。/boot パーティションには、余計なものを置いてはいけません。luks の鍵を置くなどはもってのほかです。暗号化している意味がなくなってしまいます。swap 用パーティションは暗号化します。

前回 (SoftLayerにOracle Linuxをクリーンインストール、http://dba-ha.blogspot.jp/2014/12/softlayeroracle-linux-2softlayer-advent.html) の 「パーティショをフォーマットし、マウントし、先ほどバックアップした OS イメージを展開します。」 の部分の手順を差し替える形で説明します。説明を簡略化するためです。Rescue モードで起動するところからの部分を適当に読み替えれば、既存のルート・パーティションを暗号化することもできると思います。ただし、気を付けなければならないのは、暗号化することで利用可能なパーティションサイズが暗号化のオーバーヘッド分、微々たる量ですが、少なくなってしまうことです。ファイルシステムごと dd コマンドでビットコピーしようと考えている場合は、この点をクリアする必要があります。今回は tar コマンドでファイルコピーしますので、問題はありません。

ルートパーティションを暗号化する場合、OS 起動時にコンソールからパスフレーズを入力する必要があります。SoftLayer におけるコンソールの使い方は説明しませんので、最初に利用できることを確認しておいてください。

では、パーティションを作成し終わった続きから説明します。


暗号化対象のパーティションに対し、ランダムな書き込みを行います。サイズにより、かなりの時間が必要となります。1GB あたり2分くらいはみておいた方がよいです。この手順を省略した場合、暗号の強度が低くなると考える必要があります。


dd if=/dev/urandom of=/dev/${DEV_A}2 bs=1M
dd if=/dev/urandom of=/dev/${DEV_B}1 bs=1M
dd if=/dev/urandom of=/dev/${DEV_C}1 bs=1M


パーティションを暗号化します。
暗号化方式は、anaconda インストーラが採用している方式にしました。cryptsetup コマンドのデフォルトのモード、cbc はやめた方がよいようです。
可搬性のある luks 形式とします。
データを上書きしてよいかどうか聞かれるので大文字で 「YES」 と入力してください。パスフレーズを2回入力する必要があります。パスフレーズとは、半角空白を含めてよい、パスワードよりも長いもの、という意味です。これは全部同じでよいです。推測されにくい長いものを選んでください。最強を目指すのであれば、512bit (64byte) 鍵なので、90文字程度のパスフレーズ (dd if=/dev/urandom bs=1 count=64 2> /dev/null | base64) にすればよいのだと思います。パスフレーズを忘れると回復手段がないので注意してください。パスフレーズが漏えいすると暗号化している意味がなくなってしまうので厳重に管理する必要があります。UUID は、暗号強度とは何も関係ないので、このままでもよいし、置き換えてもよいです。


cryptsetup luksFormat -c aes-xts-plain64 -s 512 --uuid=0e144deb-0180-42a1-a2ad-6404d83d9eda /dev/${DEV_A}2

WARNING!
========
This will overwrite data on /dev/sda2 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: ******** ******** ******** ********
Verify passphrase: ******** ******** ******** ********

cryptsetup luksFormat -c aes-xts-plain64 -s 512 --uuid=1a528f04-c266-4b17-b3f7-a32b01670818 /dev/${DEV_B}1

WARNING!
========
This will overwrite data on /dev/sdb1 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: ******** ******** ******** ********
Verify passphrase: ******** ******** ******** ********

cryptsetup luksFormat -c aes-xts-plain64 -s 512 --uuid=2bc0a50d-4030-4d0b-a904-f2a6d93eead5 /dev/${DEV_C}1

WARNING!
========
This will overwrite data on /dev/sdc1 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: ******** ******** ******** ********
Verify passphrase: ******** ******** ******** ********


暗号化したパーティションをオープンします。パスフレーズを入力する必要があります。


cryptsetup luksOpen /dev/${DEV_A}2 luks-0e144deb-0180-42a1-a2ad-6404d83d9eda
Enter passphrase for /dev/sda2: ******** ******** ******** ********

cryptsetup luksOpen /dev/${DEV_B}1 luks-1a528f04-c266-4b17-b3f7-a32b01670818
Enter passphrase for /dev/sdb1: ******** ******** ******** ********

cryptsetup luksOpen /dev/${DEV_C}1 luks-2bc0a50d-4030-4d0b-a904-f2a6d93eead5
Enter passphrase for /dev/sdc1: ******** ******** ******** ********


暗号化されていない最初のパーティションに /boot 領域のためのファイルシステムを作成します。


mkfs.ext4 -L /boot -U 7e70ca17-3016-4b92-8542-615d909115f9 /dev/${DEV_A}1
tune2fs -c 0 -i 0 /dev/${DEV_A}1


暗号化されたパーティション上にファイルシステムを作成します。swap 領域も作成します。
データ領域は、とりあえず何も作成しません。LVM の物理ボリュームにしてもよいし、ソフトウェア RAID 用のパーティションとしてもよいし、ファイルシステムを作成してもよいです。


mkfs.ext4 -L / -U 4bf120f5-6da0-4cb8-9540-bec49fff57a1 /dev/mapper/luks-0e144deb-0180-42a1-a2ad-6404d83d9eda
tune2fs -c 0 -i 0 /dev/mapper/luks-0e144deb-0180-42a1-a2ad-6404d83d9eda
mkswap -L SWAP -U 299ff4da-8897-405b-ae8e-5648a14fc81e /dev/mapper/luks-1a528f04-c266-4b17-b3f7-a32b01670818


OS イメージを展開できるように、マウントします。


mount /dev/mapper/luks-0e144deb-0180-42a1-a2ad-6404d83d9eda /mnt/sysimage
mkdir /mnt/sysimage/boot
chmod 555 /mnt/sysimage/boot
mount /dev/${DEV_A}1 /mnt/sysimage/boot


OS イメージを展開します。


cd /mnt/sysimage
tar xzvf /tmp/os.tgz


OS 起動時にパスフレーズを入力するだけで暗号化した領域を自動的にマウントできるようにします。


cat << 'EOF' | tee /mnt/sysimage/etc/crypttab
luks-0e144deb-0180-42a1-a2ad-6404d83d9eda UUID=0e144deb-0180-42a1-a2ad-6404d83d9eda
luks-1a528f04-c266-4b17-b3f7-a32b01670818 UUID=1a528f04-c266-4b17-b3f7-a32b01670818
luks-2bc0a50d-4030-4d0b-a904-f2a6d93eead5 UUID=2bc0a50d-4030-4d0b-a904-f2a6d93eead5
EOF
sed -i -e 's/ rd_NO_LUKS//' /mnt/sysimage/boot/grub/grub.conf
sed -i -e 's; root=UUID=[^ ]* ; root=/dev/mapper/luks-0e144deb-0180-42a1-a2ad-6404d83d9eda ;' /mnt/sysimage/boot/grub/grub.conf
cat << 'EOF' | tee /mnt/sysimage/etc/fstab
/dev/mapper/luks-0e144deb-0180-42a1-a2ad-6404d83d9eda / ext4 defaults   1 1
UUID=7e70ca17-3016-4b92-8542-615d909115f9 /boot ext4    defaults        1 2
/dev/mapper/luks-1a528f04-c266-4b17-b3f7-a32b01670818 swap swap pri=1,defaults 0 0
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
EOF


ここからの作業は、前回の説明に戻り、grub をインストールします。
その後の初期 RAM ディスクの再作成は必須です。mkinitrd コマンドが呼び出す dracut コマンドが /etc/crypttab を初期 RAM ディスクの中に埋め込みます。


その後の再起動に際し、reboot コマンド直前に以下のコマンドで暗号化パーティションをクローズしておくのがよいお作法ですが、実行しなくても害はありません。


cryptsetup luksClose luks-0e144deb-0180-42a1-a2ad-6404d83d9eda
cryptsetup luksClose luks-1a528f04-c266-4b17-b3f7-a32b01670818
cryptsetup luksClose luks-2bc0a50d-4030-4d0b-a904-f2a6d93eead5


再起動後は、パスフレーズを入力する必要があります。OS を起動するたびに入力する必要があります。sshd は動いていない状態なのでコンソールを利用する必要があります。
起動シーケンスの中で以下のような問い合わせがあります。


dracut: luksOpen /dev/sda2 luks-0e144deb-0180-42a1-a2ad-6404d83d9eda

Password (/dev/sda2): ******** ******** ******** ********


※ コンソール画面上にログも表示されるので、見分けられない可能性があります。パスフレーズの入力を始めると再表示されます。

2 件のコメント:

  1. luks暗号化をやめる際にはどのようなコマンドを叩けばいいでしょうか?

    返信削除
  2. OS 無停止で、何かのコマンドを実行すれば暗号化が解除されるですとか、
    OS 再起動後に暗号化が解除されるですとか、
    といったお気軽な方法は存在しないと思います。

    本投稿では、OS イメージを用意して、暗号化したパーティションを用意して、そこにリストアする、
    という手順となっています。
    OS イメージをバックアップして、暗号化していないパーティションを用意して、そこにリストアする、
    という手順を実行すれば、暗号化を解除する手順となります。

    以下の手順は、実際には試していない点をご了承ください。

    SoftLayerにOracle Linuxをクリーンインストール (2枚目SoftLayer Advent Calendar 2014第11日目)
    http://dba-ha.blogspot.jp/2014/12/softlayeroracle-linux-2softlayer-advent.html
    を参照し、
    「Rescue モードで起動するための準備をします。」のところから作業を始めます。

    「先ほど作成した OS イメージをバックアップします。」
    の手順が変わります。ここで、動いていた OS イメージをバックアップします。
    「cd /mnt/sysimage/srv」が「cd /mnt/sysimage」となります。

    「chroot して grub をインストールします。」の前で、
    /mnt/sysimage/etc/crypttab を削除し、
    /mnt/sysimage/etc/fstab を適宜書き直します。
    /mnt/sysimage/boot/grub/grub.conf も適宜書き直します。

    「chroot して grub をインストールします。」以下を実行します。

    返信削除