web-dev-qa-db-ja.com

opensslコマンドを使用して、TLS 1.0を使用しているかどうかを確認するにはどうすればよいですか?

セキュリティスキャンのため、TLS1.0を使用しないように言われました。特定のプロトコルが使用/有効化されているかどうかを確認するためのコマンドを提供する a link が見つかりました。私が実行したコマンド(出力あり)

(TLS1.0からの出力は無効)

$ openssl s_client -connect localhost:8443 -tls1
CONNECTED(00000003)
139874418423624:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1275:SSL alert number 40
139874418423624:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:598:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : 0000
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1505770082
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---

リンクは、プロトコルが有効になっている場合は「接続済み」、それ以外の場合は「ハンドシェイクの失敗」と表示します。ただし、上記のメッセージを見るとわかるように、TLS1.2を使用するようにTomcatを構成しても、両方のメッセージが表示されます。

Server.xmlファイルの私の設定:

<Connector port="8443" protocol="HTTP/1.1"
   maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
   keystoreFile="/glide/bigdata/bdapi/keys/bdapi_keystore.jks"
   keystorePass="bdapi123" clientAuth="false" sslProtocol="TLSv1.2" 
   sslEnabledProtocols="TLSv1.2"/>

TomcatがTLS1.0を使用することを許可する場合、引き続きCONNECTEDが表示されますが、証明書情報も表示されます。

(TLS1.0からの出力が有効)

openssl s_client -connect localhost:8443 -tls1
CONNECTED(00000003)
<snip snip>
<snip snip>
(certificate info)
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
<snip snip>
<snip snip>
(certificate info)
---
Server certificate
-----BEGIN CERTIFICATE-----
<snip snip>
<snip snip>
(public key)
-----END CERTIFICATE-----
<snip snip>
<snip snip>
(certificate info)
---
No client certificate CA names sent
Server Temp Key: ECDH, secp521r1, 521 bits
---
SSL handshake has read 2121 bytes and written 357 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : ECDHE-RSA-AES256-SHA
    Session-ID: 59C0448146B0A18DE52D99C630C896E12BA9861702AB2582C2AA0658E6458B04
    Session-ID-ctx: 
    Master-Key: <some random key>
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1505772673
    Timeout   : 7200 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---
read:errno=0

Opensslからの出力をどのように解釈しますか?上記の設定でTLS1.0を正常に無効にしましたか、それとも両方の出力で「接続済み」と表示されているため、無効にせず、セキュリティスキャンに再び失敗しますか?

9
Classified

TL; TR:サーバーがTLS 1.0をサポートしていないことをクライアントから確認するのは簡単なことではありません。 TLS 1.0との接続が成功した場合、サーバーがTLS 1.0をサポートしていることを確認できます。ただし、この試みが失敗した場合、サーバーがTLS 1.0をサポートしていないことは確認できません。


あなたが引用したリンクで与えられた情報は少なくとも部分的に間違っていることにすでに気づいています。また、それらは不完全です。サーバーで本当にTLS 1.0が無効になっているかどうかを確認することは、それほど簡単ではありません。本当に確認するために何をチェックする必要があるかを理解するには、TLS-Handshakeがどのように機能するかについて少なくとも基本的な理解を持っていることがより良いです。ここで言うことのほとんどはSSLにも当てはまることに注意してください。これは主に、現在TLSと呼ばれている同じプロトコルファミリの以前の名前です。

最初に、クライアントはTCPサーバーへの接続を作成する必要があります。これはまだTLS自体とは関係ありません。そして、すでにTCP接続が成功した場合CONNECTED(00000003)を取得します。このCONNECTEDを取得できない場合、たとえばファイアウォールがアクセスをブロックしているため、サーバーがダウンしているか、サイトから到達できない可能性があります。したがって、CONNECTEDを取得しないと、サーバーがTLS 1.0をサポートする機能について何も言われません

TCP接続が作成された後、TLS部分が始まります。最も単純なケースでは、クライアントは、ClientHelloメッセージ内のTLSハンドシェイクの最初に、可能な最高のTLSバージョンとそれがサポートする暗号を送信します。サーバーは、クライアントが提供するプロトコルバージョン以下の、サポートする最適なSSL/TLSプロトコルで応答します。また、サーバーは、クライアントが提供するものと、サーバーに受け入れられるように構成されているものに基づいて、共通の暗号を選択します。特定のケースでは、クライアントは(-tls1オプションにより)TLS 1.0を最適なプロトコルとして提供し、デフォルトの暗号セットを提供します。サーバーがTLS 1.0以下をサポートしていない場合、ハンドシェイクは失敗しますORクライアントが提供する暗号をサーバーがサポートしていない場合。最後の部分が原因で、サーバーに特定のクライアントがある場合でもサーバーが失敗する可能性がありますサーバーがクライアントが提供する暗号を好まないため、TLS 1.0が有効になっています。

そして、それはより複雑になります。現在、サーバーは同じIPアドレスで複数の証明書をサポートしています。これは、TLSハンドシェイクの開始時にClientHello内に SNI TLS拡張 を使用してターゲットホスト名を含めることで行われます。 SNI拡張がない場合、または拡張が構成済みのホスト名と一致しない場合、サーバーは通常、デフォルトの証明書を送信するか、ハンドシェイクを中止します。最後の部分のため、サーバーでTLS 1.0が有効になっている場合でも、SNI拡張が使用されなかったか、誤ったホスト名で使用されたため、サーバーが特定のクライアントで失敗する可能性がありますopenssl s_clientはデフォルトでSNIを使用しないため、SNI拡張がないために試行が失敗した可能性があります。これには-servernameオプションを使用する必要があります。もちろん、このオプションを使用してサーバーで適切に構成されたホスト名を使用する必要があります。

そして、これまでは正気なTLSスタックとサーバーへの直接接続のみを扱いました。 TLSスタックが壊れている場合、または途中にロードバランサーやファイアウォールなどの壊れたミドルボックスがある場合、サーバーがTLS 1.0をサポートしていても、偶然または故意にハンドシェイクが失敗する可能性があります。 サーバー(ファイアウォール、ロードバランサー、CDNなど)の前にSSLターミネーションがある場合、サーバーのプロパティではなく、その前のシステムのプロパティもテストします。

つまり、サーバーへのTLS 1.0接続が成功した場合、サーバーまたはその前のSSLターミネーターがTLS 1.0をサポートしていることを確認できます。 代わりにTLS 1.0接続が失敗した場合でも、サーバーがTLS 1.0をサポートしていないことは確実ではありません。

15
Steffen Ullrich

これらのツールは特定の質問に直接答えるものではありませんが、探している結果を提供する可能性があります。インターネットに接続している場合は、次のいずれかを試してください。

インターネット接続がない場合:

3
jwilleke

はい、そのウェブサイトは間違っています; CONNECTEDはTCP接続は成功したが、TLS(またはうまくいけばSSLではない)ハンドシェイクについて何も言わないことを意味します。CONNECTEDが得られないがconnect: errno=$nで終わる数行が得られる場合(数値が0の場合でも!)ハンドシェイクを試行することができなかったため、サーバーがサポートする情報がまったくありません。

エラーメッセージやその他の情報opensslが出力する情報を読むことを学ぶこともできますが、重要なインジケーターは、出力の最後のブロックの最初のNew,で始まる行です(---の後、SSL-Session:の前の数行)。実際のプロトコルバージョンが表示され、ハンドシェイクが暗号化された場合(NONE)が含まれている場合、ハンドシェイクは失敗しました-あなたの場合と同じです。

プロトコルバージョン以外の理由でハンドシェイクが失敗する可能性があることに注意してください。このテストが1.0で成功した場合、サーバーが1.0をサポートしていることを確認できますが、このテストが失敗した場合、サーバーが確実に証明されないことは証明されません1.0をサポートします。これらを区別するには、実際にTLSについて学ぶ必要があります。これを書いている間、Steffenはずっと長い時間投稿しましたが、私のパラ2と4がまだ役立つと判断しました。

FWIWはまた、s_client -ssl2のみを使用したSSLv2のテストは、デフォルトの暗号リストがSSLv2をサポートするサーバー上でもSSLv2接続を阻止するリリース1.0.0以降では無効であることにも注意します。ただし、実際の(テストラボや博物館ではない)サーバーでSSLv2について今日でも心配している人は、深刻な問題に直面しています。

2