SSL/TLSエラー:Discourseへの接続時に非常に古いブラウザで発生

デフォルトの Let’s Encrypt サポートを使用して Discourse インスタンスを設定した後、一部のユーザーからブラウザが Discourse との安全な接続を確立できないという報告を受けました。あるユーザーから提供されたスクリーンショットは、明らかに SSL/TLS エラーを指し示しています。これはブラウザ側のエラーであり、ユーザーは Discourse のコンテンツを一切表示できません。

文脈から判断すると、これらのユーザーは比較的古いオペレーティングシステムやブラウザを使用しているようです。最初は TLS 1.2 のサポートが問題ではないかと疑いましたが、確認したユーザーは不明なバージョンの macOS で Safari 10.1.2 を実行しており、Can I use... Support tables for HTML5, CSS3, etc によると、Safari はバージョン 7 から TLS 1.2 をサポートしているはずです。

TLS 1.2 以外の理由で、デフォルトの Let’s Encrypt 経由の TLS サポートを使用するデフォルトの Discourse 設定に対してブラウザやオペレーティングシステムが安全な接続を確立できない要因は他にありますか?ユーザーに何を尋ねるべきか、問題がどちら側(クライアント側かサーバー側か)で解決すべきかを特定するために、どのような質問をすべきか検討しています。

回避策として、デフォルトでは http へのトラフィックが https にリダイレクトされるようです。まずチェックを行う方法、例えば「ブラウザが TLS 1.2 をサポートしている場合のみ」や「ブラウザ/OS のバージョンが特定のバージョン以上の場合のみ」にリダイレクトし、それ以外の場合は http のままにするような設定は可能でしょうか?

設定に誤りがないか確認するための参考 URL は以下の通りです:https://forum.stadtteilgenossenschaft-wik.de

SSL サーバーテスト(SSL Server Test)を使用して、サイトをテストできます。テスト結果には「Handshake Simulation」というセクションがあり、動作する/動作しないブラウザと OS の組み合わせが表示されます。

最新の Docker イメージでは、以下の TLS 設定が表示されます。

ユーザーには、ブラウザや OS のバージョン、サポートされている TLS バージョンの詳細を確認するために、https://www.ssllabs.com/ssltest/viewMyClient.html へアクセスしてもらうことができます。

詳細なご回答をありがとうございます!

SSL サーバーテストを実行しましたが、結果に問題は見当たりませんでした:

ご指摘の通り、結果はあなたの投稿にあるものと同じようです。

唯一の失敗は、古い OS と Safari のバージョン(Safari 8+9)および古い Windows バージョンの IE 11 に対するものでした。特に IE 11 について少し懸念しています。Discourse は IE 11 をサポートし、デフォルトで TLS 1.2 もサポートするべきではないでしょうか?

また、このテストには、現在もサポートされている最も古い OS 上の Safari 10 に対するテストが含まれていません。そのため、これも失敗している可能性があります…

古い Windows バージョンをお使いのユーザーは、CBC 暗号を有効にする必要があるかもしれません:

次に、以下のリンクにそのユーザーを案内してください。

ブラウザがサポートしている情報を取得するためです。結果を共有する最も簡単な方法は、おそらく PDF として印刷してあなたに送ってもらうことです。

ありがとうございます、ユーザーから返信がありました。彼らは非常に古い iPod Touch を使用しています:

ブラウザの SSL/TLS 機能
ユーザーエージェント: Mozilla/5.0 (iPod; CPU iPhone OS 6_1_6 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B500 Safari/8536.25

プロトコルサポート

ユーザーエージェントは優れたプロトコルサポートを持っています。

ユーザーエージェントは TLS 1.2 をサポートしており、これは現在推奨されるプロトコルバージョンです。

したがって、これは古いデバイスであり(Discourse の最低サポート OS+ ブラウザから遠く離れていることは承知しています)、彼らがサイトへ最低限接続し、ブラウザが最新の HTML や JavaScript とどのようにやり取りするかを確認できるようにしたいと考えています。

これが詳細な TLS サポートレポートです:

プロトコル機能

プロトコル

TLS 1.3 いいえ
TLS 1.2 はい
TLS 1.1 はい
TLS 1.0 はい
SSL 3 はい
SSL 2 いいえ

暗号スイート(優先順位順)

TLS_EMPTY_RENEGOTIATION_INFO_SCSV ( 0xff ) -
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 ( 0xc024 ) WEAK 256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 ( 0xc023 ) WEAK 128
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ( 0xc00a ) WEAK 256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA ( 0xc009 ) WEAK 128
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA ( 0xc007 ) INSECURE 128
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA ( 0xc008 ) WEAK 112
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 ( 0xc028 ) WEAK 256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ( 0xc027 ) WEAK 128
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ( 0xc014 ) WEAK 256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ( 0xc013 ) WEAK 128
TLS_ECDHE_RSA_WITH_RC4_128_SHA ( 0xc011 ) INSECURE 128
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA ( 0xc012 ) WEAK 112
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 ( 0xc026 ) WEAK 256
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 ( 0xc025 ) WEAK 128
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 ( 0xc02a ) WEAK 256
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 ( 0xc029 ) WEAK 128
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA ( 0xc004 ) WEAK 128
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA ( 0xc005 ) WEAK 256
TLS_ECDH_ECDSA_WITH_RC4_128_SHA ( 0xc002 ) INSECURE 128
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA ( 0xc003 ) WEAK 112
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA ( 0xc00e ) WEAK 128
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA ( 0xc00f ) WEAK 256
TLS_ECDH_RSA_WITH_RC4_128_SHA ( 0xc00c ) INSECURE 128
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA ( 0xc00d ) WEAK 112
TLS_RSA_WITH_AES_256_CBC_SHA256 ( 0x3d ) WEAK 256
TLS_RSA_WITH_AES_128_CBC_SHA256 ( 0x3c ) WEAK 128
TLS_RSA_WITH_AES_128_CBC_SHA ( 0x2f ) WEAK 128
TLS_RSA_WITH_RC4_128_SHA ( 0x5 ) INSECURE 128
TLS_RSA_WITH_RC4_128_MD5 ( 0x4 ) INSECURE 128
TLS_RSA_WITH_AES_256_CBC_SHA ( 0x35 ) WEAK 256
TLS_RSA_WITH_3DES_EDE_CBC_SHA ( 0xa ) WEAK 112
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ( 0x67 ) WEAK 128
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 ( 0x6b ) WEAK 256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA ( 0x33 ) WEAK 128
TLS_DHE_RSA_WITH_AES_256_CBC_SHA ( 0x39 ) WEAK 256
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ( 0x16 ) WEAK 112
TLS_ECDHE_ECDSA_WITH_NULL_SHA ( 0xc006 ) INSECURE 0
TLS_ECDHE_RSA_WITH_NULL_SHA ( 0xc010 ) INSECURE 0
TLS_ECDH_ECDSA_WITH_NULL_SHA ( 0xc001 ) INSECURE 0
TLS_ECDH_RSA_WITH_NULL_SHA ( 0xc00b ) INSECURE 0
TLS_RSA_WITH_NULL_SHA256 ( 0x3b ) INSECURE 0
TLS_RSA_WITH_NULL_SHA ( 0x2 ) INSECURE 0
TLS_RSA_WITH_NULL_MD5 ( 0x1 ) INSECURE 0
(1) ブラウザが SSL 2 をサポートしている場合、SSL 2 のみスイートは、このサイトへの最初の接続時のみ表示されます。スイートを確認するには、すべてのブラウザウィンドウを閉じ、その後このページを直接開いてください。更新しないでください。

プロトコル詳細

サーバー名インジケーション (SNI) はい
セキュア再ネゴシエーション はい
TLS 圧縮 いいえ
セッションチケット いいえ
OCSP ステープリング いいえ
署名アルゴリズム SHA384/RSA, SHA256/RSA, SHA1/RSA, SHA256/ECDSA, SHA1/ECDSA
名前付きグループ secp256r1, secp384r1, secp521r1
次のプロトコルネゴシエーション いいえ
アプリケーション層プロトコルネゴシエーション いいえ
SSL 2 ハンドシェイク互換性 いいえ

混合コンテンツ処理

混合コンテンツテスト
画像 パッシブ はい
CSS アクティブ はい
スクリプト アクティブ はい
XMLHttpRequest アクティブ はい
WebSockets アクティブ はい
フレーム アクティブ はい
(1) これらのテストにより、ブラウザで混合コンテンツの警告が表示される可能性があります。これは正常です。
(2) テストに失敗した場合、ページを再読み込みしてみてください。エラーが解消しない場合は、ご連絡ください。

フォーマットの乱れについてお詫び申し上げます。ユーザーがリッチテキストの HTML をコピー&ペーストしてくれたため、Discourse に貼り付けた際に一部が失われてしまいました。後でフォーマットの修正方法を検討します。

前述の通り、彼らが最低限安全な接続を確立し、何か表示されるようにしたいと考えています。ブラウザが TLS 1.2 をサポートしているため、これは可能であるはずです。しかし、おそらくこのブラウザをサポートするには、TLS 1.2 に対していくつかのセキュリティレベルが低い設定を有効にする必要があるでしょう。TLS の専門家ではないため、このレポートの出力とサーバーがサポートする設定、そして変更すべき事項を照合する方法がわかりません。何が不足しており、何を設定変更すべきか教えていただけますか?

おおよその意味は理解できましたが、具体的な方法がわかりません。Discourse の Docker コンテナの TLS 設定を変更してこれらを有効にする方法を説明するドキュメントをご案内いただけますでしょうか?

TLS 関連の問題を暗号スイートを追加することで解決したとしても、Safari 6 が動作するとは思えません。

nginx 設定ファイルをオーバーライドすることで、不足している暗号スイートを追加できます。app.ymlhooks セクションに以下のスニペット(未検証ですが、動作するはずです)を追加し、ssl_ciphers の値をお好みのものに変更してください。

  after_ssl:
    - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
        from: /ssl_ciphers .*/
        to: ssl_ciphers <your_complete_cipher_list>;

余談ですが、Discourse に楕円曲線証明書へのサポートを追加しようとしています。これにより、IE11 でも最初から動作するようになります。

iOS 6 !?最後のバージョンは2014年初頭にリリースされました!それは5年以上も前のことです!

わかります、私もあなたと同じくらい驚きました。それがサポートされることを期待しているわけではありませんが、ユーザーには少なくとも一部の HTML を表示し、何が動作して何が動作しないかを確認してもらいたいと考えています。

@gerhard さん、ありがとうございます。説明された通り /var/discourse/containers/app.yml(これが正しい app.yml ファイルであることを願っています)を変更し、その後 app.yml のコメントに記載されている通り /var/discourse/launcher rebuild app を実行しました。

その後、ssllabs.com でテストを再実行しましたが、結果は変わらなかったようです:https://www.ssllabs.com/ssltest/analyze.html?d=forum.stadtteilgenossenschaft-wik.de&s=68.183.214.228&hideResults=on

設定変更が実際に機能したのか(ただしテスト結果には影響しませんでした)、それとも機能しなかったのかを確認する方法がわかりません。

あ、@gerhard さんの投稿をちゃんと読んでいませんでした。私の理解が合っていれば、ご提示いただいた設定で使用する暗号スイートを明示することになりますが、使われている値は基本的にデフォルトと同じですよね?だとすると、古いブラウザでサポートされている可能性のある他の暗号スイートも追加で設定する必要があります。

はい、その通りです。設定に弱い暗号を追加する解決策を投稿したくありませんでした。これはご自身で対応してください。:wink:

ただし、その変更を行う場合は、以前触れたプルリクエストを注視しておくことをお勧めします。マージされれば、IE11 はそのまま動作するようになります。

なるほど、設定を簡単にしすぎてセキュリティを犠牲にするのは避けたいのですね。その考えには賛成です。私も完全なコードを公開することは控えさせていただきます。

現状の進捗をお伝えします。まず、https://www.ssllabs.com/ssltest/viewClient.html?name=Safari&version=6&platform=iOS%206.0.1&key=33(および他のブラウザ/OS)を参照し、古いブラウザや OS をサポートするために不足している暗号スイート(cipher suites)を特定しました。クライアントが提示する暗号スイートは優先順でリストされているため、私は常に最上位のものを採用し、サーバーがそのリスト内のいずれかをサポートしていれば十分だと仮定して対応しました。私が特定した暗号は以下の通りです:

  • Safari 6-8 用:ECDHE-ECDSA-AES256-CBC-SHA384
  • Windows 7/8.1/Phone 8.1 Update 上の IE 11 用:ECDHE-RSA-AES256-CBC-SHA384@supermathie 氏による情報)
  • Windows Phone 8.1 上の IE 11 用:ECDHE-RSA-AES128-CBC-SHA256

これらの値を ssl_ciphers のリストの末尾にコロンで区切って追加しました。「リストの末尾」ということは「最も優先度が低く、クライアントが他の暗号をサポートしていない場合のみ使用される」という意味だと解釈しました。その後、設定を適用するために /var/discourse/launcher rebuild app を実行し、キャッシュをクリアした上で SSL Server Test (Powered by Qualys SSL Labs) で再度テストを実行しましたが、結果は変わりませんでした。

失敗していた IE 11 のテストおよび Safari 6-8 のテストの両方で、今度はハンドシェイクが成功すると思っていたのですが、まだ失敗したままです。何か見落としているに違いありません。

また、私のユーザーの一人は iOS 9 / Safari 9 を搭載した iPhone を使用しており、彼らにとっても接続が失敗しています。しかし、SSL Labs のテスト結果によると、この接続は最初から問題なく動作するはずです(@gerhard 氏の上記の結果でも確認できます)。

つまり、私は以下の 2 つの点を理解できていません:

  1. なぜ暗号のサポートを追加しても接続が依然として機能しないのか?
  2. なぜ SSL Labs は iOS 9 + Safari 9 での動作を示しているのに、実際には私のユーザーでは動作しないのか?

1 について:設定を正しく適用できたかどうか、まだ確信が持てません。SSL Labs テストの他に、サーバーがどの暗号をサポートしているかを確認し、設定変更が正しく反映されたかどうかを検証する方法は他にありますでしょうか?

SSLLabの結果を詳しく見てみると、これはうまくいっていないようです。

設定を適用して再構築した後、私のサーバーで SSLLab に表示される結果は以下の通りです。

私の理解では、設定に多くのオプションが含まれているため、もっと多くの項目がリストされるはずです。これは、この設定変更が機能しなかったことを意味するのでしょうか?

選んだ暗号スイートの名称が間違っていると思います。SSL サーバーテストでリストされている暗号スイートと、OpenSSL(nginx)で使用されている名称とのマッピングについては、Mapping OpenSSL cipher suite names to IANA names が優れたリソースです。

私のテストでは :ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA を追加し、再ビルド後にテスト結果は以下のようになりました:

もしかするとテスト側にバグがあるのかもしれませんね:man_shrugging: 私はそのような古い Safari をテスト用に持っていません。私たちがサポートしているのは Safari 10 以降のみです。依然として TLS エラーが原因で失敗していることを確信していますか?

ありがとうございます、試してみます!

Discourse の設定ファイルをもう少し詳しく見てみたところ、templates/web.ssl.template.yml が見つかりました。app.yml ファイルを通じて暗号スイートを変更する方法と、templates/web.ssl.template.yml 内の ssl_ciphers リストを直接変更する方法の違いは何でしょうか?

テンプレートはバージョン管理されていますが、app.yml は管理されていません。テンプレートを編集すると、リポジトリの更新時に問題が発生します。

ありがとうございます。これが問題でした。名称を修正したところ、SSLLabs のリストにあるすべてのブラウザでハンドシェイクが正常に動作するようになりました。忍耐強くサポートしていただき、本当にありがとうございます!

さて、古いブラウザで HTTPS エラーを乗り越えたユーザーが実際に見ているものが気になりますね。:smiley: