Linux基礎

CentOS Stream8/Nginx/php-fpm/https自己署名証明書の構築設定手順

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 した状態からです。

【図解】CentOS8 Streamのboot.isoでのminimalインストール with [VirtualBOX Guest Additions]
CentOSはバージョン8で終了、今後は CentOS Stream へシフトす...

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 への証明書インストール手順は以下をご参照下さい。

【図解/Windows】ルート証明書のインストール方法と確認方法
デジタル証明書の確認 Windows でデジタル証明書のエラーが出た際、クライア...

このとき、もし 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 ~]#

コメント

タイトルとURLをコピーしました