php-fpm の UNIX ソケットが作成されなかった場合

CentOS 7 に、nginx + php-fpm の新しい環境を作成したところ、デーモナイズされているはずの php-fpm が起動しない。

## 最初に結論

RedHat Linux 7 (CentOS7) から `/var/run (/run)` 以下のファイルは永続的に保存されなくなったため、起動する度に再作成する必要がある。

```shell-session
$ 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 に格納されたファイルは、永続的ではなくなり、再起動後に保持されません。つまり、アプリケーションは、インストール時ではなく、起動時に独自のファイルとディレクトリーを再作成する必要があります。<br>[2.3. ファイルシステムレイアウト - Red Hat Customer Portal](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/migration_planning_guide/sect-red_hat_enterprise_linux-migration_planning_guide-file_system_layout)

- 参考: [tmpfiles.d - Configuration for creation, deletion and cleaning of volatile and temporary files - Linux Man Pages (5)](https://www.systutorials.com/docs/linux/man/5-tmpfiles.d/)

### 設定例

今回起動しなかったのは、`/var/run` 以下の `/var/run/php73-php-fpm` が削除されていたことで、UNIX ソケットが生成できなかったことが原因である。なので、起動毎に `/var/run/php73-php-fpm` を作成するように設定ファイルを用意する。

`/usr/lib/tmpfiles.d` 下に設定ファイルを作成する。

例えば

```shell_session
$ 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 が起動しないことが発端となる。

```shell-session
$ 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` を確認してみる。

```shell_session
$ ls /var/run/ | grep php73-php-fpm
$
```

`/var/run/php73-php-fpm` がない……。？？？。

ディレクトリを作成して手動で起動すると、正常に動作する。

```shell-session
$ 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
```
ふむ。
しかし、再起動してみると、

```shell-session
$ ps aux | grep -v grep | grep php
$
$ ls /var/run/ | grep php73-php-fpm
$
```
php-fpm は起動していない。念のため `/var/run` を確認してみる。

```shell_session
$ ls /var/run/ | grep php73-php-fpm
$
```

`/var/run/php73-php-fpm` が消えてる……。

念のため、php-fpm の UNIX ソケット生成の設定を確認する。

```shell-session
$ 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 のコンテキストを確認する。

```shell-session
$ 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` のコンテキストもちゃんと設定されている。

```shell_session
$ 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 のプロセスのコンテキストを確認する。

```shell-session
$ 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 を調査する。

```shell-session
$ 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` コマンドでも確認できる。
 今回の場合だと、

```shell-session
$ 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` コマンドがない場合は、インストールする。

```shell-session
$ sudo yum install -y checkpolicy
$ sudo yum install -y selinux-policy-devel
```

audit.log を読みやすくする。

```shell-session
$ 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` 下のデータが消えることにつまづいていたことがわかる。