dm-cryptと2.6シリーズ・カーネルでパーティションを暗号化

今年2月、Andrew Mortenは、cryptoloopはdm-cryptによって置き換えられることになると発表した。この発表が行われた当時には多少の混乱もあったが、dm-cryptはいまや2.6.4カーネルの安定ツリーの一員となっている。本稿では、dm-cryptを使用した暗号化パーティションのセットアップ方法について見ていきたい。

dm-cryptは、Device-mapperに暗号化レイヤを提供する。Device-mapperドライバを使うことで、既存のブロック・デバイス上のセクタの範囲を指定して新しいパーティションまたは論理ボリュームを定義することができる。これらのパーティションで使用されるセクタの範囲は、マッピング・テーブルに従ってターゲットにマップされる。dm-cryptは、新しい2.6カーネルのcryptoAPIを使ってブロック・デバイスを透過的に暗号化するために使用するこのようなターゲットを提供する。

かつて暗号化の実現に使われていたcryptoloopでは、ループバック・デバイスを利用していた。dm-cryptは実装がよりクリーンであり、柔軟性が向上している。cryptoloopのメンテナFruhwirth Clemensは次のように述べている。

dm-cryptは、多くの面でcryptoloopよりも優れている。
  • loop.cのバグの影響を受けない(大量にあるうえ、管理者もいない)
  • dm-cryptは特定のユーザ空間ツール(util-linux)に依存しない
  • dm-cryptはmempoolを利用することで、cryptoloopよりも堅牢である

cryptoloopは強力な暗号アルゴリズムを使っているものの、弱い実装であり、特定の種類の平文攻撃に対して脆弱であるとされてきた。cryptoloopの脆弱性についての議論は、LWN.netを参照してほしい。dm-cryptは同じ強力な暗号アルゴリズムを使用し、実装は大きく改善されている。

dm-cryptのインストール

dm-cryptで重要なデータを暗号化する際には、最新のバックアップがあることを確認すること。まず、必要なファイルをダウンロードする。www.kernel.orgから最新のLinuxカーネルを入手する必要がある。2.6.4以降のバージョンであれば問題ないはずだが、2.6.5以降を使うことを勧める。2.6.4では一部のシステムに問題が残っているためだ。さらに、Device-mapper、hashalot(オプション)、そしてセットアップ・スクリプトのcryptsetup.shをダウンロードする。

通常通りにカーネルを設定し、Device-mapperサポートとdm-cryptサポートを追加する。これらは、[Multi-device support (RAID and LVM)]以下で[Device Mapper Support]および[Crypt Target Support]として表示される。また、[Cryptographic Options]で暗号化に使用する暗号を有効にする。

新しいカーネルをインストールして起動したら、Device-mapperをモジュールとして設定してある場合、modprobe dm-modを使用してこれをロードする必要がある。dm-cryptモジュールは、必要に応じてカーネルが自動的にロードする。起動スクリプトにこのmodprobeコマンドと、使用するその他の暗号化モジュールに対するmodprobeを入力する。

Device-mapperは/dev/mapperディレクトリと/dev/mapper/controlデバイスを使用する。これらを作成するには、Device-mapperパッケージからscripts/devmap_mknod.shスクリプトを実行する。成功すれば、このスクリプトは新しいノードのデバイス番号(メジャーとマイナー)を出力する。失敗した場合には、何も出力せずに終了する。

続いて、Device-mapperパッケージをコンパイルしてインストールする。ファイルをアンパックして、おなじみの./configuremakemake installコマンドを実行して必要なライブラリとdmsetupユーティリティを/sbinにインストールする。デバイスの作成と削除、デバイス情報の取得、テーブルの再読み込みにはdmsetupを使用する。

dmsetup create "name"を実行すると、/dev/mapper/control"name"というデバイスが作成される。次にdmsetupはstdinからのマッピング・テーブルを待つ。または、3つ目のパラメータとして、この情報を含むファイルを指定してもよい。マッピング・テーブルの形式は次のとおり。
"start sector" "sector count" "target type" "arguments"
dm-cryptテーブルの形式は次のとおり。
0 "sector count" crypt "sector format" "key" "IV offset" "real device" "sector offset"

"sector format""key"は、デバイスの暗号化に使われる暗号(aesなど)と、16進数で表された鍵である。/proc/cryptoをチェックするか、該当するカーネル・モジュールをmodprobe付きでロードすれば、利用可能な暗号を確認できる。"IV offset"は、特別な場合を除き0に設定されている。<real device>は暗号化する実際のデバイスであり、/dev/xxxxという形式で指定するか、major:minorのようにデバイス番号で指定する。"sector offset"は、実際のデバイスにおける暗号化されたデータの開始地点を示すセクタ・オフセットである。

これらの作業が煩雑に思えたとしても、心配はいらない。cryptsetup.shスクリプトを使えば、このプロセスをずっとユーザ・フレンドリにすることができる。このスクリプトではhexdumpとhashalotを使って暗号化鍵を生成する。-h plainオプションを指定すればhashalotがなくてもよい。cryptsetup.shスクリプトを使う場合は、これを$PATH(必ず実行可能にしておくこと)内の場所にコピーし、hashalotをインストール(./configuremakemake install)する。

Cryptsetup.shは、暗号化されたデバイスをセットアップするためのオプションと共にdmsetupを呼び出す。次の例は、/dev/hdb2を変換して/dev/mapper/cryptvol1を使うようにするものだ。

まず、デバイスをアンマウントしてfsckを実行し、ファイルシステムにエラーがないことを確認する。

umount /dev/hdb2
fsck /dev/hdb2

dm-cryptデバイスを作成する。

cryptsetup.sh -c aes -h ripemd160 -y -b `blockdev --getsize /dev/hdb2` create cryptvol1 /dev/hdb2

パスフレーズを要求されるので、プロンプトに入力する。これで、AES暗号を使って/dev/hdb2からデバイス/dev/mapper/cryptvol1が作成され、hashalotを使ってパスフレーズから鍵が生成される(hashalotを使用しない場合はここで-h plainオプションを指定すること)。cryptsetupのオプションの一覧は、cryptsetup.sh --helpを実行すれば表示される。

これで、新しいデバイスにデータをコピーする準備が整った。

dd if=/dev/hdb2 of=/dev/mapper/cryptvol1 bs=4k

実行する前に、このコマンドをよく確認してほしい。指定したデバイス上のすべてのデータを上書きしてしまうからだ。このコマンドが完了したら、fsck /dev/mapper/cryptvol1を実行して新しいデバイス上にエラーがないかどうか確認する。何も問題がなければ、/dev/hdb2の代わりに新しいデバイスをマウントできる、mount /dev/mapper/cryptvol1 /data(このパーティションをマウントするのにmount /dev/hdb2 /dataを使っていた場合)。

必要であれば、このプロセスを逆に実行して、暗号化デバイスから通常のデバイスにデータをコピーすることで、暗号化デバイスを暗号化解除することもできる。同様に、データの再暗号化や、パスフレーズの変更などの必要が生まれた場合にも、2つのマップされたデバイス間でデータをコピーすればよい。この作業を簡単に行うためのユーティリティは、現在開発中だ。

デバイスが不要になったら、dmsetup remove "name"を実行すれば削除できる。

cryptsetupはデバイスのマッピングを作成するので、再起動後にファイルシステムを再度マウントするには、同じパスワードでcryptsetup.shをもう一度呼び出すだけでよい。たとえば、起動スクリプトに次のコードを含めた場合、起動時にパスフレーズを要求され、デバイスが再作成される。

if [ -b /dev/mapper/cryptvol1 ] ; then
          /usr/local/sbin/cryptsetup.sh remove cryptvol1
fi

/usr/local/sbin/cryptsetup.sh -c aes -h ripemd160  -b `blockdev --getsize /dev/hdb2` create cryptvol1 /dev/hdb2

/sbin/mount /dev/mapper/cryptvol1 /data

まとめ

dm-cryptはクリーンで堅固な実装である。さらに、Device-mapperを利用することでcryptoloopよりも柔軟性が高い。現在のところ、dm-cryptは機能面ではcryptoloopと同じだが、拡張可能なことから、今後より充実した機能が実現される見込みだ。cryptoloopが近い将来、カーネルから完全に姿を消すとは考えにくいが、暗号化ファイルシステムの配備を検討しているのであれば、dm-cryptを選択肢に加えてほしい。

Mike Peters――フリーランスのコンサルタント/プログラマ。長年にわたるLinuxユーザである。