SELinux によってファイル操作が拒否されるときの対処方法

  • URLをコピーしました!
目次

概要

Linux サーバーでファイルの作成・移動・読み書きを行おうとした際、次のようなエラーが出ることがあります。

Permission denied
mv: cannot move 'file' to '/var/www/html': Permission denied

一見パーミッション(chmod/chown)の問題に見えても、実は SELinux によるアクセス制御 が原因である場合があります。
ここでは、SELinux が原因でファイル操作が拒否される際の調査・解決手順を具体的に解説します。

SELinuxとは?

SELinux(Security-Enhanced Linux)は、
従来の「パーミッション」や「所有者」設定とは別に、プロセスやファイルにセキュリティコンテキストを割り当ててアクセスを制御する仕組みです。

そのため、

  • root であっても不正なラベルのファイルにアクセスできない
  • Apache などのサービスが想定外のパスにアクセスできない
    といった動作になります。

主な原因と解決方法

原因① SELinuxが「Enforcing」モードで有効化されている

状況

SELinux がアクセスを強制的に制限しており、通常の権限設定ではアクセスできない。

確認方法

getenforce
# 出力例
Enforcing

解決方法

一時的に「Permissive」モード(警告のみ)へ変更して動作確認します。

sudo setenforce 0
getenforce
# 出力: Permissive

これで操作が通る場合、SELinuxの制御が原因です。
恒久的にモードを変更したい場合は /etc/selinux/config を編集します。

sudo vi /etc/selinux/config
# 以下の行を修正
SELINUX=permissive

⚠️ 注意:セキュリティが低下するため、恒久的な無効化は最終手段としましょう。

原因② ファイル・ディレクトリの SELinux コンテキストが誤っている

状況

Webアプリやサービスが想定ディレクトリ外のファイルにアクセスできず拒否される。
例:Apacheが /var/www/html 以外のパスを扱うとき。

確認方法

ls -Z /var/www/html/
# 出力例
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html

解決方法

アクセス対象のディレクトリに適切なコンテキストを付与します。

例:Apache が /data/www にアクセスする場合
sudo semanage fcontext -a -t httpd_sys_content_t "/data/www(/.*)?"
sudo restorecon -Rv /data/www

これで /data/www 以下が httpd_sys_content_t に設定され、Apache からアクセス可能になります。

原因③ サービスの SELinux ポリシーが制限している

状況

FTP、Nginx、MySQL などが他ディレクトリやポートへのアクセスを拒否される。

解決方法

ポリシー制御を変更できる boolean 値 を確認・設定します。

実行例(Apacheで外部アクセスを許可する場合)

# 現在の設定を確認
sudo getsebool -a | grep httpd

# 一般的に必要な設定例
sudo setsebool -P httpd_can_network_connect 1
sudo setsebool -P httpd_read_user_content 1

実行例(vsftpdでホームディレクトリを許可する場合)

sudo setsebool -P ftp_home_dir 1

原因④ ログで拒否内容が確認できる(audit.log)

状況

原因が分からない場合はログを調べると詳細な拒否理由が分かります。

確認方法

sudo ausearch -m avc --start recent
# または
sudo cat /var/log/audit/audit.log | grep denied

出力例

type=AVC msg=audit(1693200000.123:123): avc:  denied  { write } for  pid=1234 comm="httpd" name="test" dev="sda1" ...

対処

audit2whyaudit2allow を使用すると、解決策を提案してくれます。

sudo cat /var/log/audit/audit.log | audit2why
sudo cat /var/log/audit/audit.log | audit2allow -M mypolicy
sudo semodule -i mypolicy.pp

原因⑤ コンテナ環境(Docker / Podman)での SELinux 制約

状況

ボリュームマウント時にアクセス拒否される。

docker: Error response from daemon: permission denied.

解決方法

マウント時に :Z または :z オプションを指定して、SELinuxコンテキストを自動調整します。

docker run -v /data/app:/app:Z myimage

トラブル対応表

現象・エラー主な原因解決方法
Permission deniedSELinuxがEnforcingモードsetenforce 0 で一時的に無効化して確認
Apacheが外部パスにアクセス不可コンテキストが不一致semanage fcontext + restorecon
外部通信やDB接続が拒否ポリシー制限setsebool -P httpd_can_network_connect 1
詳細な拒否原因を調査したいログ解析不足/var/log/audit/audit.log + audit2why
Dockerでマウント拒否SELinuxコンテナ制約-v /path:/container:Z オプション指定

まとめ

SELinuxはセキュリティを強化する強力な仕組みですが、
想定外の動作を制限してトラブルを引き起こすこともあります。

トラブル対応の基本ステップは以下の4つです:

  1. getenforce でモード確認
  2. ls -Z でコンテキスト確認
  3. audit.log で拒否理由を調査
  4. semanage / setsebool で適切に許可設定
目次