香川県観音寺市でシステム開発

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 www

# ログ
mkdir www/log

# ドキュメントルート
mkdir www/public_html

# 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にバーチャルホストの設定

エディタで開いて

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」

エディタで開いて

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

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

# server {
#     listen 80;
#     listen [::]:80;
#     server_name {VHOST_DOMAIN};
#     return 301 https://$host$request_uri;
# }

server {

    # http  ——————————————--
    listen 80;
    listen [::]:80;

    # https ——————————————--
    # listen 443 ssl default_server;
    # listen [::]:443 ssl default_server ipv6only=on;
    # ssl on;
    # ssl_certificate            /etc/letsencrypt/live/{VHOST_DOMAIN}/fullchain.pem;
    # ssl_certificate_key        /etc/letsencrypt/live/{VHOST_DOMAIN}/privkey.pem;
    # ssl_prefer_server_ciphers  on;

    # ————————————————--

    server_name  {VHOST_DOMAIN};

    charset UTF-8;

    access_log /home/{VHOST_USER}/www/log/access.log  main;
    error_log  /home/{VHOST_USER}/www/log/error.log warn;

    root   /home/{VHOST_USER}/www/public_html;
    index  main.php index.php index.html index.htm;

    client_max_body_size 16M;

    # Basic認証をかけないIPアドレス
    # satisfy any;
    # allow 0.0.0.1;
    # allow 0.0.0.2;
    # deny all;

    # Basic認証用の設定を追加
    # auth_basic "Restricted";
    # auth_basic_user_file /home/{VHOST_USER}/www/.htpasswd;

    location / {
        set $redirect_url $uri;
        try_files $uri $uri/ /main.php?$args;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass  php-fpm-{VHOST_USER};
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param REDIRECT_URL $redirect_url;
        fastcgi_buffer_size  128k;
        fastcgi_buffers  256 16k;
        fastcgi_busy_buffers_size  256k;
        fastcgi_temp_file_write_size  256k;
        include  fastcgi_params;
    }

    # ———————————————————————
    # Aulta CMS
    # ———————————————————————
    # location ~ ^/manager/ {
    #     set $redirect_url $uri;
    #     try_files $uri $uri/ /manager/main.php?$args;

    #     location ~* \.(jpg|jpeg|gif|png|css|js|swf|ico|pdf|svg|eot|ttf|woff)$ {
    #         expires 60d;
    #         access_log off;

    #         location ~ ^/manager/compress/.*\.(css|js)$ {
    #             set $redirect_url $uri;
    #             try_files $uri $uri/ /manager/compress/_min.php?$args;
    #         }

    #         location ~ ^/manager/uploads/ {
    #             set $redirect_url $uri;
    #             try_files $uri $uri/ /manager/uploads/_execute.php?$args;
    #         }
    #     }
    # }

    # location ~* \.(jpg|jpeg|gif|png|css|js|swf|ico|pdf|svg|eot|ttf|woff)$ {
    #     expires 60d;
    #     access_log off;

    #     location ~ ^/compress/.*\.(css|js)$ {
    #         set $redirect_url $uri;
    #         try_files $uri $uri/ /compress/_min.php?$uri&$args /compress/_min.php?$args;
    #     }

    #     location ~ ^/uploads/ {
    #         set $redirect_url $uri;
    #         try_files $uri $uri/ /uploads/_execute.php?$uri&$args /uploads/_execute.php?$args;
    #     }
    # }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location ~ /\.ht {
        deny  all;
    }
}

{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認証の設定を入れたのでパスワードファイルを作成
不要な場合は、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

SSLを設定する場合はこのページの作業が終わってから下記をご覧ください。

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

パーミッションの確認

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

通常ファイルは 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

広告