LUKS2 の key slot を整理するときは、不要な slot を先に削除してはいけません。対象デバイスを固定し、新しい解除手段を追加して実際に検証し、LUKS ヘッダーをバックアップしてから、用途を確定できた slot だけを 1 つずつ削除します。削除後に通常運用用 keyfile と非常用パスフレーズの両方で解除試験が成功して、作業完了です。1
この記事では、既存の LUKS2 デバイスに次の状態を作ります。
- 通常運用用 keyfile で解除できる
- 非常用パスフレーズでも解除できる
- それぞれに対応する key slot 番号を記録できる
- 用途を確認できた不要な key slot だけが削除されている
- 変更前と削除直前の LUKS ヘッダーが別媒体に保存されている
前提環境
対象は、Linux 上のデータ用 LUKS2 デバイスです。起動用ルートデバイス、swap、detached header、TPM2、FIDO2、PKCS#11、LUKS2 token を使う構成は扱いません。
必要な条件は次のとおりです。
| 項目 | 条件 |
|---|---|
| 暗号化形式 | LUKS2 |
| 対象 | OS の起動経路に含まれないデータ用デバイス |
| 既存の解除手段 | 現在も使えるパスフレーズまたは keyfile が 1 つ以上ある |
| 通常運用用 keyfile | /etc/cryptsetup-keys/crypt_name.key |
| keyfile の長さ | 32 byte |
| keyfile の所有者と権限 |
root:root、0400
|
| ヘッダーバックアップ | 対象デバイスとは別の保護された媒体に保存する |
開始時点の有効な key slot が 1 つだけでも、新しい解除手段の追加は可能です。ただし、不要な slot の削除へ進む前に、通常運用用 keyfile と非常用パスフレーズの 2 系統を追加し、両方が機能することを確認します。
cryptsetup の機能を確認する
最初に、インストールされている cryptsetup のバージョンと open の対応オプションを確認します。
cryptsetup --version
cryptsetup open --help | grep -E -- '--test-passphrase|--key-slot'
--test-passphrase と --key-slot の両方が表示されることを確認します。--test-passphrase は mapper デバイスを作成せずに解除情報だけを検証し、--key-slot は照合対象を特定の slot に限定します。2
cryptsetup 2.7.0 では、LUKS2 token と --key-slot、--test-passphrase の組み合わせに関する修正が入っています。3 バージョン番号だけで挙動を推測せず、実行環境の --help と luksDump を確認します。この記事では token が存在する環境を対象外にします。
対象デバイスを固定する
/dev/sdX は接続順によって変化するため、そのまま作業対象にしません。lsblk と blkid で媒体を確認し、LUKS UUID に対応する永続的なパスを使います。
lsblk -o NAME,PATH,SIZE,MODEL,SERIAL,FSTYPE,TYPE,MOUNTPOINTS,UUID
sudo blkid
対象を確定したら、以降のコマンドで使う変数を設定します。次の UUID は説明用なので、実際の LUKS UUID に置き換えます。
DEVICE=/dev/disk/by-uuid/11111111-2222-3333-4444-555555555555
KEYFILE=/etc/cryptsetup-keys/crypt_name.key
HEADER_BACKUP_DIR=/media/offline/luks-header
WORKDIR=$(mktemp -d)
chmod 700 "$WORKDIR"
変数が意図した対象を指していることを確認します。
readlink -f "$DEVICE"
lsblk -o NAME,PATH,SIZE,MODEL,SERIAL,FSTYPE,TYPE,MOUNTPOINTS,UUID "$(readlink -f "$DEVICE")"
sudo blkid "$DEVICE"
sudo cryptsetup isLuks "$DEVICE" && printf '%s\n' 'LUKS device confirmed'
blkid の TYPE が crypto_LUKS であり、容量、モデル、シリアル番号が対象媒体と一致していることを確認します。一致しない場合は、以降の操作を実行しません。
現在の LUKS2 ヘッダーと key slot を確認する
luksDump は、LUKS ヘッダー、UUID、key slot、token などの情報を表示します。4
sudo cryptsetup luksDump "$DEVICE" | tee "$WORKDIR/luks-dump-before.txt"
次の項目を確認します。
| 確認項目 | 作業を続ける条件 |
|---|---|
| Version | 2 |
| UUID | 想定した LUKS UUID と一致する |
| Keyslots | 現在有効な slot 番号を列挙できる |
| Tokens | 登録されていない |
| Segments | 想定しているデータ用 LUKS2 構成である |
LUKS2 の key slot は、同じ暗号化データへ到達するための解除入口です。luksDump では slot 番号や鍵導出関数などを確認できますが、「通常運用用」「非常用」といった運用上の用途名は保存されません。用途は別途記録します。
この時点では、既存 slot を次の 3 種類に分類します。
- 解除手段と用途を確認済み
- 調査中
- 用途不明
用途不明の slot は削除候補にしません。
作業前の解除手段を試験する
現在使っているパスフレーズまたは keyfile が有効であることを、変更前に確認します。既存の解除手段が使えない状態では、新しい key slot を追加できません。
既存の解除手段がパスフレーズの場合は、次を実行して対話入力します。
sudo cryptsetup open --test-passphrase "$DEVICE"
printf 'exit status: %s\n' "$?"
既存の解除手段が keyfile の場合は、実際のパスを指定します。
sudo cryptsetup open --test-passphrase --key-file /path/to/existing.key "$DEVICE"
printf 'exit status: %s\n' "$?"
終了状態が 0 であることを確認します。失敗した場合は、対象デバイス、解除情報、keyfile のパスを再確認し、key slot の変更を中止します。
変更前の LUKS ヘッダーをバックアップする
LUKS ヘッダーのバックアップには、ヘッダーだけでなく key slot 領域も含まれます。バックアップ時点で有効だった解除情報と組み合わせると、後で削除した slot を含む過去の状態からデータ領域を復号できるため、単なる設定ファイルではなく復旧資材として管理します。5
保存先が対象 LUKS デバイスと同じ物理媒体ではないことを確認します。
findmnt -T "$HEADER_BACKUP_DIR"
lsblk -o NAME,PATH,SIZE,MODEL,SERIAL,MOUNTPOINTS
LUKS UUID と日時をファイル名に含めて、変更前のバックアップを取得します。
LUKS_UUID=$(sudo cryptsetup luksUUID "$DEVICE")
STAMP=$(date +%Y%m%d-%H%M%S)
HEADER_BEFORE_CHANGE="$HEADER_BACKUP_DIR/luks-${LUKS_UUID}-before-change-${STAMP}.img"
sudo cryptsetup luksHeaderBackup \
--header-backup-file "$HEADER_BEFORE_CHANGE" \
"$DEVICE"
sudo chown root:root "$HEADER_BEFORE_CHANGE"
sudo chmod 0400 "$HEADER_BEFORE_CHANGE"
sudo test -s "$HEADER_BEFORE_CHANGE"
sudo sha256sum "$HEADER_BEFORE_CHANGE"
ファイルが空でないこと、所有者が root:root、権限が 0400 であることを確認し、SHA-256 値、LUKS UUID、対象媒体、取得日時、保存場所を記録します。
ヘッダーバックアップを対象 LUKS デバイス内だけに保存すると、そのデバイスを開けなくなったときにバックアップへ到達できません。別の保護された媒体へ保存します。
通常運用用 keyfile を作成する
この記事では、通常運用用 keyfile として 32 byte の乱数を使います。32 byte は cryptsetup の必須値ではなく、この記事で採用する運用値です。
保存先ディレクトリを作り、同名ファイルが存在しないことを確認します。
sudo install -d -o root -g root -m 0700 /etc/cryptsetup-keys
sudo test ! -e "$KEYFILE"
既存ファイルがある場合は、上書きせず、どの LUKS デバイスに対応する keyfile かを確認します。
新規作成する場合は、oflag=excl を付けて既存ファイルの上書きを防ぎます。
sudo dd \
if=/dev/urandom \
of="$KEYFILE" \
bs=32 \
count=1 \
status=none \
oflag=excl
sudo chown root:root "$KEYFILE"
sudo chmod 0400 "$KEYFILE"
サイズ、所有者、権限、識別用ハッシュを確認します。
sudo wc -c "$KEYFILE"
sudo stat -c 'owner=%U group=%G mode=%a size=%s path=%n' "$KEYFILE"
sudo sha256sum "$KEYFILE"
期待する結果は次のとおりです。
- サイズが
32 - 所有者とグループが
root root - 権限が
400 - SHA-256 値を台帳に記録できる
keyfile の内容そのものは、端末、ログ、台帳へ出力しません。
keyfile を新しい key slot に追加する
luksAddKey は、既存の有効な解除手段で volume key を取得し、新しいパスフレーズまたは keyfile で保護された key slot を追加します。6
作業前の luksDump を保存済みであることを確認してから、keyfile を追加します。
sudo cryptsetup luksAddKey "$DEVICE" "$KEYFILE"
既存の有効なパスフレーズを求められるので、現在使える解除情報を入力します。完了後に luksDump を保存し、追加前との差分を確認します。
sudo cryptsetup luksDump "$DEVICE" | tee "$WORKDIR/luks-dump-after-keyfile.txt"
diff -u \
"$WORKDIR/luks-dump-before.txt" \
"$WORKDIR/luks-dump-after-keyfile.txt"
新しく有効になった slot 番号を記録します。以下では、その番号を KEYFILE_SLOT と表記します。
追加した keyfile が、その slot で実際に使えることを確認します。KEYFILE_SLOT は、確認した数値へ置き換えます。
sudo cryptsetup open \
--test-passphrase \
--key-file "$KEYFILE" \
--key-slot KEYFILE_SLOT \
"$DEVICE"
printf 'exit status: %s\n' "$?"
終了状態が 0 にならない場合は、次の作業へ進みません。keyfile を追加したつもりでも、対象デバイスや slot の判断を誤っている可能性があります。
非常用パスフレーズを別の key slot に追加する
通常運用用 keyfile を既存の解除手段として使い、非常用パスフレーズを対話入力で追加します。
sudo cryptsetup luksAddKey \
--key-file "$KEYFILE" \
--verify-passphrase \
"$DEVICE"
新しい非常用パスフレーズを 2 回入力します。パスフレーズはコマンドライン引数、シェル変数、履歴ファイルへ書きません。
追加後の状態を保存し、直前との差分から新しい slot 番号を確認します。
sudo cryptsetup luksDump "$DEVICE" | tee "$WORKDIR/luks-dump-after-emergency.txt"
diff -u \
"$WORKDIR/luks-dump-after-keyfile.txt" \
"$WORKDIR/luks-dump-after-emergency.txt"
新しく有効になった番号を EMERGENCY_SLOT として記録します。その slot に対して非常用パスフレーズを試験します。
sudo cryptsetup open \
--test-passphrase \
--key-slot EMERGENCY_SLOT \
"$DEVICE"
printf 'exit status: %s\n' "$?"
終了状態が 0 であることを確認します。keyfile 用 slot と非常用パスフレーズ用 slot は、異なる番号でなければなりません。
解除手段と key slot の対応を記録する
追加後の luksDump と slot 指定付き解除試験から、少なくとも次の表を作成します。
| Slot | 状態 | 解除手段 | 用途 | 判断 |
|---|---|---|---|---|
KEYFILE_SLOT |
Active | /etc/cryptsetup-keys/crypt_name.key |
通常運用 | 残す |
EMERGENCY_SLOT |
Active | 対話入力 | 非常時復旧 | 残す |
| 既存 slot | Active | 確認済みの解除情報 | 既存運用 | 必要性を判断する |
| 既存 slot | Active | 不明 | 用途不明 | 削除しない |
keyfile が他の slot では使えないことを確認したい場合は、luksDump に表示された有効 slot だけを対象に、番号を 1 つずつ指定して試験します。
sudo cryptsetup open \
--test-passphrase \
--key-file "$KEYFILE" \
--key-slot OTHER_ACTIVE_SLOT \
"$DEVICE"
printf 'exit status: %s\n' "$?"
別の slot で失敗しても、その slot が不要だとは判断できません。非常用パスフレーズ、過去の管理者用解除情報、一時的な移行用解除情報である可能性があります。
削除直前の LUKS ヘッダーを再度バックアップする
通常運用用 keyfile と非常用パスフレーズの両方が機能する状態を、削除前の第 2 基準点として保存します。
最初に、slot を限定しない通常の解除試験も実行します。
sudo cryptsetup open --test-passphrase --key-file "$KEYFILE" "$DEVICE"
printf 'keyfile exit status: %s\n' "$?"
sudo cryptsetup open --test-passphrase "$DEVICE"
printf 'emergency passphrase exit status: %s\n' "$?"
両方の終了状態が 0 であることを確認したら、削除直前のヘッダーバックアップを取得します。
STAMP=$(date +%Y%m%d-%H%M%S)
HEADER_BEFORE_DELETE="$HEADER_BACKUP_DIR/luks-${LUKS_UUID}-before-delete-${STAMP}.img"
sudo cryptsetup luksHeaderBackup \
--header-backup-file "$HEADER_BEFORE_DELETE" \
"$DEVICE"
sudo chown root:root "$HEADER_BEFORE_DELETE"
sudo chmod 0400 "$HEADER_BEFORE_DELETE"
sudo test -s "$HEADER_BEFORE_DELETE"
sudo sha256sum "$HEADER_BEFORE_DELETE"
before-change と before-delete は別ファイルとして残します。前者は作業開始前、後者は新しい 2 系統の解除経路を追加した後の状態です。
削除対象を確定する
削除できるのは、次の条件をすべて満たす slot だけです。
- slot 番号を
luksDumpで確認している - 通常運用用 keyfile の slot ではない
- 非常用パスフレーズの slot ではない
- token や起動処理から参照されていない
- 一時作業用または廃止済みの解除手段であることを確認している
- 変更前と削除直前のヘッダーバックアップを取得済みである
- 残す 2 系統の解除試験が成功している
用途不明の slot は削除しません。slot 数が多いことだけを理由に整理すると、必要な復旧経路を失う可能性があります。
不要な key slot を 1 つずつ削除する
luksKillSlot は、番号を指定して key slot を消去します。最後の有効な slot も削除でき、その場合は LUKS コンテナへ恒久的にアクセスできなくなります。7
--batch-mode または -q は使いません。認証情報を標準入力から渡した場合も バッチモードが暗黙に有効になり、最後の slot を削除するときの警告が表示されない場合があります。パスフレーズをパイプで渡さず、複数の slot をループで連続削除しません。
削除前に、残す slot 番号をもう一度確認します。
sudo cryptsetup luksDump "$DEVICE"
sudo cryptsetup open \
--test-passphrase \
--key-file "$KEYFILE" \
--key-slot KEYFILE_SLOT \
"$DEVICE"
sudo cryptsetup open \
--test-passphrase \
--key-slot EMERGENCY_SLOT \
"$DEVICE"
削除対象を確定したら、DELETE_SLOT_NUMBER を実際の数値へ置き換えて 1 slot だけ削除します。
sudo cryptsetup luksKillSlot \
--key-file "$KEYFILE" \
"$DEVICE" \
DELETE_SLOT_NUMBER
ここで指定する keyfile は、削除後にも残る KEYFILE_SLOT の解除手段です。DELETE_SLOT_NUMBER に KEYFILE_SLOT を指定してはいけません。
削除直後に 2 系統の解除経路を再試験する
1 slot を削除するたびに、状態確認と解除試験を実行します。
sudo cryptsetup luksDump "$DEVICE" | tee "$WORKDIR/luks-dump-after-delete.txt"
sudo cryptsetup open \
--test-passphrase \
--key-file "$KEYFILE" \
--key-slot KEYFILE_SLOT \
"$DEVICE"
printf 'keyfile slot exit status: %s\n' "$?"
sudo cryptsetup open \
--test-passphrase \
--key-slot EMERGENCY_SLOT \
"$DEVICE"
printf 'emergency slot exit status: %s\n' "$?"
次の状態を確認します。
| 確認対象 | 正常条件 |
|---|---|
| 削除対象 slot |
luksDump で有効ではない |
| 通常運用用 slot | slot 指定付き keyfile 試験が成功する |
| 非常用 slot | slot 指定付き対話試験が成功する |
| LUKS UUID | 作業前と変わっていない |
| LUKS Version |
2 のままである |
どちらかの解除試験に失敗した場合は、次の slot を削除しません。対象デバイス、slot 番号、keyfile、入力したパスフレーズを再確認します。
さらに不要な slot を削除する場合も、削除、luksDump、2 系統の解除試験を 1 組として繰り返します。一括削除は行いません。
luksRemoveKey と luksKillSlot を使い分ける
luksRemoveKey は、入力した解除情報に対応する key slot を削除します。slot 番号を意識せず、特定の古いパスフレーズを無効化するときに使えます。
一方、この記事では、luksDump と slot 指定付き解除試験によって削除対象の番号を確定しています。そのため、削除意図を明示できる luksKillSlot を使います。
どちらを使う場合も、削除前に残す解除経路を試験し、ヘッダーバックアップを取得する条件は変わりません。
作業結果を台帳へ記録する
作業完了後は、次の情報を記録します。
| 項目 | 記録内容 |
|---|---|
| 対象媒体 |
/dev/disk/by-id の識別子、モデル、シリアル番号、容量 |
| LUKS UUID |
cryptsetup luksUUID の出力 |
| LUKS Version | 2 |
| cryptsetup version |
cryptsetup --version の出力 |
| keyfile path | /etc/cryptsetup-keys/crypt_name.key |
| keyfile size | 32 byte |
| keyfile owner/mode |
root:root、0400
|
| keyfile SHA-256 | 識別用ハッシュ |
| 通常運用用 slot |
KEYFILE_SLOT の実値 |
| 非常用 slot |
EMERGENCY_SLOT の実値 |
| 削除した slot | slot 番号、旧用途、削除日 |
| 変更前バックアップ | ファイル名、保存場所、SHA-256 |
| 削除前バックアップ | ファイル名、保存場所、SHA-256 |
| 最終試験 | keyfile と非常用パスフレーズの試験結果 |
keyfile の中身と非常用パスフレーズ自体は台帳へ記載しません。
一時ファイルが不要になったら削除します。
rm -rf "$WORKDIR"
ヘッダーバックアップは一時ファイルではありません。復旧方針と退役条件を定めたうえで、保護された保存先に残します。
作業を中止する条件
次のいずれかに該当した場合は、破壊的操作へ進みません。
- 対象デバイスの UUID、容量、モデル、シリアル番号が想定と一致しない
- LUKS1 または detached header である
-
luksDumpに token が表示される - 起動用ルートデバイス、swap、initramfs の keyfile に関係する
- 現在の解除手段で
--test-passphraseが成功しない - keyfile が別の暗号化デバイスでも使われている可能性がある
- ヘッダーバックアップの保存先が対象デバイスと同じ物理媒体にある
- 通常運用用 keyfile と非常用パスフレーズの slot 番号を確定できない
- 削除候補の用途を確認できない
- 削除後に残る 2 系統の解除試験が成功していない
まとめ
LUKS2 の key slot 整理は、luksKillSlot を実行するだけの作業ではありません。対象媒体と LUKS UUID を固定し、現在の解除手段を試験し、変更前のヘッダーを保存したうえで、通常運用用 keyfile と非常用パスフレーズを別々の slot に追加します。
その後、slot 指定付きの --test-passphrase で解除手段と番号を対応付け、追加後のヘッダーを再度保存します。削除できるのは、用途を確定でき、残す 2 系統とは異なる slot だけです。1 slot を削除するたびに luksDump と 2 系統の解除試験を繰り返し、両方が成功する状態を維持します。
最終的に残すべきなのは、数が少ない slot ではなく、用途、解除手段、復旧方法、削除条件を説明できる slot です。
参考文献
- id774, 暗号化ディスク運用手順を整理する(2026-05-31). https://blog.id774.net/entry/2026/05/31/4829/
- cryptsetup project, cryptsetup-open(8)(2025-07-29). https://gitlab.com/cryptsetup/cryptsetup/-/blob/c66c520e26106ffb6ee297cb6bc08b691a830b28/man/cryptsetup-open.8.adoc
- cryptsetup project, Cryptsetup 2.7.0 Release Notes(2024-01-24). https://gitlab.com/cryptsetup/cryptsetup/-/blob/4dde8f078fe82e97920217e739319bbad88d3782/docs/v2.7.0-ReleaseNotes
- cryptsetup project, cryptsetup-luksDump(8)(2025-07-29). https://gitlab.com/cryptsetup/cryptsetup/-/blob/c66c520e26106ffb6ee297cb6bc08b691a830b28/man/cryptsetup-luksDump.8.adoc
- cryptsetup project, cryptsetup-luksHeaderBackup(8)(2025-07-29). https://gitlab.com/cryptsetup/cryptsetup/-/blob/c66c520e26106ffb6ee297cb6bc08b691a830b28/man/cryptsetup-luksHeaderBackup.8.adoc
- cryptsetup project, cryptsetup-luksAddKey(8)(2025-07-29). https://gitlab.com/cryptsetup/cryptsetup/-/blob/349912fec260c5cb9484ca7408c255dab16d6fbe/man/cryptsetup-luksAddKey.8.adoc
- cryptsetup project, cryptsetup-luksKillSlot(8)(2025-07-29). https://gitlab.com/cryptsetup/cryptsetup/-/blob/2c95933bb5e08839faa7960b86eea4a3901e3756/man/cryptsetup-luksKillSlot.8.adoc