概要
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" ...
対処
audit2why
や audit2allow
を使用すると、解決策を提案してくれます。
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 denied | SELinuxが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つです:
- getenforce でモード確認
- ls -Z でコンテキスト確認
- audit.log で拒否理由を調査
- semanage / setsebool で適切に許可設定


