[nginx] FuelPHPのサイトを SSL(HTTPS)化して SSL Labsで A+評価をもらう

FuelPHPで作ったサイトを SSL(HTTPS)化した際のメモです。

証明書は Let’s Encrypt のものを使います。無料で導入も楽ちんです。
最終的に SSL Labsで A+評価をいただきました。

以下の手順は、FuelPHP + nginx + CentOS7 で構築したサイトに、ドメインでアクセスできている前提になります。

CentOS7のfirewalld設定

FuelPHPはCentOS7で動かしています。

CentOS7からファイアウォールの設定は、firewalldで行うようになりました。
CentOS6まで使っていた iptablesとは使い方が違うので調べておく必要があります。

https通信を許可し、設定を反映させます。

sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload

設定後に、httpsが許可されていることを確認しましょう。

sudo firewall-cmd --list-services --zone=public --permanent
# 以下が表示されればOK
https

Let’s Encryptの証明書を生成

Let’s Encrypt は無料のSSL証明書を発行する認証局です。
certbot コマンドで証明書の生成・更新ができます。

certbot コマンド自体も、CentOS7 では yum でインストールできます。
CentOS7, nginx用の設定方法を見ながら設定します。

sudo yum install epel-release
sudo yum install certbot

certbot コマンドが使えるようになっているので、証明書を生成します。
GUIがターミナル上に表示されるので進めましょう。

sudo certbot certonly --webroot -w /var/www/it-review/public -d it-review.runble1.com --email [email protected]

生成されたファイルを確認しましょう。
4つファイルができています。

sudo ls -la /etc/letsencrypt/live/it-review.runble1.com

cert.pem:サーバ証明書
chain.pem:中間証明書
fullchain.pem:サーバ証明書と中間証明書を結合したファイル
privkey.pem:秘密鍵

nginx で使うのは fullchain.pem です。

nginxにFuelPHP用のSSL設定

FuelPHPサイト用の nginxに SSL設定を追記します。
SSL Labsで A+評価になるようにします。

sudo vim /etc/nginx/conf.d/it-review.conf

まずは全貌。

server {
    # httpでのアクセスを全てhttpsへリダイレクト
    listen 80;
    listen [::]:80;
    server_name it-review.runble1.com;
    return 301 https://it-review.runble1.com$request_uri;
}
server {
    # SSLに加えてHTTP/2を有効に
    listen 443 ssl http2;
    server_name it-review.runble1.com;

    # サーバ証明書
    ssl_certificate /etc/letsencrypt/live/it-review.runble1.com/fullchain.pem;
    # 秘密鍵
    ssl_certificate_key /etc/letsencrypt/live/it-review.runble1.com/privkey.pem;
    
    # SSLセッションキャッシュを全てのワーカープロセスで共有
    ssl_session_cache shared:SSL:30m;
    ssl_session_timeout 30m;

    # OCSP Stapling用
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/it-review.runble1.com/fullchain.pem # HSTS対応 add_header Strict-Transport-Security "max-age=31536000" always; 
 
    # 2048ビット以上で作ったDH交換鍵を指定
    ssl_dhparam /etc/ssl/private/dhparam.pem;

    # HSTS対応
    add_header Strict-Transport-Security "max-age=31536000" always;
    
    # サーバが示した暗号スイートの優先
    ssl_prefer_server_ciphers on;
    # 暗号スイート
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

    # 以下略

各項目を簡単にですが理解しておきます。

1つめの serverディレクティブでは、httpでアクセスしてきた場合の設定です。
全て https にリダイレクトします。

server {
    # httpでのアクセスを全てhttpsへリダイレクト
    listen 80;
    listen [::]:80;
    server_name it-review.runble1.com;
    return 301 https://it-review.runble1.com$request_uri;
}

2つめの serverディレクティブ内で httpsに対する設定や PHPの設定(今回は割愛)をおこないます。
SSL通信に加えて HTTP/2プロトコルを有効にしています(OpenSSL1.0.1を使用している場合は Chromeでは HTTP/2通信できません)。

server {
    # SSLに加えてHTTP/2を有効に
    listen 443 ssl http2;
    server_name it-review.runble1.com;

certbotコマンドで生成した Let’s EncryptのSSL証明書と秘密鍵を指定します。

    # サーバ証明書
    ssl_certificate /etc/letsencrypt/live/it-review.runble1.com/fullchain.pem;
    # 秘密鍵
    ssl_certificate_key /etc/letsencrypt/live/it-review.runble1.com/privkey.pem;

SSLセッションキャッシュの設定を行います。
キャッシュするとSSLの設定を使いまわして負荷軽減になります。

    # SSLセッションキャッシュを全てのワーカープロセスで共有
    ssl_session_cache shared:SSL:30m;
    ssl_session_timeout 30m;

OSCP stapingを有効にします。
OCSP(Online Certificate Status Protocol)とは、HTTPS通信で証明書の失効を確認する手順のことで、サーバ側で失効リストをキャッシュしておきます。そのためHTTP通信を高速化できます。

    # OCSP用
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/it-review.runble1.com/fullchain.pem

DH鍵を指定します。

    # 2048ビット以上で作ったDH交換鍵を指定
    ssl_dhparam /etc/ssl/private/dhparam.pem;

サーバ側から暗号スイートを指定して優先して使ってもらうよう設定しておきます。

    # サーバが示した暗号スイートの優先
    ssl_prefer_server_ciphers on;
    # 使用する暗号スイート
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

HSTSを有効化します。
サーバからブラウザへ常時HTTPSで通信するようリクエストを行う。

    # HSTS対応 serverディレクティブ内に書かないといけない
    add_header Strict-Transport-Security "max-age=31536000" always;

最後に。

SSL の共通設定は conf ファイルを別に作ってまとめておいてもいいかもしれません。
使い回せます。

# SSLセッションキャッシュを全てのワーカープロセスで共有
ssl_session_cache shared:SSL:30m;
ssl_session_timeout 30m;

# 2048ビット以上で作ったDH交換鍵を指定
ssl_dhparam /etc/ssl/private/dhparam.pem;

# OCSP Staplingを有効にする
ssl_stapling on;
ssl_stapling_verify on;

# サーバが示した暗号スイートの優先
ssl_prefer_server_ciphers on;
# 暗号スイート
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

Let’s Encryptの証明書を自動更新にする

SSL証明書は有効期限が存在します。
更新作業は、certbotコマンドで簡単に行うことができます。

root ユーザで cron を設定します。

su -

1週間に1度ぐらいの頻度で証明書の有効期限を確認し、更新をかけます。

50 3 * * 0 certbot renew --post-hook "systemctl restart nginx" >> /var/log/letsencrypt_certbot.log

参考

WordPressをLet’s Encryptで常時SSL(HTTPS)化する

Let’s Encryptの証明書を自動更新にする

WordPressのHTTPSサイトをA+評価にする

NginxでのOCSP Stapling対応設定

コメント

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