Fedoraでsystemd-cryptenrollとYubiKeyを活用:FIDO2によるLUKS2のロック解除ガイド

Fedora tutorial - IT technology blog
Fedora tutorial - IT technology blog

背景と導入の理由

深夜2時、カーネルの自動アップデート後にサーバーが再起動し、黒い画面で停止する――Please enter passphrase for disk...。1秒以上のレイテンシがある不安定なWebコンソール越しに、35文字のランダムなパスフレーズを入力し、4回目のタイプミスでシステムが一時ロックされる。本番環境の障害対応を眠気眼でこなした経験があるエンジニアなら、このもどかしさが痛いほど分かるはずです。

筆者のThinkPad(Fedora Workstation)でも、新しいカーネルを適用して再起動するたびにディスクパスフレーズの再入力が必要でした。手軽さを求めてUSBメモリに生のキーファイルを保存し、常時接続して/etc/crypttab経由でマウントする方法をとる人もいます。確かに便利ではあるものの、セキュリティリスクは極めて甚大です。そのUSBメモリを紛失・盗難されたら、ストレージ内のデータはすべて盗まれたも同然です。

FIDO2とsystemd-cryptenrollの組み合わせは、利便性とセキュリティを高度に両立する優れた解決策となります。静的なキーファイルをディスクに保存する代わりに、ハードウェアFIDO2規格のhmac-secret拡張を活用します。その仕組みは非常に堅牢で、LUKS2がYubiKeyのセキュアチップと紐づく新しいキースロットを生成します。

ブート時、systemd-cryptsetupはランダムなソルトをハードウェアキーに送信します。トークンは内部のシークレットを用いてHMACコードを計算し、復号キーを返します。ユーザーはYubiKeyを差し込み、4〜6桁の短いPINコードを入力して金属製タッチセンサーに触れるだけです。キーを抜いてしまえば、第三者がマスターキーを抽出したり複製したりすることは不可能です。

事前準備とパッケージのインストール

作業を始める前に、対象のパーティションがLUKS2規格であることを確認してください。systemd-cryptenrollは旧仕様のLUKS1には対応していません。

システム上のディスクパーティション一覧を確認します:

lsblk -f

暗号化パーティションが/dev/nvme0n1p3(FSTYPEがcrypto_LUKS)であると仮定します。ヘッダーのバージョンを確認しましょう:

sudo cryptsetup luksDump /dev/nvme0n1p3 | head -n 5

Version: 2と表示されていれば準備完了です。古いバージョンのFedoraからアップグレードした環境などでVersion: 1と表示される場合は、事前にアップグレードが必要です:sudo cryptsetup convert /dev/nvme0n1p3 --type luks2。

Fedoraに必要なFIDO2関連ライブラリをインストールします:

sudo dnf install -y libfido2 fido2-tools cryptsetup

YubiKeyをUSBポートに接続し、正しく認識されるか確認します:

systemd-cryptenroll --fido2-device=list

実行結果に/dev/hidrawX形式のパスとデバイス名(例: Yubico YubiKey OTP+FIDO+CCID)が表示されます。何も表示されない場合は、別のUSBポートを試すか、pcscdサービスを再起動してみてください。

設定手順

LUKSヘッダーを直接操作する際、処理の途中で電源が切れるとキースロット情報が破損する恐れがあります。作業前に必ず外付けUSB等へヘッダーのバックアップを取得しておきましょう:

sudo cryptsetup luksHeaderBackup /dev/nvme0n1p3 --header-backup-file ~/luks2-header-backup.img

ステップ1: YubiKeyをLUKS2のキースロットに登録

systemd-cryptenrollを実行して、空いているキースロットに新しい復号キーを登録します。PINコード(User Verification)とタッチ操作(User Presence)の両方を有効にした2層の保護を推奨します:

sudo systemd-cryptenroll --fido2-device=auto \
  --fido2-with-client-pin=yes \
  --fido2-with-user-presence=yes \
  /dev/nvme0n1p3

ターミナルで3段階の認証が求められます:

  1. 新しいスロットへの書き込み権限を付与するため、対象ディスクの既存のパスフレーズを入力します。
  2. YubiKeyのFIDO2 PIN(トークン管理用のPINコード)を入力します。
  3. YubiKeyのLEDが点滅したら、金属製センサーに触れて登録を完了します。

このコマンドにより、新しいキースロット(通常はslot 1)がYubiKeyに紐付けられます。

ステップ2: /etc/crypttab の更新

次に、起動プロセスが優先してFIDO2トークンへ問い合わせを行うよう設定します:

sudo nano /etc/crypttab

rootパーティションの設定行は通常、以下のようになっています:

luks-4a1b2c3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID=4a1b2c3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx none discard

第4フィールドにオプションfido2-device=autoを追加します:

luks-4a1b2c3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID=4a1b2c3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx none discard,fido2-device=auto

あわせてタイムアウト時間も設定しておくことをお勧めします。YubiKeyを差し忘れた場合でも、15秒待機した後に従来のパスフレーズ入力画面へと自動でフォールバックします:

luks-4a1b2c3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID=4a1b2c3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx none discard,fido2-device=auto,fido2-device-timeout=15s

ステップ3: DracutによるInitramfsの再生成

Fedoraはinitramfsのフェーズでrootパーティションの復号を行います。そのため、ブートイメージ内にFIDO2ドライバーとsystemd-cryptsetupバイナリが組み込まれている必要があります。これらが不足していると、マシンは黒い画面で停止してしまいます。

DracutにFIDO2モジュールを読み込ませる設定を追加します:

echo 'add_dracutmodules+=" crypt fido2 "' | sudo tee /etc/dracut.conf.d/fido2.conf

既存の全カーネルに対してinitramfsを再構築します:

sudo dracut -f --regenerate-all

処理には約30〜60秒かかります。エラーメッセージが出力されずに完了することを確認してください。

動作確認とトラブルシューティング

キースロットがトークンを正しく認識しているか確認します:

sudo cryptsetup luksDump /dev/nvme0n1p3

出力内のTokens:セクションにsystemd-fido2と該当するキースロット番号が表示されていれば成功です。キースロット0のテキストパスフレーズは、キーを携帯していない場合のバックアップ手段としてそのまま保持されます。

実際のブート動作の検証

システムを再起動してテストします:

sudo systemctl reboot

状況に応じて以下のいずれかの挙動になります:

  • YubiKeyを挿入している場合: PIN入力プロンプトが表示されます。PINを入力するとYubiKeyのLEDが点滅するので、キーに触れると2〜3秒でFedoraのデスクトップ画面が立ち上がります。
  • YubiKeyを挿入していない場合: 15秒のタイムアウト後、見慣れたPlease enter passphrase for disk...が表示され、通常通りオリジナルのパスフレーズを入力して起動できます。

Dracut Emergency Shellに突入した場合の対処法

ドライバーの不足やinitramfsのビルドエラーによりdracut:/#シェルに落ちてしまった場合も、落ち着いて対処してください:

  1. 従来のパスフレーズを使って手動でパーティションをロック解除します:
    cryptsetup luksOpen /dev/nvme0n1p3 root_crypt
    exit

    (root_cryptの部分は、crypttabファイルの第1フィールドに記述されているマッパー名に置き換えてください)。

  2. OSが起動したら、systemdのログを確認してFIDO2が認識されなかった原因を特定します:
    sudo journalctl -b -u systemd-cryptsetup*
  3. YubiKeyを紛失した場合や新しいキーに変更したい場合は、以下のコマンドで古いFIDO2スロットを削除できます:
    sudo systemd-cryptenroll --wipe-slot=fido2 /dev/nvme0n1p3

この設定を導入すれば、毎日の煩わしいパスワード入力の手間を大幅に削減できます。さらに重要なのは、公共の場などでPCを開く際にも、長いディスクパスフレーズを覗き見されるリスクから完全に解放されることです。

Share: