じゃあ ssl_ciphers (SSLCipherSuite) は何を指定したらいいの!? って話

今やサーバ証明書なんてLet’s Encryptあたりを使用すればフリーだしHTTP/2だとかApp Transport Securityだとかでなにかと必要になってくるSSL/TLS関連の設定。

よく見る注意事項としてSSLv2, SSLv3の無効化、弱いアルゴリズム(RC4など)を使用しないなどがありますが、じゃあ結局Cipher Suiteは何を指定したらいいんだよ!って思うんです。

Nginxだと ssl_ciphers、Apacheだと SSLCipherSuite の項目です。

"HIGH" なんて指定しても「どこがHIGHなの?」という雑な設定になるし、そこから脆弱なものを除外していくのも大変すぎます。

試しにどのCipher Suiteが設定されるかの確認。

$ openssl ciphers -v 'HIGH'

そこで2017年1月現在でのブラウザやその手のクライアントで大体サポートされてるECDH(楕円曲線ディフィー・ヘルマン鍵共有)をベースに指定して簡潔に書こうということです。
ここではECDHにはEphemeral ECDH(動的生成する一時的なECDH)という "EECDH" (※1)を指定します。

※1. openssl 1.0.2以降だと "EECDH" "ECDHE" どちらでも指定できますがCentOS 7でもopenssl 1.0.1eが使われていたので下位互換ということで "EECDH" です。

$ openssl ciphers -v 'EECDH'
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(256)  Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(256)  Mac=AEAD
ECDHE-RSA-AES256-SHA384        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA384
ECDHE-ECDSA-AES256-SHA384      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA384
ECDHE-RSA-AES256-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA1
ECDHE-ECDSA-AES256-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA1
ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(128)  Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(128)  Mac=AEAD
ECDHE-RSA-AES128-SHA256        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA256
ECDHE-ECDSA-AES128-SHA256      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA256
ECDHE-RSA-AES128-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA1
ECDHE-ECDSA-AES128-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA1
ECDHE-RSA-RC4-SHA              SSLv3    Kx=ECDH  Au=RSA    Enc=RC4(128)     Mac=SHA1
ECDHE-ECDSA-RC4-SHA            SSLv3    Kx=ECDH  Au=ECDSA  Enc=RC4(128)     Mac=SHA1
ECDHE-RSA-DES-CBC3-SHA         SSLv3    Kx=ECDH  Au=RSA    Enc=3DES(168)    Mac=SHA1
ECDHE-ECDSA-DES-CBC3-SHA       SSLv3    Kx=ECDH  Au=ECDSA  Enc=3DES(168)    Mac=SHA1
ECDHE-RSA-NULL-SHA             SSLv3    Kx=ECDH  Au=RSA    Enc=None         Mac=SHA1
ECDHE-ECDSA-NULL-SHA           SSLv3    Kx=ECDH  Au=ECDSA  Enc=None         Mac=SHA1

この一覧で特に使用したいのがEnc=AESGCM、逆に使用するべきでないEnc=RC4, None。これらをまとめて指定するために以下のようにします。

$ openssl ciphers -v 'EECDH+AESGCM:EECDH+AES256'
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(256)  Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(256)  Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(128)  Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(128)  Mac=AEAD
ECDHE-RSA-AES256-SHA384        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA384
ECDHE-ECDSA-AES256-SHA384      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA384
ECDHE-RSA-AES256-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA1
ECDHE-ECDSA-AES256-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA1

すっきりですね。優先順位(※2)もTLSv1.2 Enc=AESGCM(256)が上に来るので強度も申し分ないです。

'EECDH:!RC4:!NULL' ではなく 'EECDH+AESGCM:EECDH+AES256' としたのはAESGCMを先にもってこないと優先順位が変わって一部のブラウザで “接続エラー INADEQUATE_SECURITY” (※3)がでるためです。
また、下位互換のためのTLSv1 ECDHE-RSA(ECDSA)-AES256-SHAがあるので相当ダメなクライアント以外は問題がでません。

ついでに言うなら鍵生成時のRSA・ECDSAどちらでも対応できます。

※2. ssl_prefer_server_ciphers (SSLHonorCipherOrder) on でCipher Suiteの優先順位を指定している場合です。
※3. HTTP/2の場合はTLSv1.2を使用する必要がある (HTTP/2 over TLS/1.2)。

と、ここで終わってもいいのですが今のところAES128+SHA256で十分な強度ですし、パフォーマンスを考慮するならAES128を上に持ってくる方がほんの少し(数%~10%)だけ速いので以下のようにすれば良いと思います。
github.com を見てみるとAES128の優先順位を高くしてますしね。

$ openssl ciphers -v 'EECDH+AESGCM+AES128:EECDH+AESGCM:EECDH+AES128:EECDH+AES256'
ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2 Kx=ECDH  Au=RSA    Enc=AESGCM(128)  Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2 Kx=ECDH  Au=ECDSA  Enc=AESGCM(128)  Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2 Kx=ECDH  Au=RSA    Enc=AESGCM(256)  Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2 Kx=ECDH  Au=ECDSA  Enc=AESGCM(256)  Mac=AEAD
ECDHE-RSA-AES128-SHA256        TLSv1.2 Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA256
ECDHE-ECDSA-AES128-SHA256      TLSv1.2 Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA256
ECDHE-RSA-AES128-SHA           SSLv3 Kx=ECDH    Au=RSA    Enc=AES(128)     Mac=SHA1
ECDHE-ECDSA-AES128-SHA         SSLv3 Kx=ECDH    Au=ECDSA  Enc=AES(128)     Mac=SHA1
ECDHE-RSA-AES256-SHA384        TLSv1.2 Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA384
ECDHE-ECDSA-AES256-SHA384      TLSv1.2 Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA384
ECDHE-RSA-AES256-SHA           SSLv3 Kx=ECDH    Au=RSA    Enc=AES(256)     Mac=SHA1
ECDHE-ECDSA-AES256-SHA         SSLv3 Kx=ECDH    Au=ECDSA  Enc=AES(256)     Mac=SHA1

最終的にあまり短くなったとは言えませんがNginxの設定は以下のようにしています。

server {
    listen 443 ssl http2;
    ssl                       on;
    ssl_prefer_server_ciphers on;
    ssl_protocols             TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers               EECDH+AESGCM+AES128:EECDH+AESGCM:EECDH+AES128:EECDH+AES256;
    ...
}

コメントを残す

メールアドレスが公開されることはありません。