午前2時のパスワード入力を撲滅する:TPM 2.0によるLUKSの自動アンロック

Security tutorial - IT technology blog
Security tutorial - IT technology blog

午前2時の再起動という悪夢

深夜2時15分、リモートiDRACコンソールを見つめながらサーバーがオンラインに戻るのを待つ――そんな夜を私は何度も過ごしてきました。ルーチンのカーネルパッチによる再起動が行われ、そしてすべてが止まります。画面には、見慣れた、しかし苛立たしいプロンプトが表示されたままです:ディスクのパスフレーズを入力してください... (Please enter passphrase for disk...)。ノートPC 1台なら大した手間ではありません。しかし、暗号化された50台のノードが並ぶラックでは、これは運用上の災害です。一瞬の停電のたびに、すべてのマシンのために32文字のパスワードを入力しに待機しているわけにはいきません。

そこで、セキュリティスタックに組み込むべきなのが Trusted Platform Module (TPM) です。Dell PowerEdgeサーバーからThinkPadまで、最近のほとんどのマザーボードにはTPM 2.0チップが搭載されています。キーを暗記したり付箋に貼ったりする代わりに、そのキーをTPMハードウェア内に直接「封印(シール)」します。システムの状態が改ざんされていない場合にのみ、ドライブのロックが解除されます。これは、高度な暗号化と運用上の正気のバランスを保つための完璧な妥協点です。

最初にこのボリュームをプロビジョニングしたとき、私は toolcraft.app/ja/tools/security/password-generator のジェネレーターを使用して、エントロピーの高い文字列を作成しました。このツールは完全にブラウザ内で動作するため、キーがネットワークに流れることはありません。私はその文字列を「緊急時用(break-glass)」のバックアップとして保管しました。しかし、日常の運用では、ハードウェアにその重労働を任せたいと考えています。

PCRを理解する:セキュリティの門番

TPMは、要求してきた誰にでもキーを渡すわけではありません。PCR (Platform Configuration Registers) を使用して、システムの整合性を「測定」します。これらは、ハードウェアとソフトウェアの状態の暗号化スナップショットだと考えてください。一般的なレジスタには以下のものがあります:

  • PCR 0: コアBIOSおよびUEFIコード。
  • PCR 1: マザーボードおよびチップセットの構成。
  • PCR 7: セキュアブート(Secure Boot)のポリシーと証明書。

攻撃者がNVMeドライブを抜き取り、別のマシンに差し込んだ場合、PCRの値が変化します。TPMはこの不一致を検出し、キーの放出を拒否します。ほとんどの本番環境では、PCR 7にバインドするのが最適です。これにより、軽微なファームウェアのアップデートで永久にロックアウトされるほど脆弱ではなく、かつマシンが信頼できるセキュアブート状態にあることを保証できます。

インストール:ツールの準備

LUKS (Linux Unified Key Setup) とTPMを橋渡しするために、Clevis というフレームワークを使用します。また、ハードウェアとやり取りするために tpm2-tools も必要です。以下の手順は、Ubuntu 22.04以降、Fedora、またはRHEL 9を実行していることを前提としています。

まず、必要なパッケージをインストールします:

# Ubuntu/Debianの場合
sudo apt update
sudo apt install tpm2-tools clevis clevis-tpm2 clevis-luks clevis-dracut -y

# RHEL/CentOS/Fedoraの場合
sudo dnf install tpm2-tools clevis clevis-luks clevis-dracut -y

次に進む前に、Linuxカーネルがチップと通信できることを確認します:

tpm2_pcrread sha256:7

コマンドが64文字の16進文字列を返せば、準備完了です。「Device not found」エラーが表示される場合は、BIOS設定を確認してください。TPM(PTTまたはfTPMと表記されている場合もあります)がバージョン2.0に設定され、明示的に有効になっていることを確認してください。

設定:LUKSをハードウェアにバインドする

現代のLUKSボリュームには、キーのための複数の「スロット」があります。通常、スロット0には手動入力用のパスフレーズが保持されています。Clevisを使用して、TPMによって封印されたキーで2番目のスロットを埋めます。

ステップ 1: 対象パーティションの特定

lsblk を使用して暗号化ボリュームを特定します:

lsblk -f

crypto_LUKS というラベルを探してください。このガイドでは、パーティションが /dev/nvme0n1p3 であると想定します。

ステップ 2: キーの封印

このコマンドは新しいシークレットを生成し、それをPCR 7に対して封印し、メタデータをLUKSヘッダーに保存します。これにより、データが特定のマザーボードのセキュアブート状態に効果的に紐付けられます。

sudo clevis luks bind -d /dev/nvme0n1p3 tpm2 '{"pcr_ids":"7"}'

注: 既存のパスフレーズの入力を求められます。Clevisは、新しいキースロットの作成を承認するためにこれを必要とします。初期セットアップ時に生成した高エントロピーのパスワードを使用してください。

ステップ 3: ブートイメージの再構築

システムは、ルートファイルシステムがマウントされるずっと前の初期ブート段階でClevisをロードする必要があります。そのためには、初期RAMディスク (initramfs) を再構築する必要があります。

Ubuntu/Debian系システムの場合:

sudo update-initramfs -u

RHEL/Fedora系システムの場合:

sudo dracut -f

私はいつも、ビルドログに clevis モジュールが含まれていることを確認します。これが欠けていると、ブートプロセスは依然としてパスワードプロンプトで停止してしまい、このセットアップの目的が果たせなくなります。

自動化のテスト

テストの時間です。マシンを再起動してください。設定が正しければ、GRUBメニューが表示された後、1秒ほどの短い休止があります。パスワードを要求される代わりに、システムはそのままログイン画面へと進むはずです。魔法のように感じられますが、これはハードウェアに裏打ちされた信頼の仕組みです。

スロットの確認

LUKSヘッダーの変化を確認するには、以下を実行します:

sudo cryptsetup luksDump /dev/nvme0n1p3

2つのアクティブなスロットが表示されるはずです。スロット0は手動のバックアップです。もう1つのスロット(通常はスロット1)には、大きな「Tokens」セクションが表示されます。このメタデータは、TPMと通信するためにどのようにClevisを使用するかをシステムに伝えます。

リカバリ:失敗した場合は?

BIOSをアップデートしたり、セキュアブートを無効にしたりすると、PCR 7の値が変化します。TPMは即座に不一致を検知し、キーの放出を拒否します。これはシステムが意図通りに動作している証拠です。

これが発生した場合、ブートプロセスは単に手動のパスフレーズプロンプトにフォールバックします。バックアップパスワードを入力してログインし、バインドを更新してください:

# 古くなった、または壊れたバインドを削除する
sudo clevis luks unbind -d /dev/nvme0n1p3 -s 1

ディスク復号の自動化は、セキュリティの手を抜くことではありません。人間の介入なしに電源サイクルから復旧できる、回復力のあるインフラを構築することです。シークレットをTPMにオフロードすることで、データが「その」特定のハードウェア上でのみアクセス可能であることを保証し、ようやく午前2時の再起動中に安眠できるようになるのです。

Share: