Linuxセキュリティアプローチの比較:従来の権限を超えて
Linuxシステムを保護することは、多くの課題を伴います。長年、私は従来の裁量アクセス制御(DAC)、つまりユーザー権限、SUIDビットの管理、sudoの慎重な使用に焦点を当てることでこれらに対処してきました。
このアプローチは、正規のユーザーができることを効果的に制御する一方で、システム管理者が実行中のすべてのアプリケーションとサービスを信頼していることを根本的に前提としています。しかし、アプリケーションが侵害された場合はどうなるでしょうか?DACは、攻撃者の横方向への移動や権限昇格の試みに対して、最小限の防御しか提供しないことがよくあります。
SELinuxやAppArmorなどの強制アクセス制御(MAC)システムは、根本的に異なるセキュリティモデルを導入します。これらは管理者の判断に依存するだけでなく、MACは従来のユーザー権限とは完全に独立して、システム管理者が定義した厳格なセキュリティポリシーを強制します。これは強力です。たとえrootユーザーや侵害されたサービスであっても、そのアクションはMACポリシーによって制限される可能性があります。
SELinuxは、そのきめ細かな制御と包括的な性質により際立っており、多層防御戦略において重要な層となります。AppArmorはパスベースの制御を使用しますが、SELinuxはタイプエンフォースメントモデルという独自のアプローチを採用しています。すべてのプロセス、ファイル、ネットワークポートにラベルを付け、それらがどのように相互作用できるかを明示的なルールで定義します。この詳細なレベルがSELinuxの真の強みを際立たせています。
実践におけるSELinux:6ヶ月後に明らかになった長所と短所
SELinuxの実装は大規模な取り組みです。10以上のLinux VPSインスタンスにSELinuxを統合して約6ヶ月後、私はその現実世界での利点と課題を明確に理解しました。
長所:サービスのための要塞
- きめ細かな制御: SELinuxは、プロセスアクセスに対して非常にきめ細かな制御を提供します。サービスが利用できるファイル、ディレクトリ、ネットワークポート、さらにはカーネル機能まで、正確に指示できます。例えば、侵害されたWebサーバーは、不正なファイルへの書き込みや、明示的に許可されていない外部ネットワーク接続の実行を阻止することができます。
- 多層防御: SELinuxは、ファイアウォール、強力なパスワード、アプリケーションレベルのセキュリティと連携して、重要なセキュリティ層を追加します。攻撃者が脆弱性を悪用した場合でも、SELinuxは悪意のあるプロセスが不正なアクションを実行するのをブロックすることで、多くの場合、侵害を封じ込めることができます。
- プロセス隔離: 各サービスは、厳密に定義された独自のセキュリティコンテキスト内で動作します。これにより、SELinuxがサービス間の境界を厳密に強制するため、1つのサービスにおける脆弱性が他のサービスに影響を与える可能性がはるかに低くなります。攻撃が成功した場合の「被害範囲」は劇的に減少します。
- ゼロデイ攻撃に対する緩和策: SELinuxポリシーは、許可されるものを規定し、禁止されるものを規定しません。この決定的な違いは、未知の脆弱性から引き起こされる攻撃を阻止できることが多いことを意味します。例えば、攻撃者がゼロデイ脆弱性を使用してプロセスを侵害しても、SELinuxがそのプロセスによる
/etc/passwdへの書き込みを阻止すれば、攻撃はその目的を達成できません。
課題:複雑さと学習曲線
- 急な学習曲線: SELinuxのコンテキスト、タイプ、ロール、ルールを習得するには、かなりの時間が必要です。その用語と概念モデルは従来の権限とは大きく異なり、初期設定は非常に困難です。
- 誤設定の可能性: 誤って設定されたポリシーは、アプリケーションを簡単に機能不全に陥れる可能性があります。不可解なエラーメッセージに遭遇したり、サービスが起動しなかったりすることがありますが、多くの場合、SELinuxが問題であるという明確なヒントはありません。このことから、徹底的なテストが絶対に不可欠であることが強調されます。
- トラブルシューティングの頭痛の種: アプリケーションが誤動作した場合、SELinuxが原因であるかどうかを突き止め、正確なルール違反を特定するのに多くの時間がかかることがあります。これは通常、監査ログを深く掘り下げることを意味しますが、監査ログは冗長で、特殊な解析ツールを必要とすることがよくあります。
3年間にわたって10以上のLinux VPSインスタンスを管理してきた結果、SELinuxポリシーを本番環境にデプロイする前に、徹底的なテストがいかに重要であるかを身をもって学びました。 その影響を完全に理解せずにライブシステムにポリシーを盲目的に適用することは、ダウンタイムとフラストレーションを招く確実な方法です。ここでは、忍耐と系統的なアプローチが最大の味方となるでしょう。
推奨される設定:SELinux強制の段階的アプローチ
SELinuxを効果的に実装するには、単に有効にするだけでは不十分です。戦略的かつ段階的なアプローチが不可欠です。私は、段階的な強制、包括的なログ記録、反復的なポリシーの洗練に焦点を当てることを提案します。
SELinuxモードの理解
SELinuxは、主に3つのモードで動作します。
- Enforcing: SELinuxポリシーが完全にアクティブになり、違反はログに記録され、ブロックされます。これは本番環境で望ましい状態です。
- Permissive: SELinuxポリシーはアクティブですが、違反はログに記録されるだけで、ブロックされません。このモードは、実際に何も壊すことなく何がブロックされるかを確認できるため、トラブルシューティングやポリシー開発に非常に役立ちます。
- Disabled: SELinuxは完全に非アクティブです。セキュリティ意識の高い環境では、保護の重要な層がなくなるため、このモードは強く推奨されません。
強固な基盤から始める
- Permissiveモードから開始: 新しいシステムを展開する場合でも、既存のシステムにSELinuxを追加する場合でも、常にPermissiveモードから開始してください。これにより、SELinuxがすべてのポリシー違反をログに記録しながら、アプリケーションがスムーズに実行され続けることが保証されます。後でこれらのログを分析して、カスタムポリシーを構築または洗練できます。
- 現在のポリシーを理解する: CentOS、RHEL、Fedora、AlmaLinux、Rocky Linuxなどのディストリビューションでは、通常、デフォルトで「targeted」ポリシーが使用されます。このポリシーは、ネットワークデーモンやその他の重要なサービスの保護に焦点を当てており、一般的にユーザーアプリケーションは制約を受けません。高セキュリティのセットアップでは、Multi-Level Security(MLS)またはMulti-Category Security(MCS)を検討するかもしれませんが、「targeted」はほとんどの一般的なユースケースの実用的な出発点として機能します。
- 重要なサービスを優先する: すべてを同時に保護しようとする衝動に抵抗してください。代わりに、Webサーバー、データベース、SSHなどの最も重要なサービスにまず集中してください。Enforcingモードに切り替える前に、これらのサービスがPermissiveポリシーの下で正しく動作することを確認してください。
実装ガイド:ステータスチェックからカスタムポリシーまで
実践的な内容に入りましょう。SELinuxの設定と管理には、一連のコアコマンドとトラブルシューティングのワークフローが含まれます。
1. SELinuxステータスの確認
最初のステップは、常にシステム上のSELinuxの現在の状態を確認することです。
sestatus
このコマンドは、SELinuxのステータス、ロードされているポリシー、現在のモードなど、包括的な概要を提供します。
getenforce
SELinuxがEnforcing、Permissive、またはDisabledモードであるかを素早く確認するためのよりシンプルなコマンドです。
2. SELinuxモードの変更
SELinuxモードは一時的または永続的に変更できます。
一時的な変更(再起動まで):
sudo setenforce 0 # Permissiveモードに切り替える
sudo setenforce 1 # Enforcingモードに切り替える
これらの変更はすぐに有効になりますが、再起動後に元に戻ります。
永続的な変更:
変更を永続化するには、SELinux設定ファイルを編集する必要があります。
sudo vi /etc/selinux/config
SELINUXディレクティブを探し、enforcing、permissive、またはdisabledに設定します。その後、変更を完全に有効にするためにシステムを再起動します。
# このファイルはシステム上のSELinuxの状態を制御します。
# SELINUX= には以下の3つの値のいずれかを指定できます:
# enforcing - SELinuxセキュリティポリシーが強制されます。
# permissive - SELinuxは強制せずに警告を出力します。
# disabled - SELinuxポリシーはロードされません。
SELINUX=enforcing
# SELINUXTYPE= には以下の3つの値のいずれかを指定できます:
# targeted - ターゲットとなるプロセスが保護され、
# 保護されていないプロセスはそのままになります。
# mls - 多重レベルセキュリティ保護。
# mcs - 多重カテゴリセキュリティ保護。
SELINUXTYPE=targeted
3. SELinuxコンテキストの理解
SELinuxは、すべてのファイル、プロセス、ポートにセキュリティコンテキストを割り当てます。通常、user:role:type:levelの形式です。ほとんどのポリシー決定において、「タイプ」コンポーネントが最も重要になります。
ファイルのコンテキストを確認するには:
ls -Z /var/www/html
これにより、/var/www/html内のファイルとディレクトリのSELinuxコンテキストが表示されます。例えば、unconfined_u:object_r:httpd_sys_content_t:s0と表示される場合、これらのファイルはWebサーバーコンテンツ用であることを示します。
実行中のプロセスのコンテキストを確認するには:
ps -efZ | grep httpd
おそらくsystem_u:system_r:httpd_t:s0のようなものが表示され、Apache Webサーバープロセスのコンテキストを示します。
4. SELinuxブール値の管理
SELinuxブール値は、シンプルなオン/オフスイッチとして機能します。これらを使用すると、ポリシーを完全に再コンパイルすることなく、既存のポリシーの動作を調整できるため、一般的な調整に最適です。
すべてのブール値とその状態を一覧表示するには:
getsebool -a
例えば、Webサーバーがネットワークリソース(別のホスト上のデータベースなど)に接続する必要がある場合、httpd_can_network_connectを有効にする必要があるかもしれません。
sudo setsebool -P httpd_can_network_connect on
-Pフラグは、再起動後も変更を永続化させます。
5. 監査ログによるトラブルシューティング
トラブルシューティングのスキルが真に発揮されるのはここです。SELinuxが原因でアプリケーションが失敗した場合、auditdサービスはすべての拒否を綿密にログに記録します。これらのログを効果的に分析することが絶対に不可欠です。
auditdが実行中であることを確認するには:
sudo systemctl status auditd
SELinuxの拒否を調べるための主要なツールはausearchです。Webサーバーが特定のディレクトリへの書き込みに失敗した場合、httpdに関連する拒否を探します。
sudo ausearch -c httpd --raw | audit2allow -M mywebserver
これを分解してみましょう。
ausearch -c httpd --raw:このコマンドは、httpdコマンドに関連付けられたイベントを監査ログから検索し、生(raw)形式で出力します。audit2allow -M mywebserver:この強力なツールは、生の監査ログを処理します。その後、以前に拒否されたアクションを許可するように設計された、mywebserverという名前のカスタムSELinuxポリシーモジュール(.teファイル)とコンパイル済みパッケージ(.ppファイル)を提案します。
出力には提案されたルールが表示されます。これらを注意深く確認してください!盲目的に適用しないでください。必要以上に多くの権限を付与する可能性があります。これは私の個人的な経験と一致しています。常に許可する内容を確認してください。
6. カスタムポリシーの作成
audit2allowの出力を注意深く確認し、提案されたルールに自信がある場合、カスタムポリシーモジュールをコンパイルしてインストールに進むことができます。
sudo semodule -i mywebserver.pp
このコマンドは、新しいポリシーモジュールをカーネルにロードし、新しいルールを直ちに強制します。削除する必要がある場合:
sudo semodule -r mywebserver
実用例:Nginxが非標準ディレクトリからコンテンツを配信できるようにする
Nginxが/opt/mywebappからコンテンツを配信するようにしたいと想像してください。デフォルトでは、Nginxは通常/usr/share/nginx/htmlまたは/var/www/htmlにのみアクセスできます。
- ディレクトリとコンテンツを作成する:
sudo mkdir /opt/mywebapp sudo echo "こんにちは、SELinux!" | sudo tee /opt/mywebapp/index.html - Nginxを設定する(簡略化されています。Nginxの設定を調整してください):
server { listen 80; server_name localhost; root /opt/mywebapp; index index.html; } - ページへのアクセスを試みます。おそらく失敗するでしょう(403 Forbidden)。
- 監査ログを確認する(SELinuxがPermissiveまたはEnforcingモードであることを確認):
sudo ausearch -c nginx --raw | audit2allow -M nginx_mywebapp/opt/mywebapp内のdefault_tまたは類似のコンテキストを持つファイルにアクセスしようとしているnginxに関連する拒否が表示される可能性が高いです。ポリシーはおそらく、/opt/mywebapp(/.*)?にhttpd_sys_content_tのラベルを付けることを提案するでしょう。 - 正しいファイルコンテキストを適用する:
sudo semanage fcontext -a -t httpd_sys_content_t "/opt/mywebapp(/.*)?" sudo restorecon -Rv /opt/mywebappsemanage fcontextは永続的なコンテキストを定義し、restoreconはそれを直ちに適用します。 - (オプション)
audit2allowの出力に基づいてsemanage fcontextで不十分な場合は、カスタムポリシーを作成してインストールする:# 生成された nginx_mywebapp.te を確認 sudo semodule -i nginx_mywebapp.pp - Nginxを再起動して再度テストします。
7. 本番環境での考慮事項
- 定期的なポリシー更新: 定期的なパッケージ更新を通じて、システムのベースSELinuxポリシーを最新の状態に保ちます。
- バックアップとリカバリ: 重要なSELinuxポリシー変更を実装する前に、バックアップ戦略があることを確認してください。以前の正常な状態に戻す方法を知っていることは不可欠です。
- 継続的な監視: 設定して放置するだけではいけません。特にアプリケーションの更新やシステム変更の後には、新しいSELinuxの拒否がないか、監査ログを監視してください(LogwatchやSIEMなどのツールを使用するかもしれません)。この積極的なアプローチは、問題がエスカレートする前にそれを発見するのに役立ちます。

