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
コメント