一部の古いクライアントがMD5およびSHA1署名のみをサポートできるシナリオがあります。明らかに、これらは通常使用されなくなったと見なされますが、それでもサポートする必要があります。これらのクライアントをアップグレードすることはできることではありません(ファームウェアアップデートはリリースされなくなり、理想的にはこれらのデバイスをすべて終了したいのですが、それは不可能です)。
それでも、MD5 または SHA1 署名証明書を取得できるとします。
初めて接続したときにクライアントが送信したClientHelloブロックに含まれる受信TLSバージョンに基づいて、すべての(https)サーバーに異なる証明書を提供できますか?
クライアントから入ってくる最初の数バイトを読み、次に最悪のシナリオで他の要求を処理する代替ポートに接続を接続する小さな「プロキシ」を書くことは可能だと思いますが、可能であれば避けることをお勧めします。既存のWebサーバーがそのような機能をサポートしている場合です。
ナレーター:私が知っている限り、SSL / TLSプロトコルにはダウングレード攻撃に対する保護が含まれているため、サーバーが1.2をサポートし、クライアントも1.2をサポートしている場合は、1.0にダウングレードが発生した場合に接続を終了する必要があります(アクティブ状態の場合)。マンイン攻撃発生) - 中間攻撃)。これは、以前のSSL / TLSバージョンを引き続きサポートしながら、少なくともMD5またはSHA1署名証明書を提供するリスクをできるだけ減らす必要があると思います。
答え1
Lua拡張とSSL部分を含むNginxは、ハンドシェイクの開始とクライアントの送信内容に基づいて公開する証明書を選択できますが、ClientHello
これはユーザーにとって必要ではないかもしれません(サポートされているアルゴリズムのリスト)。
完全な文書は次の場所にあります。https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.mdそしてhttps://github.com/openresty/lua-nginx-module/#ssl_certificate_by_lua_block
それは次のように言います:
これは、要求ごとにSSL証明書チェーンとその秘密鍵を設定するのに特に便利です。
...
SSLv3プロトコルまたはより低いバージョンを使用する古いSSLクライアントを選択的に拒否するなど、クライアントからのSSLハンドシェイク要求でいくつかの興味深い作業を実行することもできます。
SNI部分を読み取ると、クライアントがアクセスしたいホスト名と関数を使用して、クライアントまたはraw_client_addr
サーバーIP(マルチホームIPの場合)に簡単にアクセスできます。ドキュメントによると、クライアントのClientHelloにアクセスする他の部分を見ることはできませんが、IPに基づいてクライアントを区別することができます。または2つの別々のサーバー名がある場合は、上記の解決策を見つけることができます。特定の証明書が一緒にリンクされて機能することがあります。raw_server_addr
server_name
読むhttps://github.com/openresty/lua-nginx-module/blob/master/src/ngx_http_lua_ssl_certby.cクライアントが送信した暗号スイートのリストにアクセスする具体的な方法は表示されません。ただし、このコードはopensslライブラリからすべての基本的な「SSL」情報を取得するため、必要なものは技術的に可能であると考えられますが、コーディングのみが必要です。
今2つのことがあります。
1)「まだMD5またはSHA1署名証明書を取得できると仮定します。」
これは難しいかもしれません。少なくとも基本操作で公に知られているCAで。 CABフォーラムの要件(https://cabforum.org/wp-content/uploads/CA-Browser-Forum-BR-1.6.3.pdf)38ページにこのような内容があります。
ユーザー証明書
ダイジェストアルゴリズム:SHA1 *、SHA-256、SHA-384、またはSHA-512
* SHA-1は、セクション7.1.3で定義されている標準に従ってRSAキーと一緒に使用できます。
それから:
7.1.3.アルゴリズムオブジェクト識別子
2016年1月1日以降、CAはSHA-1ハッシュアルゴリズムを使用して新しい加入者証明書または子CA証明書を発行できません。
2)「私が理解しているように、SSL / TLSプロトコルにはダウングレード攻撃に対する保護が含まれているため、サーバーが1.2をサポートし、クライアントも1.2をサポートしている場合、1.0にダウングレードが発生した場合に接続を終了する必要があります。 . アクティブな手動操作サブ) 中間攻撃).
はい。ただし、拡張が使用されている場合にのみ可能であり、TLS_FALLBACK_SCSV
既存のセッション中にクライアントの再ネゴシエーションが禁止されることがあります。バラよりhttps://crypto.stackexchange.com/questions/19673/how-does-tls-fallback-scsv-help#19674説明しますが、重要な部分を引用すると、次のようになります。
デフォルトでは、TLS_FALLBACK_SCSVを使用すると、クライアントはサーバーエラーを引き起こさないようにダウングレードされた接続の試行時に隠されたバージョン番号を送信できます。
Wikipediaページは次の場所にあります。https://en.wikipedia.org/wiki/Transport_Layer_Securityダウングレード攻撃についても詳しく説明します。
しかし、これはTLS 1.3から4.1.3を参照して改善されました。 RFC8446のサーバーグリーティング:
TLS 1.3 は、サーバーの任意の値にパフォーマンス低下防止メカニズムを組み込みます。 ClientHelloに応答してTLS 1.2以下をネゴシエートする
TLS 1.3サーバーは、
ServerHelloでランダムな値の最後の8バイトを具体的に設定する必要があります。
そして
すべてのハンドシェイクモードで完了したMAC(および存在する場合は署名)は、ダウングレード攻撃から保護します。また、セクション4.1.3で説明されているように、以前のTLSバージョンへのダウングレードは、
nonceの特定のバイトを使用して検出できます。 TLS 1.3とダウングレードの詳細については、[BBFGKZ16]を参照してください。
答え2
私は非常に似た問題があります。 あなたの要件を満たすサーバーを見つけることができるとは思いません。 私も考えるやめた方がいいと思います。:
接続を保護するためにMD5またはSHA1証明書に頼ってはいけません。これらの証明書は、誰かが偽造する危険があるため、脆弱であると見なされます。これで、すべてのクライアントは以前のMD5およびSHA1証明書を拒否する必要があります。
安全でない接続を介してサーバーと通信するクライアントを避ける必要があります。アップグレードできないクライアントまたはサーバーがある場合は、独自のセキュリティサンドボックスに入れる必要があります。
問題を解決する方法
あなたのように私もアップグレードできない古いソフトウェアをサポートします。安全に関する推奨事項が何であれ、私たちは保有しているリソースを活用して作業する必要があります。
私はお勧めしますトンネル。これはスタンドアロンサーバーとして実行され、受信したすべての接続を転送します。まず、接続が暗号化または復号化されます。
これを使用するには、古いホストにインストールすることをお勧めします。以前のソフトウェアでSSLを無効にし、(安全でない)暗号化を使用してサーバーに接続するのではなく、暗号化されていないstunnelに接続するように設定します。
[ "Sandbox" ] [ Wherever ]
[[ old box ]] [[ Wherever ]]
[[[ old Client ] ---->[ stunnel client ]]] ---->[[[ actual server ]]]
同じボックスにインストールできない場合は、新しいボックスにインストールしてください。安全に古いホストに接続します。これは同じスイッチに接続されたRaspberry Piです。
[ Securely on the same LAN ("Sandbox") ] [ Wherever ]
[[ old box ] [ new box ]] [[ Wherever ]]
[[[ old Client ]] ---->[[ stunnel client ]]] ---->[[[ actual server ]]]
古いソフトウェアが暗号化されていない接続を拒否する場合は、stunnel を再利用して、古い MD5 または SHA1 証明書を提供するサーバーとして機能できます。繰り返しますが、以前の証明書との接続は暗号化されていないかのように考慮する必要があるため、両方の証明書は物理的に接続されている必要があります。
[ Securely on the same LAN ("Sandbox") ] [ Wherever ]
[[ old box ] [ new box ]] [[ Wherever ]]
[[[ old Client ]] ---->[[ stunnel server ]---->[ stunnel client ]]] ---->[[[ actual server ]]]