第19章 SELinux の使用
19.1. SELinux の使用
Security Enhanced Linux (SELinux) は、新たにシステムセキュリティーの層を提供します。SELinux は、基本的に次の質問に答えます。May <subject> do <action> to <object>? 以下に例を示します。Web サーバーが、ユーザーのホームディレクトリーにあるファイルにアクセスできる可能性がありますか?
19.1.1. SELinux の概要
ユーザー、グループ、およびその他のアクセス権に基づいた標準のアクセスポリシーは Discretionary Access Control (DAC) として知られており、システム管理者が、包括的で詳細なセキュリティーポリシー (たとえば、特定のアプリケーションではログファイルの表示だけを許可し、その他のアプリケーションではログファイルに新しいデータを追加するのを許可するなど) を作成することはできません。
Security Enhanced Linux (SELinux) は Mandatory Access Control (MAC) を実装します。それぞれのプロセスおよびシステムリソースには、SELinux コンテキスト と呼ばれる特別なセキュリティーラベルがあります。SELinux コンテキストは SELinux ラベル として参照されることがありますが、システムレベルの詳細を抽象化し、エンティティーのセキュリティープロパティーに焦点を当てた識別子です。これにより、SELinux ポリシーでオブジェクトを参照する方法に一貫性を持たせ、他の識別方法に含まれる曖昧さがなくなりました。たとえば、バインドマウントを使用するシステムで、ファイルに、有効なパス名を複数設定できます。
SELinux ポリシーは、プロセスが、互いに、またはさまざまなシステムリソースと相互作用する方法を定義する一連のルールにこのコンテキストを使用します。デフォルトでは、最初にルールが明示的にアクセスを許可し、その後ポリシーが任意の対話を許可します。
SELinux ポリシールールが DAC ルールの後に確認されている点に注意してください。DAC ルールがアクセスを拒否すると、SELinux ポリシールールは使用されません。これは、従来の DAC ルールがそのアクセスを拒否すると、SELinux 拒否がログに記録されないということを示しています。
SELinux コンテキストには、複数のフィールド (ユーザー、ロール、タイプ、セキュリティーレベル) があります。プロセスとシステムリソースとの間で許可される相互作用を定義する最も一般的なポリシールールは、完全な SELinux コンテキストではなく、SELinux タイプを使用するため、SELinux ポリシーでは、SELinux のタイプ情報がおそらく最も重要です。SELinux のタイプの名前は、最後に _t
が付きます。たとえば、Web サーバーのタイプ名は httpd_t
です。/var/www/html/
にあるファイルおよびディレクトリーのタイプコンテキストは、通常 httpd_sys_content_t
です。/tmp
および /var/tmp/
にあるファイルおよびディレクトリーのタイプコンテキストは、通常 tmp_t
です。Web サーバーポートのタイプコンテキストは http_port_t
です。
Apache (httpd_t
として実行する Web サーバープロセス) を許可するポリシールールがあります。このルールでは、通常 /var/www/html/
にあるコンテキストを持つファイルおよびディレクトリーと、その他の Web サーバーディレクトリー (httpd_sys_content_t
) へのアクセスを許可します。通常、/tmp
および /var/tmp/
に含まれるファイルのポリシーには、許可ルールがないため、アクセスは許可されません。SELinux を使用すれば、Apache が危険にさらされ、悪意のあるスクリプトがアクセスを得た場合でも、/tmp
ディレクトリーにアクセスすることはできなくなります。
図19.1 Apache と MariaDB を安全に実行する SELinux の例
![SELinux_Apache_MariaDB_example](https://access.redhat.com/webassets/avalon/d/Red_Hat_Enterprise_Linux-8-System_Design_Guide-ja-JP/images/f7b4d4a7ee54ec0153a3422060470895/selinux-intro-apache-mariadb.png)
このスキーマが示すように、SELinux は、httpd_t
として実行している Apache プロセスが /var/www/html/
ディレクトリーにアクセスするのは許可しますが、同じ Apache プロセスが /data/mysql/
ディレクトリーにアクセスするのは拒否します。これは、httpd_t
タイプコンテキストと mysqld_db_t
タイプコンテキストに許可ルールがないのが原因です。一方、mysqld_t
として実行する MariaDB プロセスは /data/mysql/
ディレクトリーにアクセスできますが、SELinux により、mysqld_t
タイプを持つプロセスが、httpd_sys_content_t
とラベルが付いた /var/www/html/
ディレクトリーにアクセスするのは拒否されます。
関連情報
-
apropos selinux
コマンドで表示される man ページのselinux(8)
-
selinux-policy-doc
パッケージをインストールしている場合は、man -k _selinux
コマンドで表示された man ページ。 - The SELinux Coloring Book、SELinux の基本概念をよりよく理解するのに役立ちます。
- SELinux Wiki FAQ
19.1.2. SELinux を実行する利点
SELinux は、次のような利点を提供します。
- プロセスとファイルにはすべてラベルが付いています。SELinux ポリシーにより、プロセスがファイルと相互作用する方法と、プロセスが互いに相互作用する方法が定義されます。アクセスは、それを特別に許可する SELinux ポリシールールが存在する場合に限り許可されます。
- SELinux はきめ細かなアクセス制御を提供します。SELinux のアクセスは、ユーザーの裁量と、Linux のユーザー ID およびグループ ID に基づいて制御される従来の UNIX アクセス権だけでなく、SELinux のユーザー、ロール、タイプなど (必要に応じてセキュリティーレベルも) の、入手可能なすべての情報に基づいて決定されます。
- SELinux ポリシーは管理者が定義し、システム全体に適用されます。
- SELinux は権限昇格攻撃を軽減できます。プロセスはドメインで実行するため、互いに分離しています。SELinux ポリシールールは、プロセスがどのようにファイルやその他のプロセスにアクセスするかを定義します。プロセスへのアクセスが不正に行われても、攻撃者は、そのプロセスの通常の機能と、そのプロセスがアクセスするように設定されているファイルにしかアクセスできません。たとえば、Apache HTTP Server へのアクセスが不正に行われても、そのアクセスを許可する特別な SELinux ポリシールールが追加されたり、設定された場合を除き、ユーザーのホームディレクトリーにあるファイルを読み込むプロセスを攻撃者が利用することはできません。
- SELinux はデータの機密性と整合性を強化し、信頼できない入力からプロセスを保護できます。
SELinux は、ウイルス対策ソフトウェア、セキュアなパスワード、ファイアウォール、その他のセキュリティーシステムに代わるものではなく、既存のセキュリティーソリューションを強化することを目的としたものです。SELinux を実行している場合でも、ソフトウェアを最新の状態にする、推測が困難なパスワードを使用する、ファイアウォールを使用するなど、優れたセキュリティー対策を続けることが重要です。
19.1.3. SELinux の例
以下の例は、SELinux がどのようにセキュリティーを向上するかを説明します。
- デフォルトのアクションは拒否です。アクセスを許可する SELinux のポリシールール (ファイルを開くプロセスなど) が存在しない場合は、アクセスが拒否されます。
-
SELinux は、Linux ユーザーに制限をかけられます。SELinux ポリシーには、制限がかけられた SELinux ユーザーが多数含まれます。Linux ユーザーを、制限がかけられた SELinux ユーザーにマッピングして、SELinux ユーザーに適用されているセキュリティールールおよびメカニズムを利用できます。たとえば、Linux ユーザーを SELinux
user_u
ユーザーにマッピングすると、その Linux ユーザーは、sudo
やsu
などの setuid (set user ID) アプリケーションを実行できなくなります。 - プロセスとデータの分離が向上します。SELinux ドメイン の概念により、特定のファイルやディレクトリーにアクセスできるプロセスの定義が可能になります。たとえば、SELinux を実行している場合に、(許可が設定されていない限り) 攻撃者は Samba サーバーを危険にさらすことはできず、その Samba サーバーを攻撃ベクトルとして使用して、その他のプロセス (MariaDB など) が使用するファイルの読み書きを行うことはできません。
-
SELinux は、設定ミスによるダメージを軽減します。ドメインネームシステム (DNS) サーバーは、多くの場合、ゾーン転送で相互に情報をレプリケートします。攻撃者は、ゾーン転送を使用して、虚偽の情報で DNS サーバーを更新できます。RHEL で Berkeley Internet Name Domain (BIND) を DNS サーバーとして実行している場合、管理者がゾーン転送を実行できるサーバーを制限するのを忘れた場合でも、デフォルトの SELinux ポリシーによってゾーンファイルの更新が妨げられます。 [1] BIND
named
のデーモン自体、およびその他のプロセスによって、ゾーン転送を使用します。 -
SELinux を使用しない場合、攻撃者は脆弱性を悪用して Apache Web サーバーのパストラバーサルを行い、
../
などの特別な要素を使用してファイルシステムに保存されているファイルやディレクトリーにアクセスできます。SELinux を enforcing モードで実行しているサーバーに対して攻撃者が攻撃を試みた場合、SELinux は、httpd
プロセスがアクセスしてはならないファイルへのアクセスを拒否します。SELinux はこのタイプの攻撃を完全にブロックすることはできませんが、効果的に緩和します。 -
Enforcing モードの SELinux は、非 SMAP プラットフォームでのカーネル NULL ポインター逆参照 Operator の悪用を正常に防止します (CVE-2019-9213)。攻撃者は、null ページのマッピングをチェックしない
mmap
関数の脆弱性を利用して、このページに任意のコードを配置します。 -
deny_ptrace
SELinux ブール値と Enforcing モードの SELinux は、システムを PTRACE_TRACEME 脆弱性 (CVE-2019-13272) から保護します。このような設定により、攻撃者がroot
権限を取得できるシナリオが防止されます。 -
nfs_export_all_rw
およびnfs_export_all_ro
SELinux ブール値は、/home
ディレクトリーの偶発的な共有など、ネットワークファイルシステム (NFS) の設定ミスを防ぐための使いやすいツールを提供します。
関連情報
- オペレーティングシステムのセキュリティーの柱としての SELinux - 実際の利点と例 (Red Hat ナレッジベース)
- Ansible による SELinux の強化 (Red Hat ナレッジベース)
- selinux-playbooks SELinux ハードニング用の Ansible Playbook を含む Github リポジトリー
19.1.4. SELinux のアーキテクチャーおよびパッケージ
SELinux は、Linux カーネルに組み込まれる Linux セキュリティーモジュール (LSM) です。カーネルの SELinux サブシステムは、管理者が制御し、システムの起動時に読み込まれるセキュリティーポリシーにより動作します。システムにおけるセキュリティー関連の、カーネルレベルのアクセス操作はすべて SELinux により傍受され、読み込んだセキュリティーポリシーのコンテキストに従って検討されます。読み込んだポリシーが操作を許可すると、その操作は継続します。許可しないと、その操作はブロックされ、プロセスがエラーを受け取ります。
アクセスの許可、拒否などの SELinux の結果はキャッシュされます。このキャッシュは、アクセスベクトルキャッシュ (AVC) として知られています。このように結果がキャッシュされると、確認が必要な量が減るため、SELinux ポリシーのパフォーマンスが向上します。DAC ルールがアクセスを拒否した場合は、SELinux ポリシールールが適用されないことに注意してください。未加工の監査メッセージのログは、行頭に type=AVC
文字列が追加されて、/var/log/audit/audit.log
に記録されます。
RHEL 8 では、システムサービスは systemd
デーモンによって制御されています。systemd
はすべてのサービスを起動および停止し、ユーザーとプロセスは systemctl
ユーティリティーを使用して systemd
と通信します。systemd
デーモンは、SELinux ポリシーを調べ、呼び出しているプロセスのラベルと、呼び出し元が管理するユニットファイルのラベルを確認してから、呼び出し元のアクセスを許可するかどうかを SELinux に確認します。このアプローチにより、システムサービスの開始や停止などの、重要なシステム機能へのアクセス制御が強化されます。
また、systemd
デーモンは SELinux Access Manager としても起動します。systemctl
を実行しているプロセス、または systemd
に D-Bus
メッセージを送信したプロセスのラベルを取得します。次に、デーモンは、プロセスが設定するユニットファイルのラベルを探します。最後に、SELinux ポリシーでプロセスラベルとユニットファイルラベルとの間で特定のアクセスが許可されている場合、systemd
はカーネルから情報を取得できます。これは、特定のサービスに対して、systemd
と相互作用を必要とする、危険にさらされたアプリケーションを SELinux が制限できることを意味します。ポリシー作成者は、このような粒度の細かい制御を使用して、管理者を制限することもできます。
プロセスが別のプロセスに D-Bus
メッセージを送信しているときに、この 2 つのプロセスの D-Bus
通信が SELinux ポリシーで許可されていない場合は、システムが USER_AVC
拒否メッセージを出力し、D-Bus 通信がタイムアウトになります。2 つのプロセス間の D-Bus 通信は双方向に機能することに注意してください。
SELinux ラベリングが誤っているために問題が発生するのを回避するには、systemctl start
コマンドを使用してサービスを開始するようにしてください。
RHEL 8 では、SELinux を使用するために以下のパッケージが提供されています。
-
ポリシー -
selinux-policy-targeted
、selinux-policy-mls
-
ツール -
policycoreutils
、policycoreutils-gui
、libselinux-utils
、policycoreutils-python-utils
、setools-console
、checkpolicy
19.1.5. SELinux のステータスおよびモード
SELinux は、3 つのモード (Enforcing、Permissive、または Disabled) のいずれかで実行できます。
- Enforcing モードは、デフォルトのモードで、推奨される動作モードです。SELinux は、Enforcing モードでは正常に動作し、読み込んだセキュリティーポリシーをシステム全体に強制します。
- Permissive モードでは、システムは、読み込んだセキュリティーポリシーを SELinux が強制しているように振る舞い、オブジェクトのラベリングや、アクセスを拒否したエントリーをログに出力しますが、実際に操作を拒否しているわけではありません。Permissive モードは、実稼働システムで使用することは推奨されませんが、SELinux ポリシーの開発やデバッグには役に立ちます。
- Disabled モードを使用することは推奨されません。システムは、SELinux ポリシーの強制を回避するだけでなく、ファイルなどの任意の永続オブジェクトにラベルを付けなくなり、将来的に SELinux を有効にすることが難しくなります。
Enforcing モードと Permissive モードとの間を切り替えるには setenforce
ユーティリティーを使用してください。setenforce
で行った変更は、システムを再起動すると元に戻ります。Enforcing モードに変更するには、Linux の root ユーザーで、setenforce 1
コマンドを実行します。Permissive モードに変更するには、setenforce 0
コマンドを実行します。getenforce
ユーティリティーを使用して、現在の SELinux モードを表示します。
# getenforce
Enforcing
# setenforce 0 # getenforce Permissive
# setenforce 1 # getenforce Enforcing
Red Hat Enterprise Linux では、システムを Enforcing モードで実行している場合に、個々のドメインを Permissive モードに設定できます。たとえば、httpd_t ドメインを Permissive に設定するには、以下のコマンドを実行します。
# semanage permissive -a httpd_t
Permissive ドメインは、システムのセキュリティーを侵害できる強力なツールです。Red Hat は、特定のシナリオのデバッグ時など、Permissive ドメインを使用する場合は注意することを推奨します。