CentOS Stream8 では AppStream リポジトリがデフォルトで使えるようになっており、nginx を AppStream からインストールできるようになりました。
やりたいこと
CentOS Stream8 に nginx と php-fpm をインストールし、さらには openssl の自己署名証明書を使って常時 https 化にします。
ホスト名は www.example.com とします。
nginx では PHP の処理ができませんので、php-fpm という fastCGI で処理を渡します。
nginx と PHP 処理サーバが異なるサーバの場合、処理の渡し方は TCP/IP でのリバースプロキシで行いますが、同一ホスト内で nginx と php-fpm を使う場合は、同様に localhost (127.0.0.1) へのリバースプロキシでも可能ですが、デフォルトでは UNIX ドメインソケット (.sock スペシャルファイル) を使う方式になっており、こちらのほうが高速です。
今回の構築例も UNIX ドメインソケットを使う方式です。
手順
スタートは CentOS Stream8 を minimal install した状態からです。
nginx, php-fpm をインストール
[root@localhost ~]# dnf -y install nginx php-fpm
firewalld 設定変更
みんな、firewalld は有効にしているよね?SELinux も許せて Permissive だよね?
[root@localhost ~]# firewall-cmd --permanent --add-service http [root@localhost ~]# firewall-cmd --permanent --add-service https [root@localhost ~]# firewall-cmd --reload
cockpit と dhcpv6-client を消したいなら --remove-service で。
結果を firewall-cmd --list-all で確認しましょう。
[root@localhost ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: enp0s3
sources:
services: http https ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@localhost ~]#
PHP-FPM 設定変更
ユーザ/グループを apache から nginx に変更
[root@localhost ~]# vi /etc/php-fpm.d/www.conf
user = apache nginx
group = apache nginx
listen.owner = nobody nginx
listen.group = nobody nginx
listen.mode = 0660
[:wq]
php-fpm と nginx の手動起動および自動起動
そして php-fpm と nginx を起動します。順番的には php-fpm で listen してから nginx を起動したほうがよいでしょう。
自動起動の設定もしたいので、そういうときは systemctl enable *** --now でいっぺんに設定できます。status で状態確認。
[root@localhost ~]# systemctl enable php-fpm --now [root@localhost ~]# systemctl enable nginx --now [root@localhost ~]# systemctl status php-fpm [root@localhost ~]# systemctl status nginx
ここでいったん動作確認。http://[ホストIP] へアクセスし、以下の画面が出るか確認しましょう。
次に、管理者権限で何かしらのテキストエディタを起動し、C:\Windows\System32\drivers\etc 配下にある hosts ファイルを開き、www.example.com を名前解決できるようにしておきます。私の環境ではサーバの IP は 192.168.0.26 だったので以下のようになります。(この後、自己署名証明書の動作確認で必要になります。)
先ほどと同様に、ブラウザで http://www.example.com でアクセスし、同じ画面が出るか確認しましょう。出ない場合は ping www.example.com などで名前解決ができているか確認しましょう。
自己署名証明書を作る
まず、ディレクトリを作成します。nginx側の設定を変更するのはだるいので、nginx の初期設定に合うように、/etc/pki の下に nginx/private ディレクトリを作成します。
[root@localhost ~]# cd /etc/pki [root@localhost pki]# mkdir -p nginx/private [root@localhost pki]# cd nginx/private
次に、openssl コマンドを使って秘密鍵 (server.key) を作成します。
[root@localhost private]# openssl genrsa -out server.key 2048
そして秘密鍵を使って CSR (server.csr) を作成します。対話形式でいくつか聞かれますが、最初の Country Name を JP にし、途中の CommonName を www.example.com に設定し、あとは空欄のまま Enter にします。(このあたりは好みの問題です。
[root@localhost private]# openssl req -new -key server.key -out ../server.csr ----- Country Name (2 letter code) [XX]:JP State or Province Name (full name) []: Locality Name (eg, city) [Default City]: Organization Name (eg, company) [Default Company Ltd]: Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:www.example.com Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: [root@localhost private]#
次に、CSR に署名をします。
一般的なケースでは、上位の認証局に CSR を送付して、その認証局の秘密鍵で署名をしてもらうのですが、だるいので自己署名にします。つまり、CSR を生成するときに使った秘密鍵を、署名用にも使うわけです。
そして署名と同時に、有効期間=365日、SANs (サブジェクト代替名 : Subject Alternative Name) = www.example.com を設定します。
最近のブラウザは CommonName を一切見ず、SANs のみをチェックするので、SANs に設定が入っていないと、証明書をインストールしていても警告が出てしまいます。
SANs を設定するには適当なテキストファイルに subjetcAltName = DNS:www.example.com と記述し、openssl の -extfile オプションでそのテキストファイルを指定します。
[root@localhost private]# cd .. [root@localhost nginx]# vi sans.txt subjectAltName = DNS:www.example.com [:wq] [root@localhost nginx]# openssl x509 -req -days 365 -in server.csr -signkey private/server.key -out server.crt -extfile sans.txt
nginx の常時SSL化
https に対応できるようにするには、nginx.conf の下部にある # Settings for a TLS enabled server. より下のコメントアウト # を外せば OK です。
[root@localhost ~]# vi /etc/nginx/nginx.conf
# Settings for a TLS enabled server.
server {
listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
server_name _;
root /usr/share/nginx/html;
ssl_certificate "/etc/pki/nginx/server.crt";
ssl_certificate_key "/etc/pki/nginx/private/server.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers PROFILE=SYSTEM;
ssl_prefer_server_ciphers on;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
この設定が完了したら、次に Root ディレクトリ直下 (上記のケースでは /usr/share/nginx/html) に index.php を配置します。内容は何でもOKです。例えば以下を配置します。
# vi /usr/share/nginx/html/index.php
<html>
<head>
<title>Test Page!</title>
</head>
<body>
<p><?php echo "Hello, PHP!"; ?></p>
<p><?php echo "I've got $_GET[hoge]!"; ?></p>
</body>
</html>
その後、systemctl restart nginx で nginx を再起動し、https://www.example.com でアクセスできるか動作確認してみましょう。
自分で作成した証明書は PC にインストールしないと警告が出てくるはずです。
作った自己署名証明書を「信頼されたルート証明機関」として Windows PC にインストールすれば、Chrome や Edge では警告が出なくなるはずです。(Firefox はどうしても警告が出る)
PC への証明書インストール手順は以下をご参照下さい。
このとき、もし 403 Forbidden が表示されたのなら、index.php にうまくアクセスできていない可能性があります。ルートディレクトリに index.php が配置してあるか確認しましょう。
次に、http でアクセスしてきた通信を https にリダイレクトするよう、server_name の下あたりに return 301 の設定を加えます。
# vi /etc/nginx/nginx.conf http { ・・・ server { listen 80 default_server; listen [::]:80 default_server; server_name _; return 301 https://$host$request_uri; ・・・
ブラウザで http://www.example.com/?hoge=fuga とアクセスしてみましょう。
Hello, PHP!
I've got fuga!
と表示されたら成功です。
/と?の間には index.php が省略されています。明示的に /index.php?hoge=fuga としても同じ表示になります。この自動補完の設定は /etc/nginx/default.d/php.conf に記載されています。fastcgi_index index.php; という箇所です。
また、?hoge=fuga は index.php に hoge=fuga を渡しており、$_GET[hoge] の箇所が fuga になるわけです。hoge=ponyo にすれば、I've got ponyo! になります。
以上で設定は完了です。
nginx と php-fpm との渡しの設定
すでに上記の動作確認で nginx から php-fpm へ PHP の処理が渡っていることが確認できました。
ですが、設定はどうなっているのでしょうか。
まず、php-fpm がどのように待ち受けているかというと、/etc/php-fpm.d/www.conf にデフォルト設定が入っています。
[root@localhost ~]# cat /etc/php-fpm.d/www.conf | grep "listen ="
listen = /run/php-fpm/www.sock
上記パスの該当 .sock ファイルを見てみると
[root@localhost ~]# ls -l /run/php-fpm/www.sock
srw-rw----+ 1 root root 0 3月 24 21:35 /run/php-fpm/www.sock
左端がソケットファイルを示す s になっています。
そして nginx 側はどうなっているかというと、/etc/nginx/conf.d/php-fpm.conf にやはり www.sock の UNIX ドメインソケットへ連携するように設定が書かれています。
[root@localhost ~]# cat /etc/nginx/conf.d/php-fpm.conf
# PHP-FPM FastCGI server
# network or unix domain socket configuration
upstream php-fpm {
server unix:/run/php-fpm/www.sock;
}
[root@localhost ~]#
コメント