nginxとPHP-FPMの設定 – PHP共存版

さくらのVPSにCentOS 8をインストールした覚書です。

今回は、NginxとPHPの設定を行っていくのですが、PHPはいろんなバージョンが同居できる共存版でいきます。

DNFで入れたPHPで行く場合は「nginxとPHP-FPMの設定」をご覧ください。

なお本番環境で利用される場合はここにある内容だけを鵜呑みにせずセキュリティ専門家に相談されることをお勧めします。

環境

実施日2020-07-05
サーバさくらのVPS 2G
OSCentOS 8.2
cat /etc/redhat-release
CentOS Linux release 8.2.2004 (Core)

事前準備

本記事は、下記の2記事の作業が終わってNginxとPHP7.4が既にインストールしているところから始めます。

CentOS 8 にNginxを公式からインストール

PHP5.6.40をCentOS8にソースインストール

まだの場合は▲を先にご覧ください。
PHPのバージョンは今回は5.6.40で行きますが、ソースインストールしたPHPでしたら他のバージョンでも同じです。

変数を設定

当サイトでのソースインストールで行った場合は、下記の変数を設定することで他のバージョンでも同じように設定できるようにしています。

PHP_VERSION=5.6.40
MYSQL_TITLE=mysqlnd

PHP-FPMの設定

デフォルトファイルをコピーして配置します。

cp /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/etc/php-fpm.conf.default /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/etc/php-fpm.conf
# ;include=etc/fpm.d/*.conf
# include=/etc/php-5.6.40-fpm.d/*.conf
sed -i -e "s:^;include=etc/fpm.d/\*.conf$:include=/etc/php-$PHP_VERSION-fpm.d/*.conf:g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/etc/php-fpm.conf
# ;error_log = log/php-fpm.log
# error_log = /var/log/php-fpm/php-5.6.40-fpm.log
sed -i -e "s:^;error_log = log/php-fpm.log$:error_log = /var/log/php-fpm/php-$PHP_VERSION-fpm.log:g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/etc/php-fpm.conf
# user = nobody
# user = nginx
sed -i -e "s:^user = [a-z0-9]*$:user = nginx:g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/etc/php-fpm.conf
# group = nobody
# group = nginx
sed -i -e "s:^group = [a-z0-9]*$:group = nginx:g" /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/etc/php-fpm.conf

確認

# 書き換わった個所を確認
diff /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/etc/php-fpm.conf.default /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/etc/php-fpm.conf

# エディタで見てみる
vi /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/etc/php-fpm.conf

準備

# ディレクトリを作成
mkdir /var/log/php-fpm

mkdir /etc/php-$PHP_VERSION-fpm.d

いろいろ確認

# PHP-FPM
vi /usr/local/lib/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/etc/php-fpm.conf

# php-fpm.d
ls -la /etc/php-$PHP_VERSION-fpm.d
# nginx
vi /etc/nginx/nginx.conf
# この中で include /etc/nginx/conf.d/*.conf; がある

# nginx/conf.d
ls -la /etc/nginx/conf.d/

# default.conf
vi /etc/nginx/conf.d/default.conf

バーチャルホストの設定

ここでは例として、example.com というドメインで行っていきます。
またこのドメインには専用のユーザーを割り当てます。
ユーザー名は example とします。

VHOST_DOMAIN=example.com
VHOST_USER=example

ユーザーを作成

useradd $VHOST_USER

exampleユーザーに切り替えて色々準備

# 切り替え
su $VHOST_USER

# 移動
cd

# 公開鍵認証
mkdir .ssh
chmod 0755 ./.ssh
vi ./.ssh/authorized_keys
chmod 0644 ./.ssh/authorized_keys

# www 以下にweb関連を置く
mkdir -p ./www/{log,public_html}
chmod -R 0770 ./www

# rootに戻る
exit

PHP-FPM の設定

エディタで開いて

vi /etc/php-$PHP_VERSION-fpm.d/user-$VHOST_USER.conf

次の内容をそのままコピーして保存

[{VHOST_USER}]
listen = /run/php-fpm/user-{VHOST_USER}.sock
listen.owner = nginx
listen.group = nginx
user = {VHOST_USER}
group = {VHOST_USER}
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
slowlog = /var/log/php-fpm/{VHOST_USER}-slow.log
php_admin_value[error_log] = /var/log/php-fpm/{VHOST_USER}-error.log

{VHOST_USER} の個所をまとめて置換

sed -i -e "s:{VHOST_USER}:$VHOST_USER:g" /etc/php-$PHP_VERSION-fpm.d/user-$VHOST_USER.conf
mkdir /run/php-fpm

▲だけではOS再起動で php-fpm ディレクトリが消えてなくなるので、再起動時にディレクトリを作成するようにしておきます。

vi /etc/tmpfiles.d/php-fpm.conf
 d /run/php-fpm 0755 root root

起動設定

ソースにあるファイルをコピー

# 移動
cd /usr/local/src/php-$PHP_VERSION-mysqlc-$MYSQL_TITLE/php-$PHP_VERSION

# コピー
cp -ip ./sapi/fpm/init.d.php-fpm /etc/init.d/php-$PHP_VERSION-fpm

# パーミッション
chmod 755 /etc/init.d/php-$PHP_VERSION-fpm

# サービスに登録
chkconfig --add php-$PHP_VERSION-fpm

# 現在の状態を確認
systemctl status php-$PHP_VERSION-fpm

# 起動
systemctl start php-$PHP_VERSION-fpm

# 終了
systemctl stop php-$PHP_VERSION-fpm

# 再起動
systemctl restart php-$PHP_VERSION-fpm

# 自動起動の有効化
systemctl enable php-$PHP_VERSION-fpm

# 自動起動の解除
systemctl disable php-$PHP_VERSION-fpm

status で php-fpm が見つからないエラーのとき

sed -i -e "s:^php_fpm_BIN=\${exec_prefix}/sbin/php-fpm\$:php_fpm_BIN=\${exec_prefix}/sbin/php-fpm-$PHP_VERSION-mysqlc-$MYSQL_TITLE:g" /etc/init.d/php-$PHP_VERSION-fpm

ここまでで、 systemctl の start, stop, restart, status あたりでエラーがなく、自動起動を有効化出来ていればOK。

Nginxにバーチャルホストの設定

ここでは例として、example.com というドメインで行っていきます。
またこのドメインには専用のユーザーを割り当てます。
ユーザー名は example とします。

こちらはPHP共存版です。
DNFで入れた場合の設定は微妙に異なりますのでこちらをご覧ください

変数の設定

VHOST_DOMAIN=example.com
VHOST_USER=example

ソケット

vi /etc/nginx/conf.d/php-fpm-$VHOST_USER.conf
upstream php-fpm-{VHOST_USER} {
    ip_hash;
    server unix:/run/php-fpm/user-{VHOST_USER}.sock;
}

{VHOST_USER} の個所をまとめて置換

sed -i -e "s:{VHOST_USER}:$VHOST_USER:g" /etc/nginx/conf.d/php-fpm-$VHOST_USER.conf

バーチャルホストの設定

ファイル名はなんでも良いですが、ここでは「vhost-ドメイン.conf」

設定する内容はこちらをご覧ください

{VHOST_DOMAIN} と {VHOST_USER} の個所をまとめて置換

sed -i -e "s:{VHOST_DOMAIN}:$VHOST_DOMAIN:g" /etc/nginx/conf.d/vhost-$VHOST_DOMAIN.conf
sed -i -e "s:{VHOST_USER}:$VHOST_USER:g" /etc/nginx/conf.d/vhost-$VHOST_DOMAIN.conf

Basic認証のパスワードファイル

Basic認証の設定を入れたのでパスワードファイルを作成
不要な場合は、auth_basic のところをコメントか削除

# htpasswd が使えるなら
htpasswd -c /home/$VHOST_USER/www/.htpasswd sample_user

# htpasswd が無い場合
vi /home/$VHOST_USER/www/.htpasswd

chown $VHOST_USER:$VHOST_USER /home/$VHOST_USER/www/.htpasswd

パーミッションの確認

念のため確認と再設定をしておきます。

通常ファイルは nginx ユーザー権限。
PHPファイルは個々のユーザー権限。
SFTPは個々のユーザー権限。

chmod 750 /home/$VHOST_USER
chmod 750 /home/$VHOST_USER/www
chmod 750 /home/$VHOST_USER/www/public_html
chmod 700 /home/$VHOST_USER/www/log
chmod 750 /home/$VHOST_USER/www/.htpasswd
find /home/$VHOST_USER/www/public_html -type f | xargs chmod 640
find /home/$VHOST_USER/www -name "*.php" | xargs chmod 600

ユーザーグループの設定

バーチャルホストで、PHPの実行ユーザーは変えれるけど、通常ファイルのアクセスユーザーは変えれんっぽいので。 (このあたりもう少し調査は必要)

# 現在の状態を確認
cat /etc/group | grep nginx
cat /etc/group | grep $VHOST_USER

usermod -aG nginx $VHOST_USER
usermod -aG $VHOST_USER nginx

# 外す場合
usermod -G "" $VHOST_USER
usermod -G "" nginx

# 両方いるか再確認が必要
usermod -aG nginx example

# ▲は不要で、▼だけでいける気がする(知らんけど)
usermod -aG example nginx

# 確認
cat /etc/group | grep nginx
cat /etc/group | grep example

設定を反映

# エラーチェック
nginx -t

# 再起動
# systemctl restart php-$PHP_VERSION-fpm
systemctl restart php-5.6.40-fpm
systemctl restart nginx

SSLを設定する

SSLを設定する場合は▼の手順で行います。

CentOS8に無料SSL「Let’s Encrypt」を設定する

証明書を作ったら▼から http と https の設定をする

vi /etc/nginx/conf.d/vhost-$VHOST_DOMAIN.conf