nginx 1.15.2 にアップデートしたのでnginx.confのSSL回りを見直した


このブログは

  • SSL を受けるための nginx
  • コンテンツキャッシュ用 varnish
  • コンテンツ配信用 nginx
  • 動的コンテンツ処理用 php-fpm

と多段構成になっているが、nginx を 1.14.x から 1.15.x 系に更新した。それにともなって設定回りを若干いじったのでメモっておく。

SSL on のための設定

nginx 1.15.0 以降、SSL を on にするためのディレクティブ

ssl on;

obsolete 扱いになった。1.15.0 では警告が出るだけでこの書き方でも問題ないが、将来を見据えてまずここを修正する。

新しい書き方では、listen ディレクティブに ssl オプションを追加する。このブログのフロントの場合、古い設定ファイルを使い回していたこともあって ssl on; が残っていたので、その行を削除した上で以下のように書き換える。

listen 218.219.153.92:443 ssl http2;

SSL の見直し

SSL 回りの設定は、コンピューティングリソースの向上に伴ってどんどん使うべきではない設定が移り変わっている。特に個人のブログの場合、ここのキャッチアップが後手後手になったりするので、このタイミングで見直した。

SSL プロトコルの見直し

SSLv3 および TLSv1.0 / 1.1 はいわゆる POODLE で脆弱性が指摘されたため、無効化されていることを確認しておく。また、本来は TLSv1.3 に対応したいのだが、OpenSSL は TLSv1.3 の仕様が固まるまではサポートしない (正確には TLSv1.3 をサポートする OpenSSL 1.1.1 をリリースしない; 参考: "Using TLS1.3 With OpenSSL") ので、とりあえず設定だけ書いておく。

ssl_protocols TLSv1.3 TLSv1.2;

暗号化スイートの見直し

これまで、

ssl_ciphers  ECDHE+AESGCM:DHE+AESGCM:HIGH:!aNULL:!MD5;

と割とざくっと指定していたが、暗号化強度の低いスイートも含まれていることになる。そのため、ECDHE を中心とした強度の高いもののみを許可するように書き換える。

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:AES256:AES:
             DES-CBC3-SHA:
             HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSA

また、サーバ側の暗号化スイートを優先するようにしておかないとクライアントが指定した強度の低いものを使う可能性があるので、以下を追加する。

ssl_prefer_server_ciphers on;

DNS CAA 対応

2017 年 9 月 8 日、認証局が証明書を発行する際に DNS の CAA (Certification Authority Authorization) レコードの確認が義務づけられた。これは、DNS の CAA レコードにそのドメインの証明書の発行を依頼する認証局を登録しておくことで、認証局側が証明書を発行する際に問題ないか検証できるようにするものになる。

DKIM のように鍵ペアを用意しておく必要はなく、あくまでも認証局のドメインを CAA レコードに登録しておくだけでそんなに難しくはないので、この機会に登録しておくことにした。damelog.com の場合は Let’s Encrypt を利用していてドメインのワイルドカードは使用していないので、以下のようになる。

damelog.com.	IN	CAA	0 issue "letsencrypt.org"
damelog.com.	IN	CAA	0 issuewild ";"
damelog.com.	IN	CAA	0 iodef "mailto:〜〜"

spam よけのために「〜〜」にしているが、iodef タグには連絡先を登録する。これは required ではないので、spam をよけたいのであれば必ずしも登録する必要はない。

確認

nginx と bind を再起動したら、念のため CAA レコードが指定通り設定されているか確認する。

$ dig damelog.com CAA

; <<>> DiG 9.12.1 <<>> damelog.com CAA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37408
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 4700a4cf3a3372109d2e2bb35b631fdf7ecbfedb329fcb32 (good)
;; QUESTION SECTION:
;damelog.com.			IN	CAA

;; ANSWER SECTION:
damelog.com.		300	IN	CAA	0 iodef "mailto:〜〜"
damelog.com.		300	IN	CAA	0 issue "letsencrypt.org"
damelog.com.		300	IN	CAA	0 issuewild ";"

;; Query time: 0 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Fri Aug 03 00:14:39 JST 2018
;; MSG SIZE  rcvd: 168

問題がなければ、SSL Server Test で検証する。

スコアについては、互換性とのトレードオフなのでさじ加減は重要だとは思う。ホストするサービスによってスコアを重視するのか互換性を重視するのかは慎重に検討したい。