CentOS 7 に、nginx + php-fpm の新しい環境を作成したところ、デーモナイズされているはずの php-fpm が起動しない。
最初に結論
RedHat Linux 7 (CentOS7) から /var/run (/run)
以下のファイルは永続的に保存されなくなったため、起動する度に再作成する必要がある。
$ df -h | grep ' /run'
tmpfs 920M 8.6M 911M 1% /run
tmpfs 184M 0 184M 0% /run/user/0
tmpfs 184M 0 184M 0% /run/user/1000
よって、インストールされるパッケージが、この変更に対応していない場合は、個別に設定をすることになる。
Red Hat Enterprise Linux 7 では、/run ディレクトリーは、/var/run ディレクトリーをバインドマウントする一時ファイルストレージシステム (tmpfs) です。同様に、/run/lock ディレクトリーは /var/lock ディレクトリーをバインドマウントするようになりました。/run と /run/lock に格納されたファイルは、永続的ではなくなり、再起動後に保持されません。つまり、アプリケーションは、インストール時ではなく、起動時に独自のファイルとディレクトリーを再作成する必要があります。
2.3. ファイルシステムレイアウト - Red Hat Customer Portal
設定例
今回起動しなかったのは、/var/run
以下の /var/run/php73-php-fpm
が削除されていたことで、UNIX ソケットが生成できなかったことが原因である。なので、起動毎に /var/run/php73-php-fpm
を作成するように設定ファイルを用意する。
/usr/lib/tmpfiles.d
下に設定ファイルを作成する。
例えば
$ cat /usr/lib/tmpfiles.d/php73-php-fpm.conf
# Type Path Mode UID GID Age Argument
d /var/run/php73-php-fpm 0755 nginx nginx -
のように記述する。
フォーマット
フォーマット | 概要 |
---|---|
Type | tmpfiles.d の動作を指定。 d はディレクトリ作成 |
Path | Type に応じて絶対パスで指定。上記の d の場合、指定された Path にディレクトリを作成 |
Mode | 操作権限の指定。- を指定した場合、初期値の 0755 が設定される |
UID | Path で指定するファイルやディレクトリを所有するユーザーを指定 |
GID | Path で指定するファイルやディレクトリを所有するグループを指定 |
Age | Path で指定するファイルやディレクトリの寿命を指定。寿命を過ぎると、削除される |
Argument | Type で指定された設定に応じて、動作する。Path で指定したディレクトリを、Argument で指定するディレクトリへコピーする等 |
今回の経緯
nginx + php-fpm の UNIX ソケット接続で設定をしたところ、php-fpm が起動しないことが発端となる。
$ ps aux | grep php
vagrant 5866 0.0 0.0 112712 984 pts/0 R+ 16:38 0:00 grep --color=auto php
$ systemctl list-units | grep php-fpm
● php73-php-fpm.service loaded failed failed The PHP FastCGI Process Manager
$ systemctl status php73-php-fpm
● php73-php-fpm.service - The PHP FastCGI Process Manager
Loaded: loaded (/usr/lib/systemd/system/php73-php-fpm.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Fri 2019-04-05 16:16:13 JST; 12min ago
Main PID: 2838 (code=exited, status=78)
UNIX ソケットが生成されるディレクトリ /var/run
を確認してみる。
$ ls /var/run/ | grep php73-php-fpm
$
/var/run/php73-php-fpm
がない……。???。
ディレクトリを作成して手動で起動すると、正常に動作する。
$ sudo mkdir /var/run/php73-php-fpm && sudo chown -R nginx:nginx /var/run/php73-php-fpm
$ sudo systemctl enable php73-php-fpm
$ sudo systemctl start php73-php-fpm
$ ls -l /var/run/php73-php-fpm/php-fpm.sock
srw-rw----. 1 nginx nginx 0 Apr 5 16:33 /var/run/php73-php-fpm/php-fpm.sock
$ ps aux | grep -v grep | grep php-fpm
root 7360 0.0 0.7 357464 13852 ? Ss 16:33 0:00 php-fpm: master process (/etc/opt/remi/php73/php-fpm.conf)
nginx 7361 0.0 0.4 357464 7584 ? S 16:33 0:00 php-fpm: pool www
nginx 7362 0.0 0.4 357464 7584 ? S 16:33 0:00 php-fpm: pool www
nginx 7363 0.0 0.4 357464 7584 ? S 16:33 0:00 php-fpm: pool www
nginx 7364 0.0 0.4 357464 7584 ? S 16:33 0:00 php-fpm: pool www
nginx 7365 0.0 0.4 357464 7588 ? S 16:33 0:00 php-fpm: pool www
ふむ。
しかし、再起動してみると、
$ ps aux | grep -v grep | grep php
$
$ ls /var/run/ | grep php73-php-fpm
$
php-fpm は起動していない。念のため /var/run
を確認してみる。
$ ls /var/run/ | grep php73-php-fpm
$
/var/run/php73-php-fpm
が消えてる……。
念のため、php-fpm の UNIX ソケット生成の設定を確認する。
$ grep -r 'php-fpm.sock' /etc/opt/remi/php73/
/etc/opt/remi/php73/php-fpm.d/www.conf:listen = /var/run/php73-php-fpm/php-fpm.sock
SELinux が問題か?
次に SELinux のコンテキストを確認する。
$ ls -Z /var/run/
drwxr-xr-x. mysql mysql system_u:object_r:mysqld_var_run_t:s0 mysqld
drwxrwxr-x. root root system_u:object_r:var_run_t:s0 netreport
drwxr-xr-x. root root system_u:object_r:NetworkManager_var_run_t:s0 NetworkManager
-rw-r--r--. root root system_u:object_r:httpd_var_run_t:s0 nginx.pid
drwxr-xr-x. root root unconfined_u:object_r:var_run_t:s0 php73-php-fpm
自分で /var/run/php73-php-fpm
ディレクトリを作成したから、 unconfined_u
になるのはわかるが、なぜ再起動する度にディレクトリが削除されるのか理由がわからない。
/var/run/php73-php-fpm
のコンテキストもちゃんと設定されている。
$ grep php73 /etc/selinux/targeted/contexts/files/file_contexts.local
/var/run/php73-php-fpm(/.*)? system_u:object_r:var_run_t:s0
$ grep '/var/run' /etc/selinux/targeted/contexts/files/file_contexts | grep php-fpm
/var/run/php-fpm(/.*)? system_u:object_r:httpd_var_run_t:s0
php-fpm のプロセスのコンテキストを確認する。
$ ps auxZ | grep -v grep | grep php-fpm
system_u:system_r:httpd_t:s0 root 5854 0.2 0.7 357464 13856 ? Ss 16:49 0:00 php-fpm: master process (/etc/opt/remi/php73/php-fpm.conf)
system_u:system_r:httpd_t:s0 nginx 5855 0.0 0.4 357464 7584 ? S 16:49 0:00 php-fpm: pool www
次に audit.log を調査する。
$ sudo grep SERVICE /var/log/audit/audit.log | grep php-fpm
type=SERVICE_START msg=audit(1554280715.549:1679): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=php73-php-fpm comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
type=SERVICE_STOP msg=audit(1554280997.831:1704): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=php73-php-fpm comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
ausearch
コマンドでも確認できる。
今回の場合だと、
$ sudo ausearch -i -m service_start | grep php-fpm
type=SERVICE_START msg=audit(04/03/2019 17:38:35.549:1679) : pid=1 uid=root auid=unset ses=unset subj=system_u:system_r:init_t:s0 msg='unit=php73-php-fpm comm=systemd exe=/usr/lib/systemd/systemd hostname=? addr=? terminal=? res=success'
ausearch
コマンドがない場合は、インストールする。
$ sudo yum install -y checkpolicy
$ sudo yum install -y selinux-policy-devel
audit.log を読みやすくする。
$ sudo yum install -y setroubleshoot
$ sudo sealert -a /var/log/audit/audit.log > ~/logfile.txt
$ cat ~/logfile.txt
found 1 alerts in /var/log/audit/audit.log
--------------------------------------------------------------------------------
SELinux is preventing /opt/remi/php73/root/usr/sbin/php-fpm from read access on the file index.php.
***** Plugin catchall_boolean (89.3 confidence) suggests ******************
If you want to allow httpd to read user content
Then you must tell SELinux about this by enabling the 'httpd_read_user_content' boolean.
...
audit.log をみる限り、AVC (Access Vector Cache) の問題ではなさそうだし、 restoreconn -v /var/run/php73-php-fpm
してもディレクトリが消えてしまう問題は解決しなかった。
最終的に
何度も見落としがないか確認し直したあとに、途方に暮れて「/var/run 消える」で検索した結果、本当の原因がわかった次第だ。
検索結果を見ると、CentOS 7 リリース当時、他の人も /var/run
下のデータが消えることにつまづいていたことがわかる。