semanageコマンドでSELinuxのポリシーを管理する方法|fcontext・port・booleanの実践設定も

運営:リナックスマスター.JP(代表 宮崎智広)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > Linuxtips, セキュリティ > semanageコマンドでSELinuxのポリシーを管理する方法|fcontext・port・booleanの実践設定も
「SELinuxが邪魔でサービスが起動できない」「AVC deniedのエラーが消えない」
サーバー管理の現場でSELinuxを有効にしていると、こういった問題に頭を抱えることがあります。

ただ、SELinuxを無効化(disabled)してしまうのは最終手段です。
CIS BenchmarkをはじめとするRHEL系の多くのセキュリティ基準では、SELinuxをEnforcingのまま運用することが要件になっています。
正しいポリシー設定さえ覚えれば、SELinuxを有効にしたままサービスをスムーズに動かせます。
そのために必要なのが semanage コマンドです。

この記事では、semanageコマンドの基本的な使い方から、ファイルコンテキスト・ポート・Booleanの実践的な設定手順を解説します。
RHEL 9.4 / AlmaLinux 9 / Rocky Linux 9を想定しています。

この記事のポイント

・semanageはSELinuxポリシーを永続的に変更できる唯一のコマンド
・fcontext/port/booleanの3サブコマンドが現場で特に重要
・AVC deniedはaudit2allowで解析してから対処するのが鉄則
・chconは再起動で消えるため本番環境での使用は禁止
・semanage fcontextは「登録するだけ」でrestoreconで適用するのが2ステップの原則


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

semanageコマンドとは何か?

SELinuxは「ファイル・プロセス・ポート」すべてにセキュリティラベル(コンテキスト)を付けて、アクセス制御を行います。
このラベルのルールを「ポリシー」と呼びます。

semanage(SELinux Policy Management)は、このポリシーを永続的に管理するためのコマンドです。

SELinuxの設定は大きく3つの層に分かれています。

・モード管理:Enforcing / Permissive の切り替え(getenforce / setenforce / /etc/selinux/config)
・ファイルコンテキスト管理:ファイル・ディレクトリへのラベル付けルール(semanage fcontext + restorecon)
・ブール値管理:サービスの動作を許可・禁止するフラグ(semanage boolean / setsebool)

この記事では主に後者2つ、ファイルコンテキストとブール値の管理を中心に解説します。

よく似たコマンドに chcon がありますが、両者は根本的に異なります。
コマンド 変更の永続性 用途
chcon 一時的(restoreconで上書きされる) テスト・動作確認のみ
semanage 永続的(再起動後も維持) 本番環境での設定変更
本番サーバーで chcon だけ使ってコンテキストを変更した場合、restorecon -R / を実行した瞬間に変更が消えます。
必ずsemanageで永続化してから、restoreconで適用するという手順を守ってください。

インストールと事前確認

1. パッケージのインストール

RHEL系ではデフォルトで入っていない場合があります。

# semanageがインストールされているか確認 which semanage # インストールされていない場合 dnf install policycoreutils-python-utils

2. SELinuxの状態確認

# SELinuxの動作状態を確認 getenforce # Enforcing: 有効(アクセス拒否が実行される) # Permissive: 有効(ログのみ、拒否は実行されない) # Disabled: 無効 # 詳細な状態確認 sestatus

以下が実際のサーバーでの出力例です(ホスト名・ドメインは一部マスク)。

[root@web01.example.*** ~]# sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux mount point: /sys/fs/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

Loaded policy name: targeted が表示されていれば、一般的なRHEL環境のSELinux設定です。
なお、SELinuxをDisabledからPermissive/Enforcingへ変更するときは、コンテキスト未設定のファイルが多いとサービスが停止するリスクがあります。先にPermissiveにしてaudit.logで拒否ログを確認してから、Enforcingへ移行する段階的な手順を踏むのが安全です。

fcontext:ファイルコンテキストを管理する

SELinuxのファイルアクセス制御は「ファイルコンテキスト(セキュリティラベル)」で行います。
たとえばApacheがWebコンテンツを読めるのは、ファイルに httpd_sys_content_t というコンテキストが付いているからです。

1. 現在のコンテキストを確認する

# ファイルのコンテキストを確認(-Zオプション) ls -Z /var/www/html/ # 出力例(環境により異なります) # -rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html # ディレクトリのコンテキスト確認 ls -Zd /var/www/html/ # drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/

2. よく使うコンテキストタイプ一覧

Apacheまわりで頻繁に使うコンテキストをまとめます。スペルミスが多いので手元に控えておくと便利です。
コンテキストタイプ 用途
httpd_sys_content_t Apacheが読み取るWebコンテンツ(静的ファイル)
httpd_sys_rw_content_t Apacheが読み書きするコンテンツ(CGI書き込み先等)
httpd_sys_script_exec_t CGIスクリプトの実行ファイル
httpd_log_t Apacheのログファイル
httpd_config_t Apacheの設定ファイル
var_t コンテキスト未設定のデフォルト値(Apacheは読めない)

3. カスタムディレクトリにコンテキストを設定する

/data/web/ 以下にWebコンテンツを置きたい場合の手順です。

# Step1: semanageでポリシーを永続登録する # -a: 追加 -t: コンテキストタイプ semanage fcontext -a -t httpd_sys_content_t "/data/web(/.*)?" # Step2: restoreconでファイルに実際に適用する restorecon -Rv /data/web/ # 確認 ls -Z /data/web/

semanage fcontext の登録が「ルールの定義」で、restorecon が「ルールの適用」です。
semanage fcontextは「ポリシーデータベースに登録するだけ」です。restoreconを実行するまでファイルシステム上のラベルは変わりません。この2ステップを必ずセットで実行してください。

なお、restorecon の -v オプションを付けると変更されたファイルが表示されます。変更がなければ何も表示されないので、適用済みかどうかの確認にも使えます。

4. 登録済みのルールを確認・削除・修正する

# ローカルで追加したルールの一覧表示 semanage fcontext -l -C # 出力例(環境により異なります) # SELinux fcontext type Context # /data/web(/.*)? all files system_u:object_r:httpd_sys_content_t:s0 # ルールの削除 semanage fcontext -d "/data/web(/.*)?" # 既存ルールを変更する場合は -m(修正)を使う # -a(追加)を使うと「already defined」エラーになる semanage fcontext -m -t httpd_sys_rw_content_t "/data/web(/.*)?"

port:SELinuxのポート許可を管理する

Apacheのリスニングポートを8080に変更したら起動できなくなった、という問題はよくあります。
これはSELinuxが8080番を http_port_t として許可していないためです。

1. 許可されているポートを確認する

# HTTPサービスが使えるポート一覧を確認 semanage port -l | grep http_port_t # 出力例(環境により異なります) # http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000

8080番は含まれていないため、Apacheが8080でバインドしようとするとSELinuxに拒否されます。

SSHのデフォルトポート(22)を変更した場合も同様です。

# SSHが使えるポート一覧を確認 semanage port -l | grep ssh_port_t # 出力例(環境により異なります) # ssh_port_t tcp 22

2. ポートを追加する

# 8080番ポートをHTTPとして許可する semanage port -a -t http_port_t -p tcp 8080 # 追加後の確認 semanage port -l | grep http_port_t # http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8080, 8443, 9000 # SSHを2222番に変更する場合 semanage port -a -t ssh_port_t -p tcp 2222

3. ポートを削除する

# 追加したポートを削除する semanage port -d -t http_port_t -p tcp 8080 # 既存のデフォルトポートは削除不可(エラーになる)

Samba(445番)やPostfix(25番)などのサービスも同様の手順でポートを追加できます。
Linux ポート確認の全コマンドと組み合わせて、どのポートが必要かを先に把握しておくと効率的です。

boolean:サービスの挙動を切り替える

SELinux Booleanはポリシーの「フラグ」です。
Booleanを切り替えることで、ポリシーを書き換えずにサービスの特定の動作を許可・禁止できます。

1. Booleanの一覧と状態確認

# 全Booleanの一覧 semanage boolean -l # HTTPDに関連するBooleanのみ絞り込み semanage boolean -l | grep httpd # getseboolコマンドでも確認できる getsebool -a | grep httpd

実際のサーバー出力(一部抜粋・環境により異なります):

[root@web01.example.*** ~]# semanage boolean -l | grep httpd httpd_anon_write (off , off) Allow httpd to anon write httpd_builtin_scripting (on , on) Allow httpd to builtin scripting httpd_can_connect_ldap (off , off) Allow httpd to can connect ldap httpd_can_network_connect (off , off) Allow httpd to can network connect httpd_can_network_connect_db (off , off) Allow httpd to can network connect db httpd_can_sendmail (off , off) Allow httpd to can sendmail httpd_enable_homedirs (off , off) Allow httpd to enable homedirs httpd_use_nfs (off , off) Allow httpd to use nfs

括弧内の値は「(現在の設定、デフォルト設定)」を示します。

2. よく使うBoolean一覧

サービスごとに代表的なBooleanをまとめます。
Boolean名 有効にする場面
httpd_can_network_connect ApacheからバックエンドのAPIサーバーへ接続する
httpd_can_network_connect_db ApacheからDBサーバー(MySQL/PostgreSQL等)へ接続する
httpd_can_sendmail PHPのmail()関数など、ApacheからメールをSendmailへ渡す
httpd_use_nfs NFSマウント上のファイルをApacheで配信する
httpd_enable_homedirs ユーザーのホームディレクトリ(~/public_html)をApacheで公開する
allow_user_exec_content 一般ユーザーがホームディレクトリ内のスクリプトを実行する

3. Booleanを変更する

たとえばApacheからDBへの接続を許可する場合は httpd_can_network_connect_db を有効にします。

# -P(--persistent)で永続的に変更(再起動後も維持) setsebool -P httpd_can_network_connect_db on # semanageでも変更可能(setsebool -Pと同等) semanage boolean -m --on httpd_can_network_connect_db # 確認 getsebool httpd_can_network_connect_db # httpd_can_network_connect_db --> on

重要:-Pオプションなしの setsebool は再起動で元に戻ります。本番環境では必ず -P を付けてください。

AVC deniedエラーへの対処法

1. エラーログを確認する

SELinuxがアクセスを拒否すると /var/log/audit/audit.log にAVCエラーが記録されます。

# 最近のAVC deniedを確認 ausearch -m AVC -ts recent # sealertで人間が読みやすい形に整形(setroubleshoot-serverが必要) sealert -a /var/log/audit/audit.log

AVC denied のログには「どのプロセスが」「どのファイル/ポートに」「何の操作(read/write/connect等)を」拒否されたかが記録されています。
この情報をもとに、対処が「コンテキスト設定か」「ポート許可か」「Boolean変更か」を判断します。

2. audit2allowで対処法を確認する

# AVCエラーから必要なポリシーモジュールを生成 ausearch -m AVC -ts recent | audit2allow -M myapp # 生成されたモジュールを適用 semodule -i myapp.pp # 適用されているモジュールの確認 semodule -l | grep myapp

audit2allow は便利ですが、「全部許可」のモジュールを生成してしまうリスクがあります。
本番環境では生成された .te ファイルの内容を必ず確認し、必要最小限のルールかをチェックしてから適用してください。
既存のfcontext/port/boolean設定で対処できる場合は、カスタムモジュールを使わずsemanageで解決するほうがポリシーの管理がシンプルになります。
Apache タイムアウト設定の詳細のようなサービス設定変更を行った際にも、SELinuxのAVCエラーが発生することがあります。

トラブルシュート:よくあるエラーと対処

「ValueError: Type httpd_content_t is not valid」が出る場合

コンテキストタイプのスペルミスが原因です。

# 正しいコンテキストタイプを検索する semanage fcontext -l | grep "httpd.*content"

「already defined」エラーが出る場合

# 既存のルールを確認 semanage fcontext -l -C | grep "/data/web" # 変更する場合は -a(追加)ではなく -m(修正)を使う semanage fcontext -m -t httpd_sys_rw_content_t "/data/web(/.*)?"

semanageで設定したのにアクセスできない場合

restoreconの適用を忘れているケースが最も多いです。

# semanageで登録後、必ずrestoreconで適用する semanage fcontext -a -t httpd_sys_content_t "/data/web(/.*)?" restorecon -Rv /data/web/ # -v: 変更されたファイルを表示 -R: ディレクトリを再帰的に処理

その他の典型的なトラブルと対処法

症状 原因 対処
サービス起動直後にAVC denied が出る restorecon前にサービスが起動してコンテキスト未反映ファイルにアクセスした restoreconを先に実行してからサービスを起動する
fcontextを設定したのにサブディレクトリが拒否される 正規表現パターンが浅く、サブディレクトリにマッチしていない (/.*)? パターンで再登録し、restoreconを再実行する
ポート追加後もサービスが起動しない ファイアウォール(firewalld)側でポートが開いていない firewall-cmd --list-ports でポート開放状況を確認する
Boolean変更後も再起動するとデフォルトに戻る setsebool に -P を付け忘れた setsebool -P Boolean名 on で永続的に再設定する
カスタムポリシーモジュールが競合する 以前に適用した手動のポリシーモジュールが残っている semodule -l で一覧確認し、不要なモジュールを semodule -r モジュール名 で削除する

本記事のまとめ

semanageの主要サブコマンドと用途を整理します。
やりたいこと コマンド
ファイルコンテキストを永続登録 semanage fcontext -a -t タイプ "パス(/.*)?"
コンテキストをファイルに適用 restorecon -Rv /対象パス/
既存ルールを修正する semanage fcontext -m -t タイプ "パス(/.*)?"
ローカル追加ルールの確認 semanage fcontext -l -C
ポートを永続許可 semanage port -a -t タイプ -p tcp ポート番号
許可ポートを確認 semanage port -l | grep タイプ
Booleanを永続的に有効化 setsebool -P Boolean名 on
Booleanの状態確認 getsebool -a | grep サービス名
AVC deniedのログ確認 ausearch -m AVC -ts recent
必要なポリシーを自動生成 ausearch -m AVC -ts recent | audit2allow -M モジュール名
SELinuxを無効化せず、semanageで正しくポリシーを管理できれば、セキュリティを保ちながらサービスを安定稼働させられます。
まずは semanage fcontext と restorecon のセットをマスターするところから始めてください。
ポート確認コマンド(ss/lsof)と組み合わせることで、サービスが起動しない原因をSELinuxとポートの両面から診断できるようになります。

SELinuxを正しく設定できるLinuxエンジニアになりたいなら

ネットの古い情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

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

<PR>手元に置いて学びを深める1冊

Linuxサーバーセキュリティ徹底入門 オープンソースによるサーバー防衛の基本

まず無料メルマガでSELinuxの基礎を学び、さらに体系的に深めたい方はサーバー防衛の実践書として手元に置きたい1冊。

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

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

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

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

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

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

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

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

運営

リナックスマスター.JP(代表 宮崎智広)

株式会社イーネットマーキュリーが運営するLinux教育サイトです。代表の宮崎智広は現役のLinuxサーバー管理者として20年以上の実務経験を持ち、累計3,100名以上のエンジニアを指導してきました。実践型のLinuxセミナーや無料マニュアルの配布を通じてLinux人材の育成に取り組んでいます。