深夜2時、突如としてPagerDutyのアラートが鳴り響きます。カーネルの自動アップデート後、メインのデータベースクラスタが監視システムから忽然と姿を消しました。SSH接続を試みるも返ってくるのは Connection timed out。慌ててIPMI経由でリモートコンソールを開くと、そこには見慣れた文字列が表示されていました:dracut: Please enter passphrase for disk。コンソールで直接パスフレーズを入力する担当者がいなければ、サーバーはそのまま45分間も沈黙を続けることになります。
多くの現場インフラを調査していると、よくある2つの過ちを目にします。1つは、再起動時の停止を恐れてデータを平文(プレーンテキスト)のまま放置しているケース。もう1つは、あろうことかパスワードを /etc/crypttab ファイルに直接平文で書き込んでいるケースです。このどちらを選んでも、ディスク暗号化が持つ本来の価値は完全に失われてしまいます。
サーバー再起動時におけるLUKSの3つのアンロック方式を比較
電源オフ時のデータ保護(Data-at-Rest)を確保しつつ、サーバーの再起動をスムーズに自動化するために、システム管理者は通常次の3つのアプローチを検討します:
- 方法1:IPMIやDropbear SSHを介した手動パスフレーズ入力
再起動のたびにコンソールを開くか、initramfs環境へSSH接続して手動でパスワードを入力します。 - 方法2:USBメモリや/bootパーティションからキーファイルを直接読み込む
システムがあらかじめサーバー内に保存されたキーファイルを読み取り、LUKSパーティションを自動で復号します。 - 方法3:ClevisとTangによるネットワーク経由のアンロック(NBDE)
信頼できる内部ネットワーク経由でTangサーバーとの通信に成功した場合にのみ、クライアントはディスクを復号できます。万が一、悪意のある第三者がデータセンターからディスクを持ち去っても、取り出せるのは意味のない暗号化データの塊だけです。
各アプローチのメリットとデメリット
1. 手動によるパスフレーズ入力
- メリット:完全な自己完結性。ネットワークインフラや外部サーバーに一切依存しません。
- デメリット:運用負荷が極めて高いこと。深夜の定期再起動や停電後の自動復電時、担当者が手動でキー入力するまで関連するすべてのサービスが長時間のダウンタイムに陥ります。
2. サーバーローカルへのキーファイル保存
- メリット:起動処理が即座に完了し、ネットワークの不安定さに影響されません。
- デメリット:見せかけの安全性にすぎない点。物理サーバーにアクセスできる人物や、クラウド上のディスクイメージをクローンした攻撃者なら、一瞬でキーファイルを読み取れてしまいます。これでは暗号化の意味がありません。
3. ネットワーク結合型ディスク暗号化(Clevis + Tang)の利用
- メリット:内部LAN内で完全に自動化される点。TangサーバーはECDH(楕円曲線ディフィー・ヘルマン)ハンドシェイクプロトコルを採用しており、クライアントの秘密鍵を保持しません。そのため、仮にTangサーバーが侵害されても、攻撃者がディスクを復号するための鍵一覧を入手することは不可能です。
- デメリット:起動初期段階(early boot)のネットワークが正確に動作している必要があります。また、単一障害点(SPOF)を回避するため、最低でも2台のTangサーバーを用意することが推奨されます。
どのようなケースで導入すべきか?
ClevisとTangの組み合わせ(NBDE)は、ハウジング(コロケーション)サーバー、オンプレミスのサーバースペース、あるいは自宅の検証用ラボクラスタに最適です。安全な社内LAN内にある限りサーバーは自由に自動再起動できますが、何者かがハードディスクを抜き取ったり筐体ごと持ち出したりした場合は、内部のデータは強固にロックされたまま守られます。
Ubuntu / Debianにおける実践セットアップ手順
検証環境の構成例
- Tangサーバー: IP
192.168.10.50(Ubuntu Server 22.04/24.04) - 対象クライアント: IP
192.168.10.100(保護対象パーティション:/dev/sdb1)
ステップ1:Tangサーバーの構築
Tangサービスが消費するメモリは50MB未満です。補助サーバーや内部コンテナへ簡単にインストールできます:
sudo apt update
sudo apt install -y tang
sudo systemctl enable --now tangd.socket
サービスはsystemdソケットを介してバックグラウンドで動作し、TCPポート 80 をリッスンします。curlコマンドを使ってTangの応答を確認します:
curl -s http://localhost/adv | head -n 5
公開鍵情報を含むJSON文字列が出力されれば、Tangサーバーは正常に稼働しています。
ステップ2:クライアント上でLUKS2暗号化パーティションを作成
クライアントマシンにログインします。新しい暗号化パーティションを初期化し、緊急時レスキュー用の管理者パスフレーズを設定します:
# LUKS2形式でパーティションをフォーマット
sudo cryptsetup luksFormat --type luks2 /dev/sdb1
# パーティションを開いてext4ファイルシステムを作成
sudo cryptsetup open /dev/sdb1 secure_data
sudo mkfs.ext4 /dev/mapper/secure_data
sudo cryptsetup close secure_data
注意:設定したパスフレーズは、緊急メンテナンス時に備えてチームのパスワード管理ツール(BitwardenやVaultなど)に必ず安全に保管してください。
ステップ3:ClevisのインストールとTangサーバーへのバインド
クライアントマシンに必要なパッケージをインストールします:
sudo apt update
sudo apt install -y clevis clevis-luks clevis-initramfs
暗号化パーティション /dev/sdb1 をTangサーバーにバインド(紐付け)します:
sudo clevis luks bind -d /dev/sdb1 tang '{"url":"http://192.168.10.50"}'
Tangサーバーの鍵フィンガープリントが表示され、信頼するか確認を求められます。y を入力し、ステップ2で設定した管理者パスフレーズを入力します。Clevisは既存のパスワードを上書きすることなく、LUKSヘッダー内に新しいキースロットを作成します。
キースロットの構成を確認します:
sudo cryptsetup luksDump /dev/sdb1
Tokenセクションに clevis とTangサーバーのURLが表示されていれば、バインドは成功です。
ステップ4:/etc/crypttabによる自動マウントの設定
元の暗号化パーティションのUUIDを確認します:
sudo blkid -s UUID -o value /dev/sdb1
取得したUUIDが 12345678-abcd-1234-abcd-1234567890ab だと仮定します。/etc/crypttab ファイルに以下の1行を追加します。_netdev オプションは、ネットワークがオンラインになるまで復号処理を待機するようsystemdに指示します:
secure_data UUID=12345678-abcd-1234-abcd-1234567890ab none luks,_netdev
続けてマウントポイント用ディレクトリを作成し、/etc/fstab にマウント設定を追記します:
sudo mkdir -p /mnt/data
echo "/dev/mapper/secure_data /mnt/data ext4 defaults,_netdev 0 2" | sudo tee -a /etc/fstab
ステップ5:initramfsの更新と再起動テスト
Clevisのネットワークフックを確実に組み込むため、initramfsを再ビルドします:
sudo update-initramfs -u -k all
設定が正常に機能するか、クライアントを再起動して確認します:
sudo reboot
IPMIやコンソール経由でブートプロセスを監視します。マシンはDHCP経由で自動的にIPアドレスを取得し、192.168.10.50 のTangサーバーとハンドシェイクを行い、キーボードに一切触れることなくわずか3〜5秒でパーティションを復号して /mnt/data に自動マウントします。
実運用におけるTipsとノウハウ
- Tangサーバーへの接続が失われた場合: Clevisはタイムアウトするまで複数回再試行します。待機時間を過ぎると、システムは自動的に従来の手動パスフレーズ入力画面にフォールバックします。データアクセスが完全に膠着状態に陥る心配はありません。
- 高可用性(HA)の冗長構成: 本番環境では、単一のTangサーバーに依存すべきではありません。ClevisのShamir Secret Sharing(SSS)アルゴリズムを活用することで、異なるスイッチ配下に配置した2台のTangサーバーへ同時にバインドできます:
sudo clevis luks bind -d /dev/sdb1 sss '{"t":1,"pins":{"tang":[{"url":"http://192.168.10.50"},{"url":"http://192.168.10.51"}]}}'
しきい値パラメータ "t":1 を指定することで、2台のTangサーバーのうちどちらか1台でも応答すれば、ディスクは自動的に正常アンロックされます。

