近年Webサイトを構築する場合、基本的にHTTPではなく、よりセキュアなHTTPS(SSL/TLS)を標準として使用することが推奨されています。
実際、現在Googleの検索順位付けにはHTTPSが使用されているかによっても変化することが公表されています。 (2014年のこと)
今回の記事ではnginxをWebサーバーとして使っている環境で最強のHTTPSサーバーを設定する方法と、Cloudflareを利用しているサーバーで同様に最強のHTTPSサーバーを設定する方法について書いておきます。
目標としてはSSL LabsのSSL Server Testで最高評価のA+をとることにします。
モチベーション
https://twitter.com/FL1NE/status/1252628595480002560nginxのコンフィグで、HTTPのポートである80のアクセスをすべてHTTPSでリダイレクト(301)するようにした際、コメントで「#二度とHTTPなんか使うな」と書いたのがきっかけ。
#がコメントなのでそのままTwitterへ持ってきたらハッシュタグになってしまった。
また、Googleは以前より常時HTTPSを推進しており、最近のChromeではHTTPSに対応していないサイトで「保護されていない通信」と表示させるようにしたり、HTTPSとHTTPが混合するサイトでHTTPをブロッキングしたりするようになりました。
そして、HTTPSに対応していないことは結果としてLighthouseのスコアを下げ、検索順位にも影響すると考えられています。
今の時代のWebサイトに正しいHTTPS実装はもはや必須の存在です。
もう二度と「#二度とHTTPなんか使うな」
事前要件
必要な前知識
- Linuxのオペレーションができる
- nginxでWebサーバーが建てられる
必要な環境
- Let’s Encryptや購入した証明書でHTTPS接続できるnginxのWebサーバー
(Cloudflareを使っている場合は下のほうにある「Cloudflareを使っている場合」をみるとよいです)
事前検証
設定を変更する前に、今回はFRONTL1NEの子サイトでもあるLANDING PADⒽに対してSSL強度の測定をします。
測定にはSSL LabsのSSL Server Testを利用しています。
測定結果です。
そこまで悪くないですね。というのもちょっと前までA+だったのですが、推奨されるTLSのバージョンが一部切り捨てられたのでBとなっているようです。
結構nginxでHTTPS対応してすぐ計測したりすると最低評価のFだったりすることがおおいです。
計測結果に表示されていたメッセージを読むとどうやらSSL Labsの評価基準変更によってTLS 1.0とTLS 1.1をサポートしているときにBとなるようです。
もうTLS 1.0/1.1は無効化することが決定しており、今ではほとんど使われていないので無効化するのと、それに合わせて他の設定も最新の基準を満たすよう変更していきます。
TLS 1.0/1.1の無効化について詳しく知りたい場合、さくらインターネット様のページで解説されています。
ついにTLS 1.0/1.1の無効化が決定!影響や確認・対応方法とは? | さくらのSSL
nginxの設定変更
基本的にQiitaに投稿されているこちらの記事が一番わかりやすいです。
こちらを参考に設定変更を行なっていきます。
server { listen 443 ssl http2; server_name hatsuka.frontl1ne.net; charset utf-8; ssl_certificate /etc/letsencrypt/live/rtx1911.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/rtx1911.net/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl on; ssl_prefer_server_ciphers on; ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; ssl_dhparam /etc/nginx/ssl/dhparam.pem; ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/rtx1911.net/fullchain.pem; resolver 8.8.8.8; add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains;'; disable_symlinks off; #(残りは省略) }
元はこんな感じのconfigでちょっと前までA+判定でした。 (nginxのコンフィグファイルは大体の場合/etc/nginx/conf.d
などにあります)
これを
server { listen 443 ssl http2; server_name hatsuka.frontl1ne.net; charset utf-8; ssl_certificate /etc/letsencrypt/live/rtx1911.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/rtx1911.net/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers 'HIGH !aNULL !eNULL !kECDH !DSS !MD5 !EXP !PSK !SRP !CAMELLIA !SEED !RSA'; ssl_dhparam /etc/nginx/ssl/dhparam.pem; ssl_ecdh_curve secp384r1; ssl_session_cache shared:SSL:10m; ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/rtx1911.net/fullchain.pem; add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains;' always; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; disable_symlinks off; #(残りは省略) }
こんな感じで書き換えました。
大きく変わったところとしては
ssl_protocols TLSv1.2 TLSv1.3;
前までTLSv1 TLSv1.1 TLSv1.2
をサポートしていましたが、1.2以前をバッサリと切った形になります。
ssl_ciphers 'HIGH !aNULL !eNULL !kECDH !DSS !MD5 !EXP !PSK !SRP !CAMELLIA !SEED !RSA';
以前は、SSLで使用する暗号化スイートをほとんど手動で設定していましたが、今はこの様に指定できます。
内容としてはHIGH
で強度が高いものを使用することになり、残りは!
の論理否定で強度が弱いとされるものを個別に弾いています。
といった部分です。
これらの設定を流用する場合、ssl_certificate
や ssl_certificate_key
、 ssl_dhparam
、ssl_trusted_certificate
などで指定する証明書を自分のものに置き換えればいいです。
そして最後に…
# HTTP server server { listen 80; #二度とHTTPなんか使うな location / { # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response. return 301 https://$host$request_uri; } } #(以下省略)
この記事のタイトルである「#二度とHTTPなんか使うな」ですが、/etc/nginx/conf.d/default.conf
の様なポート80で受け付ける設定が書かれているコンフィグファイルに、全てのアクセスを301リダイレクトでHTTPSの同じアドレスへと転送する様に書いておきましょう。
設定終了後はnginxを再起動する必要があります。
systemctl restart nginx
で再起動しておきましょう。
設定後検証
設定後、再び測定を行なったところ、無事A+になることができました。
(もしも、Bなどの低いスコアとなった場合、他のnginxのコンフィグに引きずられていないかなどを確認してみてください)
Cloudflareを使っている場合
このサイト(FRONTL1NE.NET)はCDNとしてCloudflareを利用していますが、その場合はもうちょい楽です。
まず、Cloudflareのページにアクセスします。
SSL/TLSのメニューから暗号化モードがフルまたはフル (厳密) などになってHTTPS通信が行えていることを確認します。
その後「エッジ証明書」のタブから以下の様に設定を変更します。
(HSTS設定前の警告画面などはしっかり確認しましょう!)
常に HTTPS を使用 : オン
HTTP Strict Transport Security (HSTS)
ステータス: オン
Max-Age: 6 月 (推奨)
サブドメインを含める: オフ
プリロード: オン
最小 TLS バージョン : TLS 1.2
(デフォルトが1.0ですが、1.0/1.1は終わるので1.2を最小にします)
日和見暗号化 : オン
TLS 1.3 : オン
HTTPS の自動リライト : オン
これだけでほとんどの場合A+になります。
Cloudflareが暗号化スイートの設定などをよしなにしてくれるのでかなり楽でした。
参考サイト
SSL Labs Grade Change for TLS 1.0 and TLS 1.1 Protocols | Qualys Blog
ついにTLS 1.0/1.1の無効化が決定!影響や確認・対応方法とは? | さくらのSSL
コメント