Linuxサーバー環境(RHEL, AlmaLinux, Rocky Linux, CentOSなど)でWebサーバーや各種サービスを構築している際、chmod 777 や chown でパーミッションを正しく設定したにもかかわらず、「Permission denied」エラーが発生したり、Webページで 500 Internal Server Error が出る原因の多くは SELinux(Security-Enhanced Linux) にあります。
SELinuxはLinuxのセキュリティを飛躍的に高める強力なアクセス制御機能ですが、仕組みや確認方法を知らないと「トラブル時にとりあえず無効化してしまう」という運用になりがちです。しかし本番環境での無効化は大きなセキュリティリスクを伴います。
この記事では、SELinuxの基本的な仕組み(MAC機能)をはじめ、getenforce や sestatus を使った状態確認、一時的・恒久的な動作モード切り替え手順、そして拒否ログの調査から適切なパーミッション復旧手順(ls -Z, restorecon, setsebool)まで分かりやすく解説します。
1. SELinux(Security-Enhanced Linux)とは?基本と役割
SELinux(Security-Enhanced Linux) は、アメリカ国家安全保障局(NSA)とLinuxコミュニティによって開発されたLinuxカーネル向けの高度なセキュリティ拡張機能です。
伝統的なアクセス制御(DAC)とSELinux(MAC)の違い
従来のLinuxセキュリティは任意アクセス制御(DAC: Discretionary Access Control)に基づいています。DACでは、ファイルの所有者(ユーザー)やグループ、およびパーミッション(rwx)によってアクセス権が決定されます。そのため、もし root 権限を持つプロセスが乗っ取られた場合、システム内のあらゆるファイルにアクセスされてしまう脆弱性がありました。
一方、SELinuxが提供するのは強制アクセス制御(MAC: Mandatory Access Control)です。MACでは、ユーザー権限や root 権限の有無に関わらず、システム管理者があらかじめ定めた「セキュリティポリシー」に従って、プロセスが実行できる操作やアクセスできるファイルを厳格に制御します。
| 項目 | 任意アクセス制御(DAC) | 強制アクセス制御(MAC / SELinux) |
|---|---|---|
| 判定基準 | ユーザーID・グループID・ファイル権限(rwx) | セキュリティラベル(コンテキスト)とポリシールール |
| アクセス制御の主体 | ファイルの所有者(変更自由) | システム管理者・カーネルポリシー(変更制限あり) |
| root権限奪取時 | システム全体のファイルにアクセス可能 | 権限奪取されたプロセスに割り当てられた領域のみに制限 |
セキュリティラベル(コンテキスト)による保護の仕組み
SELinuxでは、システム上のすべての「プロセス(主体)」と「ファイル/ディレクトリ/ポート(対象)」にセキュリティコンテキスト(ラベル)というタグが付与されます。
コンテキストは ユーザー:ロール:タイプ:レベル という形式(例: system_u:object_r:httpd_sys_content_t:s0)で構成されており、特に重要なのが「タイプ(Type)」です。SELinuxは「このタイプを持つプロセスは、どのタイプを持つファイルに何をして良いか」を判定します(これを タイプコンテキスト / Type Enforcement と呼びます)。
例えば、ApacheやNginxなどのWebサーバープロセス(httpd_t)が、一般ユーザーのホームディレクトリエリア(user_home_t)を開こうとすると、たとえファイルパーミッションが 777 であってもSELinuxによってアクセスが拒否されます。
2. SELinuxの3つの動作モード(Enforcing / Permissive / Disabled)
SELinuxには以下の3つの動作モードが存在します。サーバー構築時やトラブルシューティング時には、今どのモードで動作しているかを正しく把握することが極めて重要です。
動作モードの種類と特徴
- Enforcing(有効・拒否モード): SELinuxが完全に有効化されている状態です。セキュリティポリシーに違反するすべてのアクセスをブロック(遮断)し、拒否ログを記録します。本番環境での推奨モードです。
- Permissive(有効・警告モード): SELinuxは動作していますが、違反アクセスをブロックしません。代わりに「アクセス拒否されるはずだった操作」をログ(audit.log)にのみ記録します。トラブルシューティングや設定検証時に活用されます。
- Disabled(無効化モード): SELinuxの機能自体が完全に停止している状態です。アクセスの保護も拒否ログの記録も行われません。モード変更にはOSの再起動が必要です。
| 動作モード | アクセス遮断 | 拒否ログの記録 | 切り替え時のOS再起動 | 主な用途 |
|---|---|---|---|---|
| Enforcing | あり(ブロックする) | あり | 不要(Permissive間) | 本番環境の標準運用 |
| Permissive | なし(許可する) | あり | 不要(Enforcing間) | トラブル原因特定・検証 |
| Disabled | なし | なし | 必要 | 非推奨(検証・開発用) |
3. SELinuxの現在の状態を確認するコマンド
サーバー上でSELinuxが有効になっているか、どのモードで動いているかを確認するには主に2つのコマンドを使用します。
getenforce コマンド(簡易確認)
現在の動作モードを一行で確認したい場合は getenforce を使用します。
$ getenforce
Enforcing
出力結果は Enforcing、Permissive、Disabled のいずれかになります。
sestatus コマンド(詳細確認)
設定ファイル上のモードやポリシー名など、より詳しい情報を確認したい場合は sestatus(SELinux Status)コマンドを実行します。
$ sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Memory protection checking: actual (secure)
Max kernel policy version: 33
主要なチェックポイントは以下の通りです。
- SELinux status:
enabled(有効)かdisabled(無効)か - Current mode: メモリ上で現在リアルタイムに動作しているモード(
enforcingまたはpermissive) - Mode from config file: 設定ファイル(
/etc/selinux/config)で指定されている次回起動時のデフォルトモード - Loaded policy name: 適用中のポリシー名(標準は
targeted)
4. SELinuxの動作モードを変更・切り替える手順
SELinuxのモード変更には、「一時的な変更(再起動なし・再起動で元に戻る)」 と 「恒久的な変更(設定ファイルの編集)」 の2種類があります。
【一時的】setenforce コマンドで変更する
Webサーバーやスクリプトが動かない原因がSELinuxにあるかどうかを確認したい場合は、setenforce コマンドで一時的に Permissive へ変更します。OSの再起動は不要で、即座に反映されます。
Permissive(警告モード)に変更する:
sudo setenforce 0
# または
sudo setenforce Permissive
Enforcing(有効モード)に戻す:
sudo setenforce 1
# または
sudo setenforce Enforcing
※ setenforce による変更はメモリ上のみの設定です。サーバーを再起動すると設定ファイルの内容に戻ります。また、Disabled から Enforcing へ直接切り替えることはできません。
【恒久的】/etc/selinux/config を編集して変更する
OS再起動後もモードを維持したい場合は、設定ファイル /etc/selinux/config を編集します。
sudo vi /etc/selinux/config
ファイル内の SELINUX= の値を変更します。
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=permissive
設定を保存した後、サーバーを再起動することで恒久的に反映されます。
sudo reboot
注意(RHEL 9 / AlmaLinux 9 / Rocky Linux 9 以降): RHEL 9系以降のOSでは、/etc/selinux/config で SELINUX=disabled を指定する運用は非推奨化されており、カーネルパラメータ(selinux=0)での無効化が必要になる場合があります。実務では SELINUX=disabled ではなく SELINUX=permissive での運用が推奨されます。
Disabled から Enforcing に戻す際の注意点(自動リラベル)
SELinuxを `Disabled` にしていた期間中に作成・更新されたファイルには、正しいセキュリティコンテキスト(ラベル)が付与されていません。
そのまま設定ファイルを `SELINUX=enforcing` に書き換えて再起動すると、システムファイルや設定ファイルのラベル不整合によりOSが起動しなくなったり、サービスが一切起動しなくなる重大なトラブルが発生します。
Disabled から無事に有効化(Enforcing / Permissive)に戻すためには、再起動前に以下のコマンドを実行して「次回起動時の全ファイル再ラベル付け(autorelabel)」を指示してください。
sudo touch /.autorelabel
sudo reboot
再起動時の初回ブート中にストレージ全体のラベル付け処理が自動実行され、適切なコンテキストが再割り当てされます(ファイル数によっては数分程度時間がかかります)。
5. SELinuxでブロックされた場合の確認と正しいトラブル対処法
「パーミッションは755/644で正しいのにWebサーバーで403 Forbiddenや500 Errorが出る」「SSHのポート番号を変更したら起動しない」といったトラブルが発生した際、SELinuxを安全に解消する4ステップの切り分け手順を解説します。
ステップ1:SELinuxが原因か一時的にテストする
まず sudo setenforce 0 を実行して Permissive に切り替え、エラーが発生していた操作(Webページ閲覧やサービスの起動など)を再実行します。
- Permissiveで正常に動作した場合: 原因は100% SELinuxのポリシー・ラベル違反です。
- Permissiveでもエラーが変わらない場合: 原因は通常のパーミッション(chmod/chown)、設定ファイルの構文エラー、マウント権限などSELinux以外の場所にあります。
ステップ2:アクセス拒否ログ(audit.log)を確認する
SELinuxがブロックした操作は、/var/log/audit/audit.log に type=AVC(Access Vector Cache)ログとして記録されます。
sudo grep "AVC" /var/log/audit/audit.log
# または journalctl を利用
sudo journalctl -u auditd | grep "denied"
ログの出力例:
type=AVC msg=audit(1672531199.123:456): avc: denied { read } for pid=2345 comm="httpd" name="index.html" dev="sda1" ino=98765 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0
ログから読み解くべき情報は以下の2点です。
- scontext(送信元コンテキスト): 動作を行おうとしたプロセス(例:
httpd_t=Webサーバー) - tcontext(対象コンテキスト): アクセスされたファイルやポート(例:
user_home_t=ユーザーホームディレクトリ内のファイル)
Webサーバープロセス(httpd_t)がホームディレクトリタイプ(user_home_t)のファイルを読もうとして拒否(denied)されたことが明確に判明します。
ステップ3:コンテキスト(ラベル)の確認と修正
ファイルのセキュリティコンテキストを確認するには、ls -Z コマンドを使用します。
ls -Z /var/www/html/index.html
unconfined_u:object_r:user_home_t:s0 /var/www/html/index.html
本来Webコンテンツとして公開すべきファイルのタイプは httpd_sys_content_t である必要がありますが、user_home_t になっているためブロックされています。
① 一時的なコンテキスト変更(chcon):
sudo chcon -t httpd_sys_content_t /var/www/html/index.html
※ chcon は手軽ですが、後述の restorecon 実行時やパッケージ更新時にデフォルト設定へ戻ってしまうため、一時的なテスト用途にとどめます。
② 恒久的なコンテキスト変更(semanage fcontext + restorecon):
ディレクトリ配下のデフォルトポリシーを登録し、それを適用するのが正しい恒久対処法です。
# 1. ポリシーにコンテキスト定義を追加
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"
# 2. 定義されたコンテキストを実際のファイル群に再適用
sudo restorecon -Rv /var/www/html
ステップ4:Boolean(ブール値)フラグの調整
コンテキストが正しくても、「Webサーバーから外部のデータベースやネットワークAPIに接続できない」「Webサーバーからメール送信できない」といった場合は、SELinuxの Boolean(スイッチ機能) がオフになっていることが原因です。
Booleanの設定一覧を確認する:
getsebool -a | grep httpd
例:Webサーバー(httpd)からのネットワーク接続を許可する:
# 一時的にON
sudo setsebool httpd_can_network_connect on
# 恒久的にON(-P オプションで再起動後も保持)
sudo setsebool -P httpd_can_network_connect on
このように、SELinuxを無効化しなくても適切なコンテキスト修正やBooleanのON化によって安全にトラブルを解決できます。
6. SELinuxに関するよくある質問(FAQ)
Q1. トラブルが起きたらとりあえず「Disabled」に無効化しても問題ないですか?
A. 本番環境での無効化は避けるべきです。
無効化(Disabled)にするとWebアプリケーション等の脆弱性を突かれた際にサーバー全体を占有される危険性が激増します。トラブル調査時は無効化するのではなく sudo setenforce 0 で Permissive モードにしてログを分析し、コンテキストやBooleanを修正して Enforcing で運用するのがセキュリティベストプラプラクティスです。
Q2. UbuntuやDebianでもSELinuxは使われていますか?
A. デフォルトでは使用されていません。
UbuntuやDebianなどのDebian系ディストリビューションでは、SELinuxではなく AppArmor という別のMAC機能が標準で導入されています。SELinuxは主に RHEL(Red Hat Enterprise Linux)、CentOS、AlmaLinux、Rocky Linux、Fedora などの Red Hat 系ディストリビューションで標準採用されています。
Q3. SSHのポート番号を変更したらログインできなくなりました。これもSELinuxの影響ですか?
A. SELinuxの影響である可能性が非常に高いです。
SELinuxではSSHサービス(sshd)が待機できるポート番号がデフォルトで 22 番(ssh_port_t)に限定されています。SSHポートを例えば 2222 番に変更した場合、ファイアウォールの許可だけでなく、SELinux側にもポート定義を追加する必要があります。
# SELinuxに新規SSHポートを追加許可
sudo semanage port -a -t ssh_port_t -p tcp 2222
7. まとめ:適切なSELinux運用で安全なLinuxサーバーを構築しよう
SELinuxは一見複雑でトラブルの元に見えますが、基本的なコマンドと動作モードを理解すれば非常に強力な防壁となります。
最後に、日常の運用でよく使うSELinuxコマンドの早見表をまとめます。
| 用途・目的 | 実行コマンド |
|---|---|
| 現在のモード確認 | getenforce |
| 詳細ステータス確認 | sestatus |
| 一時的に警告モードへ変更 | sudo setenforce 0 |
| 一時的に有効モードへ復帰 | sudo setenforce 1 |
| ファイルのセキュリティラベル確認 | ls -Z <ファイルパス> |
| コンテキストの恒久初期化・復元 | sudo restorecon -Rv <ディレクトリパス> |
| アクセス拒否ログの検索 | sudo grep "AVC" /var/log/audit/audit.log |
| Boolean設定の恒久変更 | sudo setsebool -P <項目名> on |
Linuxサーバーの権限管理やトラブルシューティングに関する詳細は、以下の関連記事もぜひあわせて参考にしてください。

コメント