Linux Kernel Lockdown: ルート権限による攻撃を防ぐ方法

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

ルート権限を超えて:午前2時のサバイバル・ストーリー

午前2時、監視ダッシュボードに5xxエラーが急増しました。攻撃者がWebアプリケーションの脆弱性を突き、ルート権限を奪取したのです。以前なら、これは「詰み」を意味していました。ルートユーザーであれば、悪意のあるカーネルモジュールのロード、機密メモリのスクレイピング、再起動後も持続するバックドアをカーネルイメージに埋め込むことが可能だからです。

しかし、この特定のサーバーは持ちこたえました。たとえ uid=0 であっても、攻撃者は姿を隠せませんでした。ルートキットを注入しようとするあらゆる試みは「Operation not permitted(許可されていない操作です)」エラーで失敗したのです。その理由は、Linux Kernel Lockdownを有効にしていたからです。この機能は、たとえスーパーユーザーであっても、オペレーティングシステムの核心部を修正する全権限を持つべきではないという考え方に立ち、Linuxのセキュリティモデルを転換させます。

クイックスタート:5分でLockdownを確認・有効化する

Ubuntu 20.04+、RHEL 8+、Debian 10+を含む主要な最新ディストリビューションは、カーネルでLockdownをサポートしています。ただし、デフォルトでは無効になっていることが多いです。以下の手順でステータスの確認と有効化が可能です。

ステップ1:現在のステータスを確認する

まず、カーネルがこの機能をサポートしているか、どのモードが有効かを確認します。以下のコマンドを実行してください:

cat /sys/kernel/security/lockdown

以下のような出力が表示されます:

none [integrity] confidentiality

括弧 [] 内の値が現在アクティブなモードです。もし [none] と表示されているなら、そのカーネルはルート権限による改ざんに対して無防備な状態です。ファイルが存在しない場合は、カーネルが古すぎる(5.4未満)か、CONFIG_SECURITY_LOCKDOWN_LSM フラグが設定されていません。

ステップ2:GRUB経由で恒久的に有効化する

Lockdownを恒久的に有効にするには、起動時にカーネルパラメータを渡します。GRUBの設定ファイルを開きます:

sudo nano /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT の行を探し、lockdown=integrity を追加します。設定は以下のようになります:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash lockdown=integrity"

ファイルを保存し、ブートローダーを更新してシステムを再起動します:

sudo update-grub
sudo reboot

こうした環境のセキュリティを強化する際、私は toolcraft.app/ja/tools/security/password-generator を使って複雑なサーバーパスワードを生成しています。ブラウザ上でローカルに動作するため、機密性の高い文字列がネットワークに流れることがありません。境界線のセキュリティを保つためのシンプルな習慣です。

Integrity(整合性)対 Confidentiality(機密性):レベルの選択

Lockdownは単なるオン・オフのスイッチではありません。2つの異なる保護レベルを提供しています。適切なレベルを選ぶには、セキュリティ要件とシステムデバッグの必要性のバランスを考える必要があります。

Integrityモード

lockdown=integrity を設定すると、ユーザースペースのプロセスが実行中のカーネルを修正しようとする機能をブロックします。本番サーバーの95%にとって、これが標準的な選択肢です。このモードでは以下の制限が適用されます:

  • /dev/mem および /dev/kmem を無効化し、メモリへの直接書き込みを停止。
  • kexec を制限し、署名されていない信頼できないカーネルの起動を防止。
  • 署名されていないカーネルモジュールのロードをブロック(ルートキット阻止に不可欠)。
  • CPUを乗っ取る可能性のあるMSR(Model-Specific Register)への書き込みアクセスを制限。

Confidentialityモード

lockdown=confidentiality モードは、いわば「パラノイア」設定です。Integrityモードのすべてに加え、ユーザーがカーネルからデータを 抽出 することも禁止します。より強力な制限が加わります:

  • /proc/kcore へのアクセスを完全に制限。
  • カーネルメモリを覗き見る可能性のあるeBPF(Berkeley Packet Filter)操作をブロック。
  • デバッガがカーネルにアタッチするのを防止。

高度なセキュリティが要求される環境でのみ使用してください。カーネルパニックやパフォーマンスのボトルネックを調査する必要がある場合、このモードは支障をきたす可能性が高いです。

信頼の連鎖:LockdownとUEFI Secure Boot

現代のディストリビューションでは、BIOSでUEFI Secure Bootが有効になっていると、自動的にLockdownが有効になることがよくあります。これにより、強固な「信頼の連鎖(Chain of Trust)」が構築されます。ハードウェアがブートローダーを検証し、ブートローダーがカーネルを検証し、カーネルがLockdownを使用してルートユーザーがその信頼を損なわないようにします。mokutil でステータスを確認してください:

mokutil --sb-state

Secure Bootが有効なら、カーネルはすでにデフォルトで integrity モードになっているはずです。本番環境でこれを上書きする必要がある場合は、通常、ハードウェア設定でSecure Bootを無効にする必要がありますが、あまりお勧めしません。

実践的な注意点:何が動かなくなるか?

Lockdownは強力ですが、破壊的な側面もあります。私は、この機能を有効にするまで何年も動いていたスクリプトが「Permission Denied(拒否されました)」エラーを吐くのを、何時間もかけてデバッグしてきました。

  1. プロプライエタリなドライバ: 古いNvidiaや特殊なRAIDコントローラモジュールなど、署名されていないドライバはロードに失敗します。Machine Owner Key (MOK) を使用して手動で署名する必要があります。
  2. ハイバネーション: ディスクへのサスペンド(休止状態)は無効化されることが多いです。これは、電源が切れている間に保存されたシステム状態が改ざんされ、復帰時にカーネルが侵害される可能性があるためです。
  3. ハードウェアツール: dmidecode やセンサーなど、メモリアドレスから直接読み取るユーティリティは、動作を停止するか、空の結果を返すようになります。
  4. オブザーバビリティ: confidentiality モードでは、bccbpftrace などの高度なツールが特定の関数を調査できなくなります。

「決定的証拠」を見つける方法

カーネルがアクションをブロックすると、そのイベントをログに記録します。サービスが原因不明の失敗をした場合は、すぐにログを確認してください:

dmesg | grep -i "Lockdown"

Lockdown: systemd-udevd: /dev/mem is restricted(Lockdown:systemd-udevd:/dev/memは制限されています)のようなエントリが表示されます。このログエントリは頼もしい味方です。どのシステムコールやデバイスアクセスがブロックされたかを正確に教えてくれます。

最後に

Kernel Lockdownは、Linuxのセキュリティにおける大きな勝利です。これは、ルートアカウントが侵害される可能性がある(そして実際に侵害される)ことを認めた上での対策です。攻撃対象領域を最小限に抑えることで、1つのサービスが突破されても、ハードウェアへの信頼が完全に失われる事態を防げます。まずはステージング環境で integrity モードから始め、監視スクリプトをテストした上で本番環境へ展開しましょう。将来の自分に感謝することになるはずです。

Share: