Let's Encrypt ~CentOSとNginxと、時々、Laravel~


前書き

かなりはまったので個人的備忘録
某映画作品と本文は一切関係ございません。
タイトルのニュアンスが素敵だったので真似ただけです。


環境

  • CentOS 7.6
  • nginx 1.12.2
  • Laravel 5.5 LTS

前提

rootユーザ
通らない場合、適宜sudoなどつけてください。

example.comをご自身のドメインに変えるだけで動くようになっていると思います。(間違っていたらコメントで教えてください。)

公開ディレクトリ /var/www/html/example.com/public


Nginx インストール

$ yum install nginx 
$ systemctl start nginx
$ systemctl enable nginx
$ systemctl status nginx

PHP インストール

$ yum install yum-utils
$ yum-config-manager --enable remi-php72
$ yum install php php-fpm php-common php-xml php-mbstring php-json php-zip

$ systemctl start php-fpm
$ systemctl enable php-fpm
$ systemctl status php-fpm

ソケット通信対応のため下記変更

$ vim /etc/php-fpm.d/www.conf
/etc/php-fpm.d/www.conf
...
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
;listen = 127.0.0.1:9000
listen = /var/run/php-fpm/php-fpm.sock
...


...
listen.owner = nginx
listen.group = nginx
...

再起動

$ systemctl restart php-fpm 

Nginx設定

デフォルトで/etc/nginx/conf.d/*.confで読み込まれるものを下記のように追記
変更を行うと/etc/nginx/sites-enabled/*下のconfファイルも読込されるようになります。

$ vim /etc/nginx/nginx.conf
/etc/nginx/nginx.conf
...
    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
...
$ mkdir /etc/nginx/sites-available/
$ vim /etc/nginx/sites-available/example.com

ハマったポイント
fastcgi_passはwww.confの設定で変わります。
/var/run/php-fpm/php-fpm.sock127.0.0.1:9000などいろいろ設定があるみたいですが、今回は前者を採用しています。

/etc/nginx/sites-available/example.com
server {
    listen 80;
    listen [::]:80;

    server_name example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    include snippets/ssl-example.com.conf;
    include snippets/ssl-params.conf;

    root /var/www/html/example.com/public;

    index index.php index.html index.htm index.nginx-debian.html;

    server_name example.com;

    location / {
            try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
            deny all;
    }

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/letsencrypt;
    }
}

Certbot インストール ~ 証明書発行

いよいよLet's Encryptから証明書発行してもらいます。

$ yum install epel-release
$ yum install certbot

$ systemctl stop nginx
$ mkdir /var/www/letsencrypt
$ certbot certonly --webroot --webroot-path=/var/www/letsencrypt -d example.com
$ systemctl start nginx

シンボリックリンクで/etc/nginx/sites-enabled/を読み込まれるようにします。

$ mkdir /etc/nginx/sites-enabled/
$ ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

certbotコマンドで作成された証明書を下記ファイルに記入

$ vim /etc/nginx/snippets/ssl-example.com.conf
/etc/nginx/snippets/ssl-example.com.conf
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

SSLの諸設定を下記ファイルで設定

$ openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
$ vim /etc/nginx/snippets/ssl-params.conf
/etc/nginx/snippets/ssl-params.conf
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:60m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;

#ssl_session_timeout 5m;

resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options nosniff;

ssl_dhparam /etc/ssl/certs/dhparam.pem;

Nginx 再起動

$ systemctl restart nginx

ここまでするとhttpsで見れると思います。


Cron設定

3ヶ月毎の更新のためのCron設定

certbotコマンドのフルパスを確認します。

$ which certbot
/usr/bin/certbot
$ crontab -e
00 04 01 * * root /usr/bin/certbot renew --webroot-path=/var/www/letsencrypt --post-hook "systemctl reload nginx"

これで大丈夫なはず!。。