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 インストール
```terminal
$ yum install nginx 
$ systemctl start nginx
$ systemctl enable nginx
$ systemctl status nginx
```
---

#### PHP インストール
```terminal
$ 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
```

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

```terminal
$ vim /etc/php-fpm.d/www.conf
```

```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
...
```

再起動

```terminal
$ systemctl restart php-fpm 
```

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

```terminal
$ vim /etc/nginx/nginx.conf
```

```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/*;
...
```

```terminal
$ mkdir /etc/nginx/sites-available/
$ vim /etc/nginx/sites-available/example.com
```

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

```conf:/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から証明書発行してもらいます。


```terminal
$ 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/`を読み込まれるようにします。

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

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

```terminal
$ vim /etc/nginx/snippets/ssl-example.com.conf
```

```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の諸設定を下記ファイルで設定

```terminal
$ openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
$ vim /etc/nginx/snippets/ssl-params.conf
```

```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 再起動

```terminal
$ systemctl restart nginx
```

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

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

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

```terminal
$ which certbot
/usr/bin/certbot
```


```terminal
$ crontab -e
```

```vim
00 04 01 * * root /usr/bin/certbot renew --webroot-path=/var/www/letsencrypt --post-hook "systemctl reload nginx"
```

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