LUKSとcryptsetupでLinuxの機密データを保護する:ノートPCからサーバーまでの暗号化設定ガイド

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

Linuxのアカウントパスワードが意味をなさない瞬間

外出先のカフェに会社のThinkPadを忘れてしまった、あるいは企業でSASドライブ付きの旧型サーバーを廃棄したとします。エンジニアの中には、いまだに「rootパスワードは25文字の強固なものを設定しているから、誰にも侵入できない」と確信している人も少なくありません。

しかし、現実はそれほど甘くありません。第三者がUbuntu Live入りのUSBを挿すか、あるいはSSDを取り外して外付けドライブスタンドにセットするだけで、OSのアカウント管理はすべて無力化します。.envファイル、SSH秘密鍵、プロジェクトのソースコード、さらにはMySQLデータベースまで、すべてが平文(プレーンテキスト)のまま丸見えになってしまうのです。物理ハードウェアへの直接アクセスを許した場合、OSのログインパスワードは何の役にも立ちません。

2022年、私の同僚はあるトラブルでインフラの全APIトークンを大至急差し替える事態に陥りました。データセンターでレンタルサーバーを返却する際、エンジニアが追加ストレージの初期化を忘れてしまったことが原因です。この教訓以来、私たちのチームではすべてのワークステーションおよびデータ用ストレージでハードウェアレベルの暗号化を義務付けています。

脆弱性の本質:ブロックデバイスとプレーンテキスト

なぜシステムのパスワードはLive USBの前に無力なのでしょうか? その原因はストレージの階層構造にあります。

  • OSの権限管理機構(User、Sudo、Chmod):Linuxがブートし、カーネルが稼働している間のみ機能します。この状態において、OSは個々のファイルに対する読み書き権限を制御します。
  • ブロックデバイス層(Block Device):ハードウェアの最下層において、SSDのメモリチップには加工されていないデータブロックがそのまま記録されています。攻撃者が別のカーネルでブートした場合、セクタから直接読み出すことを防ぐ手段はありません。

端的に言えば、ディスクを暗号化せずにLinuxにパスワードを設定するのは、玄関のドアを開け放ったまま寝室のドアだけに鍵をかけているようなものです。侵入者は家に入り、重要書類の入ったキャビネットごと持ち去ることができてしまいます。

Linuxでデータを保護する3つのアプローチ:どれを選ぶべきか?

デバイス紛失時の情報漏洩を防ぐアプローチには、主に以下の3つがあります。

  • 個別ファイルごとの暗号化圧縮(Zip、7z、GPG):数個のファイルをメール送付する際には手軽です。しかし、継続的な書き込みが発生するデータベースやサービスログには適用できません。
  • ディレクトリ単位の暗号化(eCryptfs、fscrypt):特定のディレクトリ(/home/userなど)配下のデータのみを保護します。ファイルサイズやディレクトリ構造などのメタデータは保護されず、スワップ領域や/tmpに機密データが漏れるリスクも残ります。
  • LUKSによるブロックレベルの暗号化:パーティション全体が解読不能なランダムデータに変換されます。正しいキーがロードされた時のみRAM上で復号されます。AES-NIインストラクションセットに対応したCPUであれば、パフォーマンス低下は極めて軽微(通常2%未満)です。

暗号化標準LUKSとcryptsetupツール

LUKS(Linux Unified Key Setup)は、現在ほとんどのLinuxディストリビューションで標準採用されているディスク暗号化仕様です。現行バージョンはLUKS2で、強力なAES-XTS-PLAIN64アルゴリズム(鍵長256ビットまたは512ビット)をサポートしています。また、LUKS2ではキースロットが最大32個まで管理可能(LUKS1の8個から拡張)となり、数百ギガバイトのデータを再暗号化することなく、チームメンバーへの鍵の追加やパスフレーズの変更が容易に行えます。

パーティション暗号化の設定手順

ここでは、追加のストレージパーティション(サーバーのデータ用ドライブや外付けドライブなど)、例えば/dev/sdb1を暗号化する手順を解説します。

ステップ1:cryptsetupのインストールとハードウェア要件の確認

まず、CPUがハードウェア暗号化アクセラレーションに対応しているか確認します。

grep -m1 -E '(aes|aesni)' /proc/cpuinfo

出力にaesフラグが含まれていれば、CPU側で低遅延の暗号化処理を実行する準備が整っています。次に、ツールをインストールします。

# Debian, Ubuntu
sudo apt update && sudo apt install -y cryptsetup

# RHEL, Rocky Linux, AlmaLinux
sudo dnf install -y cryptsetup

ステップ2:LUKS形式でのパーティションフォーマット

lsblkコマンドで対象のパーティション名を正確に特定します。誤ったドライブを指定すると、既存のオペレーティングシステムが完全に消失します。

sudo cryptsetup luksFormat --type luks2 /dev/sdb1

大文字での警告メッセージが表示されます。正確にYESと入力し、解除用のパスフレーズを設定します。総当たり(ブルートフォース)攻撃への耐性と覚えやすさを両立させるため、ランダムな4〜6単語を組み合わせたパスフレーズを推奨します。

ステップ3:デバイスのロック解除(マッピング)

フォーマット直後のパーティションはそのままではマウントできません。/dev/mapper/配下の仮想ブロックデバイスとしてマッピングする必要があります。

sudo cryptsetup open /dev/sdb1 secure_vault

ステップ2で設定したパスフレーズを入力すると、/dev/mapper/secure_vaultに新しいデバイスノードが作成されます。この仮想デバイスは、通常のストレージと同様にフォーマットやマウントが可能です。

ステップ4:ファイルシステムの作成とマウント

初回設定時は、ロック解除したデバイス上にファイルシステム(ext4など)を作成します。

# ext4形式でフォーマット
sudo mkfs.ext4 -L DATA_VAULT /dev/mapper/secure_vault

# マウントポイントの作成とシステムへのマウント
sudo mkdir -p /mnt/secure_vault
sudo mount /dev/mapper/secure_vault /mnt/secure_vault

これで、PostgreSQLのデータベース、機密ソースコード、SSL証明書などを/mnt/secure_vaultへ安全に保存できるようになりました。Linuxカーネルがディスクへの書き込み時にデータを自動暗号化します。

ステップ5:パーティションの安全なアンマウントとロック

外付けドライブを取り外す前やメンテナンス終了時には、マウントを解除して暗号化層を閉じる必要があります。

# ディレクトリをアンマウント
sudo umount /mnt/secure_vault

# マッピングデバイスをロック
sudo cryptsetup close secure_vault

これにより、/dev/sdb1は意味を持たないバイナリデータの塊に戻ります。第三者がドライブを抜き取って別のマシンに接続しても、ランダムなガベージデータとしてしか認識されません。

LUKS運用における2つの重要ポイント

セキュリティ対策がデータ消失の悲劇につながらないよう、以下の2点に注意してください。

  1. LUKSヘッダーを必ずバックアップする:パーティションの先頭には、メタデータと暗号化キーを格納するヘッダー(LUKS2では約16MB)が存在します。この領域に不良セクタが発生すると、正しいパスフレーズを知っていてもデータは永久に復元できなくなります。セットアップ完了直後に必ずバックアップを取得してください。
    sudo cryptsetup luksHeaderBackup /dev/sdb1 --header-backup-file ~/backup_sdb1_header.img

    バックアップファイルは、安全なUSBメモリや暗号化されたクラウドストレージなど、別の安全な場所に保管してください。

  2. ヘッドレスサーバーでの自動ロック解除:データセンターに設置されたサーバーには、リブートのたびにパスフレーズを手動入力するためのディスプレイやキーボードがありません。外付けUSBドライブ上のキーファイルを使用するか、TPM 2.0チップとの連携(systemd-cryptenrollを利用)、またはClevis/Tang(ネットワークバインドディスク暗号化:NBDE)を導入することで、安全なローカルネットワーク経由で自動ロック解除を行う設計を検討してください。
Share: