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 であっても許さない。
RHEL/MiracleLinux系ではこの仕組みとして SELinux(selinux)が、Ubuntu系では AppArmor(apparmor)が採用されている。
同じ MAC でも、この2つはアプローチが異なる。
⚖ SELinux と AppArmor のアプローチの違い
SELinux は、ファイル・プロセス・ポートといったあらゆる対象に「ラベル(コンテキスト)」を付ける。そして、どのラベルのプロセスがどのラベルの対象にアクセスしてよいかをポリシーで厳密に定義する方式だ。
きめ細かく強力なぶん、概念はやや難しめになる。
一方 AppArmor は、プログラムごとに「このアプリはこのパスのファイルだけ触ってよい」というパス基準のプロファイルで縛る方式だ。相対的に分かりやすいとされる。
どちらも狙いは同じだ。「万一あるプロセスが乗っ取られても、そのプロセスがあらかじめ許された範囲しか行動できないようにし、被害の拡大を封じ込める」こと。
これは最小権限の原則を、ユーザ単位ではなくプロセスの振る舞い単位で徹底するもの、と捉えると腑に落ちる。
本トラックが前提とする RHEL/MiracleLinux系では SELinux が標準なので、以降は SELinux を中心に説明する。
では、その SELinux が今どう動いているかを、どこで確かめればよいのか。
🚦 状態を確認する getenforce と3つのモード
SELinux には3つの動作モードがある。
Enforcing(強制)はポリシー違反を実際にブロックする本番モードだ。Permissive(警告のみ)は違反をブロックせずログにだけ記録する観察モード。Disabled(無効)は SELinux 自体を止める状態だ。
現在どのモードかは `getenforce` を実行すると Enforcing のように一語で返る。
より詳しい情報は `sestatus` で得られる。現在のモードと設定ファイル上のモード、ポリシーの種類などをまとめて確認できる。
RHEL/MiracleLinux系では既定で Enforcing になっており、これがセキュリティ上望ましい状態だ。
トラブルが起きると安易に Disabled にしてしまう人がいる。だがそれは家の鍵を壊して「開かない問題」を解決するようなもので、本来は避けるべき対処である。
とはいえ、切り分けのために一時的にモードを変えたい場面はある。そのとき何を使うのか。
🔄 モードを切り替える setenforce と恒久設定
モードの切り替えには `setenforce` を使う。`setenforce 0` で Permissive に、`setenforce 1` で Enforcing に、その場で切り替えられる。
ただしこの変更は一時的で、再起動すると元に戻る。
これがむしろ切り分け作業に便利だ。「ある操作が失敗するのは SELinux のせいか?」を確かめたいとき、一時的に Permissive にして同じ操作が通るなら、原因は SELinux にあると判断できる(確認後はすぐ Enforcing に戻す)。
恒久的にモードを変えたいときは設定ファイル /etc/selinux/config の SELINUX= 行を書き換える。
注意点として、Disabled と Enforcing/Permissive の間の切り替えは setenforce では行えず、config を編集して再起動する必要がある。
なお Disabled から復帰させると、ファイルのラベルが古くなっているため再ラベル付け(autorelabel)が走り、起動に時間がかかることがある。
ここで「ラベル」という言葉が出たが、初学者を最も悩ませるのが、まさにこのラベルにまつわる現象だ。
🏷 ラベルとブール値 — つまずきの正しい直し方
SELinux で初学者が最もつまずくのが、ファイルのラベル(コンテキスト)に起因する「なぜか動かない」現象だ。
たとえば Web の公開ファイルを既定の /var/www 以外の場所に置くと、SELinux 的にはラベルが合わずアクセスが拒否される。
これを「SELinux を切る」で解決するのは誤りだ。正しくはラベルを正す対処をする。
一時的には `restorecon -Rv /path` で既定のラベルに戻す。恒久的にそのパスを特定用途として扱わせたいときは `semanage fcontext -a -t httpd_sys_content_t '/srv/web(/.*)?'` のようにルールを追加してから restorecon を当てる。
また、特定機能のオン・オフを切り替える「ブール値」という仕組みもある。`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 は通常のパーミッションを置き換えるものではなく、その上に重ねる二段目の防御だ。両方を正しく効かせることで、ひとつのプロセスの綻びがシステム全体へ波及するのを防げる。