audit2allowコマンドでSELinuxの拒否エラーを解消する方法|カスタムポリシーモジュールの作成手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtips, セキュリティ > audit2allowコマンドでSELinuxの拒否エラーを解消する方法|カスタムポリシーモジュールの作成手順
「Nginxをインストールして起動しようとしたら Permission denied が出て動かない」「cronで動かしているスクリプトが突然失敗するようになった。ログを見ると avc: denied という見慣れないエラーが出ている」

SELinuxをEnforcingモードで運用するサーバーでは、こうした拒否エラーは日常的に発生します。真っ先に思いつく対処は「setenforce 0 でSELinuxを無効化する」ですが、それではせっかくの強制アクセス制御が無駄になります。パッケージアップデートのタイミングで再度 Enforcing に戻った瞬間、また同じ問題が繰り返されます。

この記事では、audit2allowコマンドを使ってSELinuxのAVC拒否エラーを正しく解消する方法を、実機の出力例を交えて解説します。auditログからカスタムポリシーモジュールを生成してsemoduleで適用するまでの一連の手順を体系的にまとめます。

実行環境:Rocky Linux 9.4 / RHEL 9.4 で動作確認済み

この記事のポイント

・audit2allow -M でAVCログからポリシーモジュールを生成する
・semodule -i mymod.pp の1コマンドでポリシーを即座に反映できる
・適用前に .te ファイルを確認して最小権限を守ること
・全ログを無差別に渡すと別プロセスの権限が混入するリスクがある


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜSELinuxが「Permission denied」を起こすのか

SELinux(Security-Enhanced Linux)はLinuxカーネルに組み込まれた強制アクセス制御(MAC)機能です。通常のUNIXパーミッション(chmodで設定するDAC)とは独立して動作し、「どのプロセスが、どのファイルやポートに、どの操作をできるか」を細かく制限します。

この制限を実現するのがSELinuxポリシーです。ポリシーに書かれていないアクセスはすべて拒否され、その記録が /var/log/audit/audit.logAVC(Access Vector Cache)拒否ログとして書き込まれます。

つまり、audit.log の AVC denied メッセージは「不正アクセスの証拠」ではなく、「ポリシーで想定されていない正当なアクセスが拒否されている」という意味であるケースがほとんどです。audit2allowはこのAVCログを解析し、必要最小限の許可ルールを自動生成してくれるツールです。

セキュリティの観点から見ると、audit2allowで作成したカスタムポリシーは「SELinuxを壊さずに特定の操作だけ追加で許可する」アプローチです。setenforce 0(無効化)や permissive モードへの変更とは根本的に異なります。

audit2allowを使う前の準備

1. SELinuxの状態と必要ツールを確認する

まず現在のSELinuxの動作モードを確認します。

# SELinuxの動作モードを確認 getenforce sestatus

実際のサーバー出力例:

[root@web01 ~]# getenforce Enforcing [root@web01 ~]# sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux mode from config file: enforcing Policy MLS status: enabled Policy deny_unknown status: allowed Max kernel policy version: 33

次に audit2allow が使えるか確認します。RHEL 9 / Rocky Linux 9 では policycoreutils-python-utils パッケージに含まれています。

# audit2allowが使えるか確認 which audit2allow # 入っていない場合はインストール(Rocky Linux 9 / RHEL 9) dnf install -y policycoreutils-python-utils

2. AVCログを絞り込む(ausearch・grep)

audit2allowを使う前に、対象のAVCログを正確に絞り込むことが重要です。全ログを無差別に渡すと、関係ないプロセスの操作まで許可してしまうリスクがあります。

ausearchコマンドを使うと、プロセス名・時間帯・メッセージタイプを指定して絞り込めます。

# 最近のAVC拒否ログを抽出(-ts recent = 直近10分) ausearch -m AVC -ts recent # 特定プロセス(nginx)のAVC拒否ログを本日分だけ抽出 ausearch -m AVC -c nginx -ts today # 日時を指定して絞り込む(例:今日の10:00以降) ausearch -m AVC -ts 10:00 # grepで絞り込む場合(ausearchが使えない環境向け) grep "AVC" /var/log/audit/audit.log | grep 'comm="nginx"'

ausearchの出力に何も出てこない場合は、auditdサービスが停止していないか確認してください(systemctl status auditd)。

audit2allowでポリシーモジュールを作成する

1. ausearch | audit2allow -M でモジュールを生成する

ausearchで絞り込んだAVCログをパイプでaudit2allowに渡し、ポリシーモジュールを生成します。

# Nginx用のカスタムポリシーモジュールを生成 ausearch -m AVC -c nginx -ts today | audit2allow -M mynginx

実行すると、カレントディレクトリに2つのファイルが生成されます。

mynginx.te:人間が読めるポリシーソース(Type Enforcement)
mynginx.pp:コンパイル済みポリシーパッケージ(semoduleで適用するファイル)

2. .te ファイルで何を許可するか確認する

semodule -i を実行する前に、必ず .te ファイルの内容を確認してください。意図しないプロセスへの許可が含まれていないかチェックします。

# 生成されたポリシーの内容を確認 cat mynginx.te

実際のサーバー出力例(Nginxが /var 配下のカスタムパスを読もうとして拒否されたケース):

module mynginx 1.0; require { type httpd_t; type var_t; class file { open read getattr }; } #============= httpd_t ============== allow httpd_t var_t:file { open read getattr };

このテキストが読めれば、「httpd_t(NginxやApacheが動くSELinuxドメイン)が var_t(/var 配下のデフォルトコンテキスト)のファイルに対して read・open・getattr の操作を許可する」というルールだとわかります。

確認のポイントは次の2点です。

・想定外のドメイン(unconfined_t など)が含まれていないか
・許可している操作クラスが過剰でないか(executewrite が意図せず含まれていないか)

3. semodule -i でポリシーを適用する

内容を確認したら .pp ファイルをシステムに適用します。

# ポリシーモジュールを適用 semodule -i mynginx.pp # 適用されたことを確認 semodule -l | grep mynginx

実際のサーバー出力例:

[root@web01 ~]# semodule -i mynginx.pp [root@web01 ~]# semodule -l | grep mynginx mynginx 1.0

ポリシー適用後にサービスを再起動し、ausearchで再確認します。

# サービス再起動 systemctl restart nginx # AVC拒否が解消されたか確認 ausearch -m AVC -c nginx -ts recent # 何も出力されなければ成功

よくあるパターン別の実践例

1. httpd(Apache・Nginx)がカスタムディレクトリを読めない場合

/var/www/html 以外のディレクトリ(例:/data/web)にドキュメントルートを設定したとき、httpdはそのディレクトリのSELinuxコンテキストが httpd_sys_content_t でないと読めません。

このケースでは、audit2allowよりも semanage fcontext + restorecon を使う方法が推奨です。コンテキストを正しく設定することで、拒否の根本原因を解消できます。

# 方法A:/data/web のSELinuxコンテキストを httpd_sys_content_t に変更(推奨) semanage fcontext -a -t httpd_sys_content_t "/data/web(/.*)?" restorecon -Rv /data/web # 方法B:audit2allowでカスタムポリシーを作る(複雑なケース向け) ausearch -m AVC -c httpd -ts today | audit2allow -M myhttpd cat myhttpd.te semodule -i myhttpd.pp

恒久的に /var/www 以外のパスを使う場合は方法A(semanage fcontext)が正解です。audit2allowは方法Aで対処できない複雑なアクセスパターンに使います。

2. カスタムサービスがネットワーク接続できない場合

SELinuxには「どのドメインがどのポートに接続できるか」のポリシーもあります。例えば、Nginxをリバースプロキシとして動かし、上流サービスの8080番ポートに接続しようとして拒否されるケースがよくあります。

このケースでは semanage port でポートのSELinuxタイプを設定する方法が優先です。

# 方法A:8080番ポートに http_port_t タイプを追加(推奨) semanage port -a -t http_port_t -p tcp 8080 # 現在定義されているポートのSELinuxタイプを確認 semanage port -l | grep http_port_t # 方法B:audit2allowでポリシーを作る場合 ausearch -m AVC -c nginx -ts today | audit2allow -M nginx_port cat nginx_port.te semodule -i nginx_port.pp

3. cronジョブがスクリプトを実行できない場合

/etc/cron.d/ 経由で実行するスクリプトが、SELinuxによって拒否されることがあります。特にスクリプトが /tmp/home 配下のファイルを操作したり、別のコマンドを呼び出したりするときに crond_t ドメインの制約に引っかかります。

# cron関連のAVC拒否ログを抽出 ausearch -m AVC -c crond -ts today ausearch -m AVC -c run-parts -ts today # ポリシーモジュールを生成・内容確認・適用 ausearch -m AVC -c crond -ts today | audit2allow -M mycron cat mycron.te semodule -i mycron.pp

cronジョブが複数の操作を行う場合、1回目の拒否を解消すると次の拒否が出ることがあります。しばらくジョブを走らせながら ausearch で繰り返し確認し、必要な許可をすべて積み上げていく作業が必要です。

audit2allowを使う際の3つの注意点

注意1:audit2allow -a(全ログ対象)は使わない
audit2allow -a は audit.log 全体を対象とするため、直近の全AVC拒否が混在します。関係ないプロセスへの許可も含まれてしまうため、必ず ausearch で絞り込んでからパイプで渡してください。

注意2:.te ファイルを必ず目視確認する
生成された .te ファイルには「allow ドメイン タイプ:クラス { 操作一覧 }」という形式でルールが記述されています。想定外のドメインや、過剰な操作クラス(executewrite など)が含まれていないか確認してから semodule -i を実行します。

注意3:カスタムモジュールの管理を記録しておく
適用したモジュール名は semodule -l で確認でき、不要になれば semodule -r モジュール名 で削除できます。誰が・いつ・何の目的でポリシーを追加したかを運用記録として残すことを習慣にしてください。サーバーを長期運用すると、誰が作ったかわからないカスタムポリシーが蓄積してしまいます。

# 適用済みカスタムモジュールの一覧確認 semodule -l # 不要なモジュールを削除 semodule -r mynginx

トラブルシュート(よくあるエラー)

1. ausearch で何も出力されない

auditdサービスが停止しているか、ログローテーションで古いログが削除されている可能性があります。

# auditdの状態確認 systemctl status auditd # auditdが停止していたら起動する systemctl start auditd systemctl enable auditd # ローテーション後のログも含めて検索する ausearch -m AVC -ts 2026-08-01 --input-logs

2. semodule -i が「Failed」で終わる

ディスクの空き容量不足か、SELinuxポリシーデータベースの不整合が原因のことが多いです。

# ディスク容量確認(/usr/share/selinux への書き込みが必要) df -h /usr # policycoreutils のバージョン確認 rpm -q policycoreutils policycoreutils-python-utils # SELinuxストアを再構築する(最終手段) semodule -B

3. ポリシー適用後もまだ Permission denied が出る

・適用したモジュールが正しくロードされているか semodule -l | grep モジュール名 で確認する
・サービスを再起動せずにファイルにアクセスしている場合はプロセスを再起動する
・auditログに別の avc: denied がないか再確認する(1つ解消すると次の拒否が出ることがある)
・SELinuxのコンテキストが変わっていないか ls -Z 対象ファイル で確認する

本記事のまとめ

audit2allowを使ってSELinuxの拒否エラーを解消する手順をまとめます。
やりたいこと コマンド
SELinuxの動作モードを確認 getenforce
AVC拒否ログを抽出(プロセス絞り込み) ausearch -m AVC -c nginx -ts today
ポリシーモジュールを生成 ausearch -m AVC -c nginx | audit2allow -M mynginx
生成内容の確認 cat mynginx.te
ポリシーを適用 semodule -i mynginx.pp
適用済みモジュールを確認 semodule -l
カスタムモジュールを削除 semodule -r mynginx
SELinuxを無効化せずに、必要な操作だけを許可する——これが現場のLinux管理者に求められる正しいアプローチです。audit2allowはそのための強力なツールですが、「絞り込んで生成し、内容を確認してから適用する」という手順を必ず守ってください。

SELinuxのポリシー管理をマスターしたら、次はLinuxサーバー全体のセキュリティ設計を体系的に固めませんか?

SELinuxをEnforcingモードで正しく運用できるエンジニアは、現場で確実に信頼されます。ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。