dm-crypt/スワップの暗号化

提供: ArchWiki
2020年12月22日 (火) 20:33時点におけるKgx (トーク | 投稿記録)による版 (→‎スワップパーティションの使用: 翻訳を修正)
ナビゲーションに移動 検索に移動

必要に応じて、以下で説明する様々な方法を使ってスワップパーティションを暗号化することができます。再起動時にスワップパーティションを (新しい暗号を使って) 初期化することで、過去にスワップアウトされた重要なファイルの断片がそのまま残ってしまうのを防ぐことができ、強固なデータの保護が可能になります。ただし、スワップを暗号化すると基本的にハイバネートが使えなくなってしまいます。

suspend-to-disk を使用しない

suspend-to-disk (ハイバネーション) が必要ない場合、/etc/crypttab を設定することで plain dm-crypt を使って起動時にランダムなパスワードでスワップパーティションを復号化することができます。ランダムなパスワードはシャットダウン時に破棄されるため、スワップデバイス内のデータには二度とアクセスできなくなります。

/etc/crypttabswap から始まる行をアンコメントするだけで機能を有効にできます。<device> パラメータはあなたの使用しているスワップデバイスの名前に変更してください。例:

/etc/crypttab
# <name>  <device>     <password>     <options>
swap      /dev/sdX#    /dev/urandom   swap,cipher=aes-cbc-essiv:sha256,size=256

上記の設定で /dev/sdX#/dev/mapper/swap にスワップパーティションとしてマッピングされ、通常のスワップと同じように /etc/fstab に追加できるようになります。既にスワップパーティションを使っていた場合、無効化するか fstab エントリを再利用してデバイスを /dev/mapper/swap に変更してください。大抵の場合はデフォルトのオプションで問題ありません。他のオプションやカラムの説明については man 5 crypttab および point cryptsetup FAQ 2.3 を見てください。

警告: 名前付きデバイスの中身は永久に削除されます。スワップデバイスに対してカーネルのシンプルな命名を使うのは危険です。名前の順番が起動時に変わってしまう可能性があるためです (例: /dev/sda, /dev/sdb)。以下の方法があります:
  • by-idby-path を使用する。ただし、どちらもハードウェアを変更すると変わる可能性があります。永続的なブロックデバイスの命名#by-id と by-path を参照。
  • LVM の論理ボリュームの名前を使用する。
  • #UUID と LABEL に書かれている方法を使う。ラベルや UUIDmkswap によって起動時にスワップデバイスを再作成・暗号化するため直接使われることはありません [1]

カーネルの命名の代わりに by-id による命名を使う場合、まずスワップデバイスを確認してください:

# ls -l /dev/disk/*/* | grep sdaX
lrwxrwxrwx 1 root root 10 Oct 12 16:54 /dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-partX -> ../../sdaX
lrwxrwxrwx 1 root root 10 Oct 12 16:54 /dev/disk/by-id/wwn-0x60015ee0000b237f-partX -> ../../sdaX

そして出力された行の中から適切なデバイスを選択して以下のように設定してください:

/etc/crypttab
# <name>  <device>                                                         <password>     <options>
swap      /dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-partX  /dev/urandom   swap,cipher=aes-cbc-essiv:sha256,size=256

再起動後 swapon -s を実行することで任意のデバイスマッパーエントリ (例: /dev/dm-1) が表示され、lsblk コマンドで FSTYPE カラムの crypt が表示されます。起動時に新しく暗号化するため、/dev/mapper/swap の UUID は毎回変わります。

ノート:
  • スワップに選択したパーティションが LUKS パーティションだった場合、crypttab はスワップパーティションを作成するのにパーティションを上書きしません。crypttab で間違ってスワップパーティションを指定したときにデータが消失しないようにするための安全機構です。そのようなパーティションを使うときは LUKS ヘッダーを上書きしてください。
  • ルートファイルシステムで sd-encrypt フックと luks.* カーネルパラメータを使用する場合、systemd は "Not creating device 'swap' because it was not specified on the kernel command line." とエラーを吐きます。問題を解決するには rd.luks.* パラメータを使ってください。

UUID と LABEL

ノート: 以下の方法は systemd と sd-encrypt init フックを使用している場合は機能しません。

/dev/sdX# あるいは /dev/disk/by-id/ata-SERIAL-partX などのシンプルなカーネルデバイス名で crypttab のスワップを使うのは危険です。デバイス名やパーティションレイアウトに少しでも変更があると /etc/crypttab は次回の起動時に重要なデータをフォーマットしてしまいます。PARTUUID を使用した場合も同じです。

正規の UUID またはLABELを指定することにより、正しいパーティションを識別する方が信頼性が高くなります。 デフォルトでは、 dm-crypt と mkswap がそのパーティションのコンテンツを上書きするだけで、UUID と LABEL も削除されるため、これは機能しません。 ただし、スワップオフセットを指定することは可能です。 これにより、スワップ暗号化用の永続的な UUID またはLABELを提供する以外の目的なしに、非常に小さく、空の、偽のファイルシステムを作成できます。

選択したラベルでファイルシステムを作成します:

# mkfs.ext2 -L cryptswap /dev/sdX# 1M

デバイス名の後の異常なパラメータは、ファイルシステムのサイズを 1 MiBに制限し、暗号化されたスワップの余地を残します。

# blkid /dev/sdX#
/dev/sdX#: LABEL="cryptswap" UUID="b72c384e-bd3c-49aa-b7a7-a28ea81a2605" TYPE="ext2"

これにより、 /dev/sdX# は、デバイス名やパーティション番号が将来どのように変更されるかに関係なく、 UUID または LABEL のいずれかで簡単に識別できるようになりました。 残っているのは、 /etc/crypttab/etc/fstab のエントリだけです。

/etc/crypttab
# <name> <device>         <password>    <options>
swap     LABEL=cryptswap  /dev/urandom  swap,offset=2048,cipher=aes-xts-plain64,size=256

この設定を使用すると、 cryptswap は、デバイス名が何であるかに関係なく、対応する LABEL を持つパーティションのみを使用しようとします。 パーティションを他の目的で使用することにした場合、それをフォーマットすることにより、 cryptswap LABEL もなくなるため、 cryptswap は次回の起動時にパーティションを上書きしません。

suspend-to-disk を使用する

コンピュータをディスクにサスペンド (ハイバネート) して復帰できるようにするには、スワップ領域を残す必要があります。あらかじめ LUKS スワップパーティションを用意して、ディスクに保存するか起動時に手動で入力できるようにしなければなりません。

以下の3つの方法はハイバネートのためにスワップの暗号化を設定する方法です。以下の方法を使う場合、スワップアウトされたデータがしばらくスワップに残り続ける可能性があるため注意してください。システムをシャットダウンするときにスワップを再暗号化するシステムジョブを設定することでリスクを減らすことができます。

LVM on LUKS

スワップボリュームが initramfs でアクティブ化されるボリュームグループにある場合は、 ハイバネーションの指示に従ってください。

スワップパーティションの使用

暗号化されたスワップパーティションから再開するには、暗号化されたパーティションを initramfs でロック解除する必要があります。

  • encrypt フックでデフォルトの busybox ベースの initramfs を使用する場合は、 #mkinitcpioフック の指示に従ってください。
  • sd-encrypt mkinitcpio フックで systemd ベースの initramfs を使用する場合は、追加の rd.luks カーネルパラメーターを指定するだけでスワップパーティションのロックを解除できます。

mkinitcpio フック

ノート: このセクションは encrypt フックを使用する場合にのみ適用され、シングルデバイスしかアンロックできません (FS#23182)。sd-encrypt を使用することで複数のデバイスをアンロックできるようになりますが (Dm-crypt/システム設定#sd-encrypt フックを使うを参照)、スワップの自動認識は使えなくなります [2]

スワップデバイスがルートファイルシステムのデバイスとは異なるデバイス上にある場合、 encrypt フックによって開かれません。つまり、再開は /etc/crypttab の前に行われます。 を使用できるため、再開する前に、 /etc/mkinitcpio.conf にフックを作成して、スワップLUKSデバイスを開く必要があります。

現在使用中のパーティションを使いたい場合、先に無効化する必要があります:

# swapoff /dev/<device>

また、このデバイスを指す /etc/crypttab の行をすべて削除してください。

既存のスワップパーティションを再利用する場合、パーティションが GPT パーティションテーブルに載っているときはパーティションを削除してから再作成する必要があります。パーティショニングを見てください。削除することで systemd-gpt-auto-generator によって起動時にパーティションが有効にならないようにします。

次の設定には、起動のたびにスワップパーティションに追加のパスフレーズを手動で挿入する必要があるという欠点があります。

警告: /boot が暗号化されていない場合は、このセットアップをキーファイルで使用しないでください。 報告された問題についてお読みください [3] または、https://bbs.archlinux.org/viewtopic.php?id=201881

に従って gnupg で暗号化されたキーファイルを使用します。

スワップパーティションの暗号化されたコンテナをフォーマットするには、ユーザーが記憶できるパスフレーズのキースロットを作成します。

/dev/mapper にパーティションをオープン:

# cryptsetup open --type luks /dev/<device> swapDevice

マッピングされたパーティションにスワップファイルシステムを作成:

# mkswap /dev/mapper/swapDevice

起動時にスワップをオープンにするフックを作成する必要があります。mkinitcpio-openswapAURインストールして設定するか、以下の手順に従って下さい。open コマンドを記述したフックファイルを作成:

/etc/initcpio/hooks/openswap
 run_hook ()
 {
     cryptsetup open --type luks /dev/<device> swapDevice
 }

パスワードを入力してスワップデバイスを開くため、または:

/etc/initcpio/hooks/openswap
 run_hook ()
 {
     ## Optional: To avoid race conditions
     x=0;
     while [ ! -b /dev/mapper/<root-device> ] && [ $x -le 10 ]; do
        x=$((x+1))
        sleep .2
     done
     ## End of optional

     mkdir crypto_key_device
     mount /dev/mapper/<root-device> crypto_key_device
     cryptsetup open --type luks --key-file crypto_key_device/<path-to-the-key> /dev/<device> swapDevice
     umount crypto_key_device
 }

一部のコンピューターでは、復号化プロセスとデバイスの列挙が完了する前に mkinitcpio がデバイスをマウントしようとすると、競合状態が発生する場合があります。 コメント付きの オプション ブロックは、ルートデバイスをマウントする準備ができるまで、起動プロセスを最大2秒遅らせます。 (暗号化されたルートデバイスからキーファイルをロードしてスワップデバイスを開くため。)

ノート: スワップがソリッドステートドライブ (SSD) 上にあり Discard/TRIM を使用する場合、--allow-discards オプションを上記の openswap フックの cryptsetup 行に追加する必要があります。discard について詳しくは Dm-crypt/特記事項#ソリッドステートドライブ (SSD) の Discard/TRIM のサポートSSD の記事を見てください。さらに 'discard' オプションをスワップデバイスの fstab エントリに追加してください。

次に、フック設定ファイルを作成して編集します:

/etc/initcpio/install/openswap
build ()
{
   add_runscript
}
help ()
{
cat<<HELPEOF
  This opens the swap encrypted partition /dev/<device> in /dev/mapper/swapDevice
HELPEOF
}

フック openswap/etc/mkinitcpio.confHOOKS 配列の filesystem の前で encrypt} の後に追加します openswap の後に resume フックを追加することを忘れないでください。

HOOKS=(... encrypt openswap resume filesystems ...)

イメージ作成とアクティベーション

次の行を追加して、マップされたパーティションを / etc / fstabに追加します。

/dev/mapper/swapDevice swap swap defaults 0 0

/dev/mapper/swapDevice から再開するようにシステムを設定します。たとえば、カーネル休止状態をサポートする GRUB を使用する場合は、カーネルパラメータ resume=/dev/mapper/swapDeviceGRUB_CMDLINE_LINUX_DEFAULT に追加して、 GRUB に追加します。 /etc/default/grub の変数。暗号化されたルートパーティションとスワップパーティションを持つカーネルラインは、次のようになります。

kernel /vmlinuz-linux cryptdevice=/dev/sda2:rootDevice root=/dev/mapper/rootDevice resume=/dev/mapper/swapDevice ro

起動時に、 openswap フックがスワップパーティションを開くので、カーネルレジュームがそれを使用できます。休止状態から再開するために特別なフックを使用する場合は、それらが HOOKS 配列の openswap に配置されていることを確認してください。 initrd が swap を開くため、この場合、 /etc/crypttab に swapDevice のエントリが必要ないことに注意してください。

スワップファイルを使う

スワップファイルは、既存のパーティション内のスワップスペースを予約するために使用でき、暗号化されたブロックデバイスのパーティション内にセットアップすることもできます。

スワップファイル のスワップファイル作成手順に従い、 スワップファイルにハイバネーション に従って休止状態を設定します。

ノート: スワップファイルから再開する場合、 resume パラメータは、スワップファイルを含むファイルシステムを含むロック解除/マップされたデバイスを指している必要があります。

既知の問題

  • ログに "Stopped (with error) /dev/dm-1" と出力される場合 [4] を見てください。