この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
この一言、私のセミナーで本当に何度聞いたか分かりません。
Webサーバーを立てたのにブラウザからアクセスが返ってこない、アプリをデプロイしたのに接続を拒否される、設定ファイルを何度見直しても問題がない。
途方に暮れて
/var/log/audit/audit.log を開くと、「avc: denied」の行が延々と続いている。分かります。その気持ち、痛いほど分かります。
私自身、SE時代に「SELinuxはとにかく無効にする」をチーム全員に口頭で引き継いできた人間ですから。
この記事では、SELinuxを「邪魔者」と決めつけて無効化し続けた私の失敗談と、20年以上サーバーを運用してきた経験から気づいた「setenforce 0 に頼らない実務の作法」を、実際のコマンドとともに正直に話します。
この記事のポイント
・SELinuxをdisabledにすると、OS標準のセキュリティ層が丸ごと消える
・トラブル特定の基本は getenforce / sestatus / audit2why の3コマンド
・permissiveモードで調査してから setsebool や restorecon で正規対処する
・無効化より「コンテキスト付与」で解決できる事例が現場では大半を占める
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
SELinuxが「邪魔者」に見えてしまう理由
SELinux(Security-Enhanced Linux)は、Linuxカーネルに組み込まれた強制アクセス制御(MAC: Mandatory Access Control)の仕組みです。私たちがよく使う chmod や chown によるパーミッション管理(DAC: Discretionary Access Control)とは別のレイヤーで動作し、プロセスが「どのファイル・ポートにアクセスできるか」をポリシーで厳密に制御します。
初学者にとってSELinuxが「邪魔者」に見える最大の理由は、「設定が正しいのに動かない」という体験にあります。
パーミッションは755に設定済み、ファイルの所有者も正しい、ポートも開放している。それでも403 Forbiddenが返ってくる、サービスが起動しない。
「何が悪いのか分からない」という状態で
setenforce 0 と打ち込んだら動いた。この成功体験が積み重なり、「とりあえず無効にする」が習慣化するのです。
SELinuxは確かに挙動が独特で、慣れるまで直感に反する部分があります。
ですが「邪魔」なのではなく、「向き合い方を知らないから邪魔に感じる」だけです。
この違いに気づくまでに、私は3年以上かかりました。
SE時代にsetenforce 0で逃げ続けた頃の話
私がSEとして働いていたのは2001年から2006年にかけてのことです。SELinuxがRHELに本格搭載されたのはRHEL 4(2005年2月リリース)からでした。
それまでシンプルな chmod / chown だけで権限管理をしてきた私には、SELinuxの「タイプ強制」という概念が全くピンと来ませんでした。
1. アプリが動かない → 「とりあえずpermissiveに」
当時、私のチームに「SELinuxの専門家」は誰もいませんでした。新しいサーバーを構築してApacheを動かすと、コンテンツが表示されない。
/var/www/html にはファイルがある、httpd.conf の設定も正しい。それでも403 Forbiddenが返ってくる。先輩に聞くと「SELinuxが弾いてるんだろ、setenforce 0しとけ」と一言。
打ち込んだら即座に解決。これが私の「SELinux問題の解法」として定着してしまいました。
「なぜ弾かれたのか」を理解しないまま解決してしまう。
現場では「動いた」が全てです。原因究明に時間をかける余裕はありませんでした。
この習慣が、私を3年間SELinuxから遠ざけ続けました。
2. 「本番でも問題ない」を積み重ねた慢心
最初は開発・検証環境だけと思っていたSELinux無効化が、気づけば本番サーバーにも適用されていました。「今まで一度もSELinuxが原因で事故が起きていない」という実績が慢心を生んでいたのです。
これは私が現場でよく見かけるパターンでもあります。
「SELinux無効のまま3年間運用しているが何も問題ない」という話はよく聞きます。
ですがこれは「問題が起きていない」のではなく、「攻撃を受けたときに被害が拡大しやすい状態」が続いているだけかもしれません。
SELinuxのありがたさは、実害が出て初めて気づくものです。
3. 転機になった上司の一言
私が考え方を変えたのは2005年の秋、チームリーダーからの指摘がきっかけでした。構築手順書のレビュー中に「この手順、SELinux無効にしてるけど、セキュリティ要件通ってる?」と聞かれたのです。
そのとき私には答えられませんでした。
「動くから無効にした」以上の理由を持っていなかったのです。
そこから初めて、SELinuxのAVCログを真剣に読み始めることになりました。
SELinuxを無効にしてはいけない理由
SELinuxを disabled にすることのリスクは、大きく3つあります。・DACでは防げない攻撃の「封じ込め」ができなくなる:
SELinuxはアプリケーションが乗っ取られた際に「どこまで被害を広げさせるか」を制限します。
Apacheが攻撃を受けても、SELinuxが有効であれば、Apacheプロセスは
/var/www/html 以外のファイルには基本的に触れられません。無効化はこの「封じ込め」を丸ごと取り除くことを意味します。
・RHEL / Rocky Linux の標準をわざわざ壊すことになる:
RHELの標準設定はenforcing(強制モード)です。
セキュリティコンプライアンス(DISA STIG・CIS Benchmark等)ではSELinux有効が前提条件になっています。
無効化はコンプライアンス違反に直結し、監査で指摘される事項になります。
・再有効化のコストが非常に高い:
一度 disabled にしたサーバーを再び enforcing にするには、ファイルシステム全体のSELinuxコンテキスト(ラベル)を再付与する必要があります。
本番サーバーではこの作業が大きなダウンタイムリスクになります。
最初から無効にしないことの方が、長期的にはずっとコストが低いのです。
SELinuxのエラーで「動かない」が起きた時の対処手順
「avc: denied」が出た時の対処は、手順さえ知っていれば怖くありません。私が現場の実務で実際に使っている対処手順を順番に紹介します。
1. SELinuxの現在のモードを確認する
SELinuxには3つのモードがあります。・enforcing:ポリシー違反を検出して拒否する(本番での通常運用モード)
・permissive:ポリシー違反を検出するが許可する(原因調査に使うモード)
・disabled:SELinux機能を無効にする(再有効化には再起動が必要)
まずは
getenforce と sestatus で現状を確認しましょう。# getenforce Enforcing # sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinuxfs version: 33 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
「Mode from config file: enforcing」は
/etc/selinux/config の設定値で、これがサーバー再起動後も使われます。2. audit.logからSELinuxのエラーを読む
SELinuxが何かをブロックしたときは、必ず/var/log/audit/audit.log に記録されます。ログをそのまま読むのは難しいですが、
audit2why コマンドを使うと人間が読める形に変換できます。なお、
audit2why と audit2allow は policycoreutils-python-utils パッケージに含まれています。Rocky Linux 9 / RHEL 9 では
dnf install policycoreutils-python-utils でインストールできます。# audit2why < /var/log/audit/audit.log type=AVC msg=audit(1726123456.789:1234): avc: denied { read } for pid=12345 comm="httpd" name="index.php" dev="sda1" ino=67890 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file permissive=0 Was caused by: Missing type enforcement (TE) allow rule. You can use audit2allow to generate a loadable module to allow this access. # ausearch -m avc -ts recent type=AVC msg=audit(1726123789.000:5678): avc: denied { name_connect } for pid=23456 comm="httpd" dest=3306 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:mysqld_port_t:s0 tclass=tcp_socket permissive=0 # setsebool -P httpd_can_network_connect_db on # semanage fcontext -a -t httpd_sys_content_t "/opt/myapp(/.*)?" # restorecon -Rv /opt/myapp Relabeled /opt/myapp from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
1件目は「Apacheが
default_t タイプのファイルを読もうとして拒否された」ケースです。default_t はSELinuxコンテキストが適切に設定されていないファイルに付くタイプで、semanage fcontext と restorecon で正しいタイプを付与することで解決できます。2件目は「ApacheがMySQLのポート(3306番)に接続しようとして拒否された」ケースです。
これは
setsebool -P httpd_can_network_connect_db on というブール値の変更で解決します。【重要】permissiveへの切り替えは一時的な調査手段として使う
setenforce 0 でpermissiveに切り替えると、SELinuxはブロックせずにログだけ記録するようになります。これは「何を拒否されているか」を洗い出すための調査手段であり、本番での恒久設定ではありません。
調査が終わったら必ず
setenforce 1 でenforcingに戻し、正規の設定変更で解決することが鉄則です。SELinuxを味方にする実務3ステップ
SELinuxのトラブルに直面したとき、私が現在も実践している3ステップを紹介します。この手順を身につければ、「とりあえず無効化」という選択肢を取らなくて済むようになります。
ステップ1:permissiveモードで「何が弾かれているか」を全部洗い出す
まずsetenforce 0 でpermissiveに切り替え、アプリを起動して実際の操作を再現します。この間SELinuxはブロックせずにAVCログだけ記録するので、全ての「必要な権限」が洗い出せます。
・
setenforce 0 でpermissiveに切り替える(再起動なしで即時反映)・アプリを再起動し、本番同等のユーザー操作を再現する
・
ausearch -m avc -ts recent で直近のAVCログを確認する・必要な権限が全て洗い出せたら
setenforce 1 でenforcingに戻すステップ2:audit2whyで「どう解決するか」を特定する
audit2why の出力が「The boolean httpd_can_network_connect was false」のようなメッセージの場合、setsebool コマンドで既存のSELinuxブール値をtrueに切り替えるだけで解決します。SELinuxには数百のブール値があり、
「ApacheがDBに接続する」「Apacheがネットワーク越しにCGIと話す」
といった典型的なユースケースのほとんどはブール値の変更だけで対応できます。
getsebool -a | grep httpd でApache関連のブール値一覧が確認できます。ステップ3:独自パスのコンテンツはsemanage + restoreconで解決する
RHELの標準パス(/var/www/html など)以外に置いたファイルは、SELinuxコンテキストが正しく付与されていないことがあります。この場合、
semanage fcontext でそのパスに正しいタイプを定義し、restorecon -Rv パス で再ラベル付けすることで解決します。この設定はリブート後も永続します。
20年以上の運用経験から言うと、SELinuxトラブルの大半はこの3ステップで片付きます。
permissiveで調査 → audit2whyで原因特定 → setsebool / semanage / restorecon で解決。
この流れを一度体験すれば、「とりあえず無効化」という選択肢が消えていきます。
まとめ
SELinuxは「邪魔者」ではありません。向き合う手順を知らないから「邪魔に見える」のです。
私がSE時代に3年間逃げ続けた理由は、ただひとつ「どうすれば無効にせずに解決できるか」を知らなかったからです。
audit.logを読む方法と、setsebool / semanage / restorecon の3コマンドを知っていれば、SELinuxトラブルの大半は解決できます。
Linuxサーバーのネットワーク到達性とSELinuxを切り分けるには、ポートの状態確認と組み合わせると効率が上がります。
・Linuxのポート確認(ssコマンド・lsofコマンド)と合わせて確認することで、SELinuxかネットワーク設定かの切り分けが早くなります。
・サービスの起動・停止の操作についてはsystemctlコマンドの使い方も参照してください。
| やりたいこと | コマンド |
|---|---|
| SELinuxモードを確認する | getenforce |
| SELinuxの詳細状態を確認する | sestatus |
| 一時的にpermissiveに切り替える(再起動なし) | setenforce 0 |
| enforcingに戻す(再起動なし) | setenforce 1 |
| AVCエラーを人間が読める形で確認する | audit2why < /var/log/audit/audit.log |
| 直近のAVCエラーを検索する | ausearch -m avc -ts recent |
| SELinuxブール値を永続的に変更する | setsebool -P httpd_can_network_connect on |
| 独自パスにSELinuxコンテキストを付与する | semanage fcontext -a -t httpd_sys_content_t "/opt/app(/.*)?" |
| SELinuxコンテキストを再付与する | restorecon -Rv /opt/app |
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、
SELinuxの設定から権限管理、ネットワーク設計まで、現役講師が20年の運用経験をもとに体系的に解説するハンズオンセミナーを開催しています。
「なぜそうするのか」の理由まで理解できるカリキュラムで、現場で即戦力になるスキルを身につけましょう。
>> Linux Master Pro Seminar の詳細はこちら
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:Linuxでipコマンドで設定したネットワークが再起動後に消えた日の話|ifconfigからnmcliへの移行で変わった設定の型
- この記事の属するカテゴリ:Linux学習ガイドへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます