無料SSLのLet’s Encryptの普及により、もはやサイトの常時SSLは常識となりつつあるが、常時SSL化したからといって安心してはいられない。
SSLのバージョンや「暗号スイート(Cipher Suites)」という暗号アルゴリズムの組み合わせのしかたにより、せっかく常時SSLを導入しても脆弱性が残ってしまう。
というわけで常時SSLのセキュリティを更に高める方法を解説していく。
※動作確認環境
CentOS Linux 7.6
Nginx version 1.14.2
BIND version 9.9.4
Let’s Encryptで常時SSL化済み
サイトのSSL安全性をチェック
「SSL Server Test」を実行
まず、Qualys SSL LABSの「SSL Server Test」で自分のサイトのSSLをチェックする。
※「SSL Server Test」は世界的に有名なSSL暗号化の安全性をチェックするための無料ツールで、誰でもWEBから簡単に利用できます。
SSL Test – SSL Server Test (Powered by Qualys SSL Labs)
https://www.ssllabs.com/ssltest/
「Hostname」に自分のドメインを入力し、「Do not show the results on the boards」にチェックを入れて「Submit」をクリックするだけです。
※「Do not show the results on the boards」にチェックを入れないとテスト結果が公開されてしまい、もし脆弱性があるSSL設定だった場合は公開されたらマズイので必ずチェックを入れましょう。
1分ほど待つとSSLのテスト結果が表示されます。
既に「A+」の評価をもらっているので完璧のような気がするが、チェック結果の詳細を見て更に完璧を目指していきます。
チェック結果の解析
このチェックを行った際のnginx.confの設定は以下のとおりです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
server { server_name onoredekaiketsu.com; ...省略... #SSL設定 listen 150.95.212.180:443 ssl http2 default_server; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_certificate /etc/letsencrypt/live/onoredekaiketsu.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/onoredekaiketsu.com/privkey.pem; ssl_dhparam /etc/nginx/ssl/dhparam.pem; ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/onoredekaiketsu.com/fullchain.pem; resolver 8.8.8.8; add_header Strict-Transport-Security 'max-age=31536000; includeSubonoredekaiketsu.coms;'; } |
この設定でのチェック結果をスクロールして順に見ていきます。
Certificate #1: RSA 2048 bits (SHA256withRSA)
Server Key and Certificate #1の「DNS CAA」が赤文字で「No」になっています。
ここは問題無し。
Configuration
Protocols(プロトコル)の部分の「TLS 1.0」と「TLS 1.1」が赤文字で「Yes」になっています。
Handshake Simulationの部分に「TLS 1.0」と「TLS 1.1」が赤文字でたくさん表示されています。
Protocol Detailsの「Session resumption (caching)」が赤文字で「No (IDs assigned but not accepted)」と表示されています。
ここは問題無し。
対策が必要な項目
- Server Key and Certificate #1の「DNS CAA」
- Protocols(プロトコル)の「TLS 1.0」と「TLS 1.1」
- Handshake Simulationの「TLS 1.0」と「TLS 1.1」
- Protocol Detailsの「Session resumption (caching)」
対策が必要なのはこの4つですね。
対策開始
DNS CAAレコードをBINDに設定
DNS CAAレコードとは、ドメインのSSL証明書に署名を許可する認証局(CA:Certification Authority)を指定するDNSエントリです。CAAレコードで認証局を指定することによりSSL証明書の改ざんを防ぐことができます。
まず、CAAレコードを作成します。
今回は「CAA Record Helper」を利用してCAAレコードを作成していきます。
■CAA Record Helper
https://sslmate.com/caa/
「1. Enter Your Domain Name」にドメイン名を入力し、「2. Select Authorized Certificate Authorities」では許可する認証局を選択します。
※ワイルドカード証明書を利用している場合は「Wildcard」にもチェック。
※「3. Incident Reporting (Optional)」は任意です。
すると「4. Publish Your CAA Policy」にDNSサーバの種類別でCAAレコードが生成されて表示されます。
当方の環境は「BIND version 9.9.4」なので、「Legacy Zone File (RFC 3597 Syntax)」の
1 2 |
onoredekaiketsu.com. IN TYPE257 \# 22 000569737375656C657473656E63727970742E6F7267 onoredekaiketsu.com. IN TYPE257 \# 12 0009697373756577696C643B |
を、vi等で「/var/named/onoredekaiketsu.com.hosts」の末尾あたりに追加してBINDを再起動します。※vi等で直接編集した場合はシリアルナンバーの増加も忘れずに。
1 |
# vi /var/named/onoredekaiketsu.com.hosts |
1 |
# systemctl restart named |
以上でBINDのCAAレコード設定は完了です。
プロトコルの「TLS 1.0」と「TLS 1.1」を無効化
Nginxのserverディレクティブで「TLS 1.0」と「TLS 1.1」を無効化します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
server { server_name onoredekaiketsu.com; ...省略... #SSL設定 listen 150.95.212.180:443 ssl http2 default_server; ssl_protocols TLSv1.2; #TLSv1とTLSv1.1を削除 ssl_prefer_server_ciphers on; ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_certificate /etc/letsencrypt/live/onoredekaiketsu.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/onoredekaiketsu.com/privkey.pem; ssl_dhparam /etc/nginx/ssl/dhparam.pem; ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/onoredekaiketsu.com/fullchain.pem; resolver 8.8.8.8; add_header Strict-Transport-Security 'max-age=31536000; includeSubonoredekaiketsu.coms;'; } |
「ssl_protocols」の部分の「TLSv1」と「TLSv1.1」を消すだけです。
Session resumption (caching)設定
Nginxのhttpディレクティブで「ssl_session_cache」と「ssl_session_timeout」の設定を追加します。
1 2 3 4 5 6 7 |
http { ...省略... ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; } |
Nginxを再起動します。
1 2 |
# systemctl restart php-fpm # systemctl restart nginx |
これで全ての設定が完了です。
再チェック
もう一度「SSL Server Test」を行ってみます。
SSL Test – SSL Server Test (Powered by Qualys SSL Labs)
https://www.ssllabs.com/ssltest/
Protocol Supportの値が100になりました。
DNS CAAが緑色の「Yes」になりました。
TLS 1.0とTLS 1.1が「No」になり赤文字の警告が消えました。
Android 4.4.2未満や古いブラウザをTLS 1.2で切り捨てたことにより赤文字の警告が全て消えました。
Session resumption (caching)が「Yes」になり赤文字の警告が消えました。
すべての警告が消えてスッキリしました。
SSLのバージョンや暗号スイート(Cipher Suites)、その他のセキュリティの仕組みはどんどんアップデートさせるので、SSLの安全性チェックは定期的に行っておきましょう。
以上で解決です。