🐧 Linux 総合学習プラットフォーム
セキュリティ/権限強化 ・ 中級

SELinux / AppArmor の概要

通常のパーミッションに加えて、より強力にプロセスの行動を縛る仕組みが MAC(強制アクセス制御)です。RHEL/MiracleLinux系では SELinux が、Ubuntu系では AppArmor が採用されています。SELinux はファイルやプロセスに「ラベル」を付け、ポリシーで許可された動きしか認めません。現在の状態は getenforce で確認でき、Enforcing(強制)・Permissive(警告のみ)・Disabled(無効)の3モードがあります。setenforce で一時的にモードを切り替えられます。

これまで見てきたパーミッション(所有者・グループ・その他に対する rwx)は、Linuxの基本的なアクセス制御だ。

だが、これだけで本当に守りきれるのだろうか。

たとえば Web サーバのプロセスが乗っ取られた場合を考えてみたい。そのプロセスは Web サーバの実行ユーザが持つ権限の範囲で、本来触るべきでないファイルまで読み書きできてしまうかもしれない。

つまずきパーミッションは「誰が」を見るが、「そのプロセスが本来の仕事の範囲を超えていないか」までは縛れない。ここに穴がある。

ここに穴がある。パーミッションは「誰が」を見るが、「そのプロセスが本来やるべき仕事の範囲を超えていないか」までは縛れないのだ。

この弱点を補うのが MAC(Mandatory Access Control=強制アクセス制御)である。

💡
ポイントMAC は、管理者が定めたポリシーに反する動作を、ファイルの所有者でも root でも許さない。これが「強制」の意味だ。

MAC では、管理者が定めたポリシーに反する動作を、たとえファイルの所有者であっても、たとえ root であっても許さない。

RHEL/MiracleLinux系ではこの仕組みとして SELinux(selinux)が、Ubuntu系では AppArmor(apparmor)が採用されている。

同じ MAC でも、この2つはアプローチが異なる。

⚖ SELinux と AppArmor のアプローチの違い

乗っ取られたWebプロセス許された範囲/var/www → OK範囲外/etc/shadow などポリシーが拒否被害を封じ込める

SELinux は、ファイル・プロセス・ポートといったあらゆる対象に「ラベル(コンテキスト)」を付ける。そして、どのラベルのプロセスがどのラベルの対象にアクセスしてよいかをポリシーで厳密に定義する方式だ。

きめ細かく強力なぶん、概念はやや難しめになる。

🔗
たとえSELinux はラベル基準(対象に名札を付けて照合)、AppArmor はパス基準(このアプリはこのパスだけ)。狙いは同じだ。

一方 AppArmor は、プログラムごとに「このアプリはこのパスのファイルだけ触ってよい」というパス基準のプロファイルで縛る方式だ。相対的に分かりやすいとされる。

どちらも狙いは同じだ。「万一あるプロセスが乗っ取られても、そのプロセスがあらかじめ許された範囲しか行動できないようにし、被害の拡大を封じ込める」こと。

これは最小権限の原則を、ユーザ単位ではなくプロセスの振る舞い単位で徹底するもの、と捉えると腑に落ちる。

本トラックが前提とする RHEL/MiracleLinux系では SELinux が標準なので、以降は SELinux を中心に説明する。

では、その SELinux が今どう動いているかを、どこで確かめればよいのか。

🚦 状態を確認する getenforce と3つのモード

SELinux には3つの動作モードがある。

💡
ポイントEnforcing=違反を実際にブロック(本番)。Permissive=ブロックせずログだけ(観察)。Disabled=SELinux 自体を停止。

Enforcing(強制)はポリシー違反を実際にブロックする本番モードだ。Permissive(警告のみ)は違反をブロックせずログにだけ記録する観察モード。Disabled(無効)は SELinux 自体を止める状態だ。

getenforce で現在のモードが一語で返る。sestatus なら現在と設定ファイル上のモード、ポリシー種別までまとめて出る。

現在どのモードかは `getenforce` を実行すると Enforcing のように一語で返る。

より詳しい情報は `sestatus` で得られる。現在のモードと設定ファイル上のモード、ポリシーの種類などをまとめて確認できる。

RHEL/MiracleLinux系では既定で Enforcing になっており、これがセキュリティ上望ましい状態だ。

🔗
たとえトラブルで安易に Disabled にするのは、家の鍵を壊して「開かない問題」を解決するようなもの。本来避けるべきだ。

トラブルが起きると安易に Disabled にしてしまう人がいる。だがそれは家の鍵を壊して「開かない問題」を解決するようなもので、本来は避けるべき対処である。

とはいえ、切り分けのために一時的にモードを変えたい場面はある。そのとき何を使うのか。

🔄 モードを切り替える setenforce と恒久設定

setenforce 0 で Permissive に、setenforce 1 で Enforcing に、その場で切り替えられる。

モードの切り替えには `setenforce` を使う。`setenforce 0` で Permissive に、`setenforce 1` で Enforcing に、その場で切り替えられる。

ただしこの変更は一時的で、再起動すると元に戻る。

コツ「失敗の原因は SELinux か?」を確かめるとき、一時的に Permissive にして通れば原因は SELinux。確認後すぐ Enforcing に戻す。

これがむしろ切り分け作業に便利だ。「ある操作が失敗するのは SELinux のせいか?」を確かめたいとき、一時的に Permissive にして同じ操作が通るなら、原因は SELinux にあると判断できる(確認後はすぐ Enforcing に戻す)。

恒久的にモードを変えたいときは設定ファイル /etc/selinux/config の SELINUX= 行を書き換える。

つまずきDisabled と Enforcing/Permissive の切り替えは setenforce では行えず、config を編集して再起動する必要がある。

注意点として、Disabled と Enforcing/Permissive の間の切り替えは setenforce では行えず、config を編集して再起動する必要がある。

なお Disabled から復帰させると、ファイルのラベルが古くなっているため再ラベル付け(autorelabel)が走り、起動に時間がかかることがある。

ここで「ラベル」という言葉が出たが、初学者を最も悩ませるのが、まさにこのラベルにまつわる現象だ。

🏷 ラベルとブール値 — つまずきの正しい直し方

SELinux で初学者が最もつまずくのが、ファイルのラベル(コンテキスト)に起因する「なぜか動かない」現象だ。

つまずきWeb の公開ファイルを既定の /var/www 以外に置くと、ラベルが合わずアクセスが拒否される。「SELinux を切る」は誤った対処。

たとえば Web の公開ファイルを既定の /var/www 以外の場所に置くと、SELinux 的にはラベルが合わずアクセスが拒否される。

これを「SELinux を切る」で解決するのは誤りだ。正しくはラベルを正す対処をする。

restorecon -Rv /path で既定ラベルに戻す。恒久化は semanage fcontext -a -t httpd_sys_content_t '/srv/web(/.*)?' の後に restorecon。

一時的には `restorecon -Rv /path` で既定のラベルに戻す。恒久的にそのパスを特定用途として扱わせたいときは `semanage fcontext -a -t httpd_sys_content_t '/srv/web(/.*)?'` のようにルールを追加してから restorecon を当てる。

コツ機能のオンオフは「ブール値」で。getsebool -a で一覧、setsebool -P httpd_can_network_connect on で恒久的に有効化。

また、特定機能のオン・オフを切り替える「ブール値」という仕組みもある。`getsebool -a` で一覧でき、`setsebool -P httpd_can_network_connect on` のように -P 付きで恒久的に有効化できる。

違反の記録は /var/log/audit/audit.log に残る。`ausearch -m avc` や sealert で「何が拒否され、どう直せばよいか」のヒントを読み取れる。

これらの正攻法を覚えておくと、SELinux を有効に保ったまま問題を解決できる。

つまり、現場の勘どころは一言で言い表せる。

🛠 実務の使いどころ

実務での勘どころは、「SELinux を切らずに付き合う」ことに尽きる。

Enforcing のまま運用し、何か拒否されたら、まずログを見てラベルやブール値で正す。この習慣が、いざ攻撃を受けたときの最後の砦を残す。

新しいソフトを既定と違う場所に入れたときや、サービスのポートを変えたときは、SELinux 視点でのラベル設定が要ると意識しておく。そうすると原因究明が速くなる。

どうしても切り分けが必要なときだけ一時的に Permissive にして観察し、終わったら Enforcing へ戻す。

💡
ポイントMAC は通常のパーミッションを置き換えず、その上に重ねる二段目の防御。両方を効かせて綻びの波及を防ぐ。

MAC は通常のパーミッションを置き換えるものではなく、その上に重ねる二段目の防御だ。両方を正しく効かせることで、ひとつのプロセスの綻びがシステム全体へ波及するのを防げる。

この項目に出てくる用語

SELinuxエスイーリナックス
ラベルとポリシーでプロセスの動きを強制的に制限するMACの仕組み。
AppArmorアップアーマー
プログラム単位のプロファイルで動作を制限する、Ubuntu系のMAC。
最小権限さいしょうけんげん
必要な人に必要な分だけ権限を与え、それ以外は与えない設計原則。

関連コマンド

getenforcesetenforce

▶ 学習アプリでこの続きを学ぶ・演習する