Debian GNU/LinuxやUbuntuなど最近のLinuxディストリビューションではインストール時にディスクの内容を暗号化する設定をすることができます。インストーラのメニューで選択するだけなので、簡単に設定できます。
しかし、groongaの開発に参加していて、頻繁な単体テストの実行でデータベースを作成・削除を繰り返すなどキャッシュが効かないディスクI/Oが多い使い方をする場合は、暗号化による速度劣化を体感してしまいます。Linux上で開発をしている場合はよくあることですよね。
この場合、「一部だけ暗号化しない」または「一部だけ暗号化する」というように記憶領域を使い分ければ、安全性を高めながら開発効率を落とさずにすみます。しかし、インストール後に使い分けたくなった場合、追加のディスクがないと「一部だけ暗号化しない」使い方をすることはできません1。
そこで、ここではディスクを追加しないで「一部だけ暗号化する」簡単な方法を紹介します。インターネット上には日本語の情報があまり見つからない2のですが、これは需要がないからという気もします。が、気にせずに続けます。
概要
loopデバイスを使うとディスク上のファイルをディスクのように扱えます。これを利用して、暗号化していないディスク上にイメージファイルを作成し、それをloopデバイスで追加のディスクのように扱えるようにして、そこに暗号化ファイルシステムを作成します。暗号化したいファイルはイメージファイル内に保存し、暗号化しなくてもよいファイルはいつも通りの場所に保存します。
これで追加のディスクなしに「一部だけ暗号化する」ことができます。簡単ですね。
初期設定
まず、cryptsetupをインストールします。
% sudo aptitude -V -r -D install -y cryptsetup
暗号化したいファイルを保存する領域として利用するイメージファイルを作成します。保存したいデータサイズを考えて作成してください。以下は20GBのイメージファイルを~/encrypted.imgに作成する例です。countの値でサイズを調整してください。
% dd if=/dev/zero of=$HOME/encrypted.img bs=1M count=20480
イメージファイルができたらloopデバイスに関連付けます。
% sudo /sbin/losetup /dev/loop0 ~/encrypted.img
これでデバイスファイルのように扱うことができるようになったので、イメージファイルを暗号化のために初期化します。初期化をすると内部のデータが壊れるので、確認のためのプロンプトがでます。今回は新しく作成したイメージで中には大事なものは何もないので大文字で「YES」と入力してください。
% sudo /sbin/cryptsetup luksFormat /dev/loop0
WARNING!
========
This will overwrite data on /dev/loop0 irrevocably.
Are you sure? (Type uppercase yes): (YESと入力)
Enter LUKS passphrase: (パスフレーズを入力)
Verify passphrase: (確認のため同じパスフレーズをもう一度入力)
暗号化のための初期化が完了したら暗号化して読み書きできるデバイスファイルを作成します。
% sudo /sbin/cryptsetup luksOpen /dev/loop0 encrypted
Enter passphrase for /dev/loop0: (初期化時に設定したパスフレーズを入力)
これで、/dev/mapper/encryptedというデバイスファイルができます。このデバイスファイル経由で読み書きすれば暗号化されるので、今後はこのデバイスファイルに対して操作します。
まず、デバイスファイルをフォーマットします。
% sudo /sbin/mkfs -t ext4 /dev/mapper/encrypted
mountし、読み書きできることを確認します。
% sudo mount -t ext4 /dev/mapper/encrypted /mnt
% ls /mnt
lost+found
% echo test | sudo tee /mnt/file
% cat /mnt/file
test
これで初期設定は完了です。後始末をしましょう。
% sudo umount /mnt
% sudo cryptsetup luksClose encrypted
% sudo losetup -d /dev/loop0
umountして暗号化デバイスを閉じてloopデバイスの関連付けを削除しています。
運用
実際に使うときは必要になったときに、以下の手順を行います。
-
loopデバイスをイメージファイルに関連付ける
-
loopデバイスに暗号化して読み書きするデバイスを作る
-
暗号化して読み書きするデバイスをmountする
用が済んだら逆順に後片付けをします。
しかし、これでは面倒なので、シェルスクリプトを作ります。
mount-encrypted.sh:
#!/bin/sh
sudo mkdir -p /mnt/encrypted
sudo /sbin/losetup /dev/loop0 ~/encrypted.img
sudo /sbin/cryptsetup luksOpen /dev/loop0 encrypted
sudo mount -t ext4 /dev/mapper/encrypted /mnt/encrypted
umount-encrypted.sh:
#!/bin/sh
sudo umount /mnt/encrypted
sudo /sbin/cryptsetup luksClose encrypted
sudo /sbin/losetup -d /dev/loop0
以下のように使います。
% mount-encrypted.sh
Enter passphrase for /dev/loop0: (パスフレーズを入力)
% (/mnt/encrypted以下を使う)
% umount-encrypted.sh
実際は以下のように/mnt/encrypted/以下に1つディレクトリを作り、そこを一般ユーザ権限で読み書きできるようにし、そこに対して一般ユーザで読み書きするようにすると便利でしょう。
% sudo mkdir -p /mnt/encrypted/$USER
% sudo chown -R $USER:$(id -g -n) /mnt/encrypted/$USER
% echo test > /mnt/encrypted/$USER/file
% cat /mnt/encrypted/$USER/file
test
さらに、メールボックスなど暗号化したいファイルは暗号化イメージにmvして、ホームディレクトリからはシンボリックを張ると暗号化以前と同じように使えます。
% mv ~/Mail/ /mnt/encrypted/user/
% ln -fs /mnt/encrypted/user/Mail/ ./
まとめ
Debian GNU/Linuxで、通常の暗号化されていないディスク上に追加のディスクなしで暗号化した領域を作成する方法を紹介しました。データを暗号化した領域に置いておくとディスクを盗まれたときなどに簡単にデータを読み出すことができなくなり、万が一のときの安全性が高まります。
しかし、ログインして利用しているときは同じマシンにログインしているユーザからは見えてしまう可能性があります3。暗号化しただけで安心しないで、大事なデータは適切に扱うようにする必要があります。