じゃあ 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;
    ...
}

Firefoxの「すべての表示したページの履歴」を1発で消す.uc.xul

ucjs_clear_history

動作確認

キャッシュを消すやつ作ってたらこれもあったらいいんじゃないかってことです。
「表示したページの履歴」としてますが「ダウンロード履歴」も消えます。わりと適当です。

あと履歴が多いと消すのに時間が掛かってFirefoxが固まります。

ダウンロード: clear_all_page_history.uc.js for Firefox 27

ダウンロード: clear-all-history-fx50.uc.xul for Firefox 50

  • 2017.01.05 Firefox 50でも動くように書き直し
<?xml version="1.0" encoding="UTF-8"?>
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript"><![CDATA[
var ucjsHistoryClear = function() {
    try {
        PlacesUtils.history.clear();
    } catch (e) {
    }
}
]]></script>
<menupopup id="menu_ToolsPopup">
    <menuitem id="menu_ucjsHistoryClear"
              label="表示したページの履歴を消去"
              oncommand="ucjsHistoryClear()"/>
</menupopup>
</overlay>