web-dev-qa-db-ja.com

ハンドシェイク中の「tlsv1 alert internal error」

PHP URLの可用性をチェックするスクリプトがあります(基本的に、URLをブラウザーで開くことができ、その逆も可能です) : https://thepiratebay.Gd/ 。このURLはブラウザで正しく開くことができますが、fsockopen()はSSLハンドシェイクエラーで失敗するだけです。 、しかしさらに掘り下げながら、コンソールopensslクライアントを使用して https://thepiratebay.Gd/ に接続することもできないことがわかりました。

openssl s_client -connect thepiratebay.Gd:443 
CONNECTED(00000003)
39613:error:14077438:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert internal error:/SourceCache/OpenSSL098/OpenSSL098-50/src/ssl/s23_clnt.c:602:

このWebサイトはWebブラウザーまたはcurlを使用して正常に開くように見えますが、opensslを介して接続する方法を見つけることができませんでした。どうやら、サーバーはECDHE-ECDSA-AES128-GCM-SHA256暗号化でTLS 1.2を使用していますが、opensslの暗号化を強制しても失敗します:

openssl s_client -cipher ECDHE-ECDSA-AES128-GCM-SHA256 -connect thepiratebay.Gd:443 -tls1_2
CONNECTED(00000003)
140735195829088:error:14094438:SSL routines:SSL3_READ_BYTES:tlsv1 alert internal error:s3_pkt.c:1256:SSL alert number 80
140735195829088:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:596:
---
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.2
    Cipher    : 0000
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1432931347
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---

0.9.8y、1.0.1g、および最新の0.9.8zfと1.0.2aのさまざまなopensslバージョンを試しました。また、少なくとも5台のサーバー(CentOS、Debian、OSX)で運良くこれを実行しようとしました。

他のすべてのWebサイトは正常に処理されているようです。成功したハンドシェイク出力の例を次に示します。

openssl s_client -connect stackoverflow.com:443  -tls1
CONNECTED(00000003)
depth=1 /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/ST=NY/L=New York/O=Stack Exchange, Inc./CN=*.stackexchange.com
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGajCCBVKgAwIBAgIQCn1PE//Ffo4Be8tPBlsAZDANBgkqhkiG9w0BAQsFADBw
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz
dXJhbmNlIFNlcnZlciBDQTAeFw0xMzEwMjIxMjAwMDFaFw0xNjA3MDYxMjAwMDBa
MGoxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJOWTERMA8GA1UEBxMITmV3IFlvcmsx
<---skipped few lines--->
qOHCjaUIx7vKszN4cqbvyry/NdxYkPCC7S8Eks8NjSyppzRL79tU0Yr1MUhVEd6h
GjB2qDwvAGqyWmLz1Q/l82lZbXyBF26DVTJ3RFRUzzieyzKucaVgohI7HC2yyJ9Y
AsE7wvVK4odQI3fRjOsLRaXjFtpiaor0rERUxM4mg7jj05leRBkSazNjv2xvCL5/
Qqm5PN666tREQwvgvXZgg+ZlKWkFyOq6X3THstM6CC8DTGED0cb94WPQA4YTp9OQ
rS3+OedQN+Nlu80Sk8Y=
-----END CERTIFICATE-----
subject=/C=US/ST=NY/L=New York/O=Stack Exchange, Inc./CN=*.stackexchange.com
issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
---
No client certificate CA names sent
---
SSL handshake has read 3956 bytes and written 426 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES128-SHA
    Session-ID: 2E38670F2CABEF3D65FAC67DB6D2E00DBACA4519E50B463D57FCFF8410640BF5
    Session-ID-ctx: 
    Master-Key: 4C63E5502FF7DD36853048E775435A76CB1FDEB37104D6714B1C37D89482D8111B93574D2B3D7F38A1EEFF85D69F9F54
    Key-Arg   : None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - 39 a8 c2 5f c5 15 04 b3-20 34 af fe 20 8e 4d 6c   9.._.... 4.. .Ml
    0010 - 6e 63 f1 e3 45 fd 2a 2c-d9 3c 0d ac 11 ab c0 c9   nc..E.*,.<......
    0020 - ce 51 19 89 13 49 53 a0-af 87 89 b0 5d e2 c5 92   .Q...IS.....]...
    0030 - af e5 84 28 03 4e 1e 98-4c a7 03 d5 5f fc 15 69   ...(.N..L..._..i
    0040 - 7c 83 d2 98 7d 42 50 31-30 00 d7 a8 3c 85 88 a7   |...}BP10...<...
    0050 - cd c0 bb 45 c8 12 b1 c8-4b 76 3c 41 5e 47 04 b5   ...E....Kv<A^G..
    0060 - 60 67 22 76 60 bb 44 f3-4b 3d 3d 99 af 0e dd 0d   `g"v`.D.K==.....
    0070 - 13 95 db 94 90 c2 0f 47-26 04 65 6b 71 b2 f8 1c   .......G&.ekq...
    0080 - 31 95 82 8b 00 38 59 08-1e 84 80 dc da 04 5c f0   1....8Y.......\.
    0090 - ae cc 2b ac 55 0f 39 59-0b 39 7d c7 16 b9 60 ef   ..+.U.9Y.9}...`.

    Start Time: 1432930782
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)

これらすべてのopensslバージョンに同じバグがあると信じることは難しいので、私は何か間違ったことをしていると考えています。

誰でもopensslを使用してこの特定のウェブサイトに接続する方法をアドバイスできますか?

14
Alex Rudakov

これら二つは悪い組み合わせです:

-cipher ECDHE-ECDSA-AES128-GCM-SHA256

そして:

error:/SourceCache/OpenSSL098/OpenSSL098-50/src/ssl/s23_clnt.c

OpenSSL 0.9.8はECを完全にサポートしていません。また、TLS 1.1または1.2はサポートしていません。 AEAD暗号スイートを取得するには、TLS 1.2を使用する必要があります。つまり、OpenSSL 1.0.0以降(IIRC)が必要です。

OpenSSL 1.0.1および1.0.2にはこれらが含まれているため、これらのバージョンを使用することをお勧めします。


 openssl s_client -connect thepiratebay.Gd:443 ...

探しているコマンドはopenssl s_client -connect thepiratebay.Gd:443 -tls1_2 -servername thepiratebay.Gd -CAfile XXXです。 -servernameはSNIに参加します。

サイトにアクセスすると、サーバーはAddTrust External CA Rootによって認証されました。サイトにアクセスすると、DigiCert High Assurance EV Root CAによって認証されました。また、サイトに再度アクセスすると、COMODO ECC認証局によって認証されました。

さまざまなCAと構成は、ロードバランサーの背後にある分散サイトと通信し、参加する各Webサーバーはわずかに異なる構成になります。


複数のWebサーバーと構成に加えて、一部のWebサーバー自体の構成が誤っています。検証用のパスを構築するために必要なチェーンを送信しないため、これらは誤って構成されています。

チェーンには(1)サーバー証明書を含める必要があります。 (2)「ルート」へのチェーンを形成する下位CAまたは中間体。 (2)の場合、1つ以上の中間体が存在する場合があります。

チェーンにはnotルートを含める必要があります。ルートが必要であり、信頼されている必要があります。


このWebサイトはWebブラウザまたはcurlを使用して正常に開くように見えますが、opensslを介して接続する方法を見つけることができませんでした...

これは、Webサーバーの設定ミスにより、ブラウザが何百ものルートCAと下位CAのリストを持ち歩くためです:)リストにはAddTrust External CA RootDigiCert高保証EVルートCA、およびCOMODO ECCルート認証局.


誰でもopensslを使用してこの特定のウェブサイトに接続する方法をアドバイスできますか?

OK、OpenSSLコマンドの場合、-CAfileを使用する必要があります。通常、openssl s_client -connect ... -CAfile DigiCertHighAssuranceEVRootCA.crtDigiCert High Assurance EV Root CAで認証されたサーバーの場合)のようなものを使用します。ただし、この場合は機能しません。

必要なルートCAと下位CAを含む単一のファイルを作成する必要があります。このファイルは、サーバー証明書を検証するためのパスを構築するために必要なPEM形式のルートCAと下位CAの連結である必要があります。少なくとも3つまたは4つの証明書が必要なようです。

または、独自のファイルを作成するのをやめて、 cacert.pem のようなものを使用できます。しかし、CA Zooを使用することには多少のリスクがあります(それらに対する私の愛情の言葉)。いくつかのリスクについては、 cacert.pemは私のコンピューターに固有ですか? を参照してください。

プログラムでは、OpenSSLで SSL_CTX_load_verify_locations を使用します。連結されたPEMファイルは、CAfileを介して渡されます。

PHPで何を使用するのかわかりません。


関連、 cacert.pem には155のルートと下位があります。それらのほとんどは、サイトthepiratebay.Gdの認証には必要ありません。

$ cat cacert.pem | grep BEGIN | wc -l
     155

したがって、CAfileをサイトの認証に必要なものだけに制限する理由。


(コメント)これが尋ねる正しいスレッドかどうかはわかりませんが、これらのチェックのいくつかをプログラムでスキップして、偽陰性の数を減らす方法があるのではないかと思います...

私はおそらくnotチェックを忘れるでしょう。何が起こっているのか理解できたので、システムを放棄するよりも、システムを操作する方が簡単です。

繰り返しますが、次のいずれかです。

  1. 必要なルートCAと下位CAのみを使用する

    1. あなたはそれを構築し、PEM証明書の連結
    2. ファイルを作成piratebay-certs.pem
    3. 必要なCAを追加する
  2. 事前に定義された信頼されたルートCAと下位CAでCA Zooを使用する

    1. ダウンロードする
    2. cacert.pem

3番目のオプションは、Webサーバーの構成を修正するサイトを取得することです。しかし、もしそれが今までに起こらなければ、おそらく起こらないでしょう。 (そして、それは設計上の決定かもしれません-サイトが複数のCAを使用して、1つのCAがサイトをDoSできないようにすることができます。しかし、それは不完全なチェーンに対処しません)。


より一般的な観察:

PHP URLの可用性をチェックするスクリプトがあります(基本的に、スクリプトは、URLがブラウザーで開くことができる場合、特定のURLに対してtrueを返す必要があります。

特にpiratebay.Gdから離れて、ランダムなURLをチェックするには、おそらくcacert.pemを使用する必要があります。これは、100万のサイトのランダムサンプルがそれらのすべてを使用する可能性が高いためです。

piratebay.Gdがまだ失敗する場合は、cacert.pemに欠けているものを見つけてから、次のようにします。

cat cacert.pem > my-expanded-cacert.pem
cat missing-cert.pem >> my-expanded-cacert.pem
12
jww

別の理由で同じエラーメッセージが表示されました。多くのサーバーが [〜#〜] sni [〜#〜] を使用しているため、このエラーが発生する可能性があります。

私の場合(boost_asio + opensslで作成されたc ++クライアント)、次のコードを使用して修正しました。

 char port[] =  "https";
 string Host =  "www.server.com"
 boost::asio::ip::tcp::resolver::query query(Host, port);
 ...
 boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12);
 ...
 ...
 //the following line fix the issue
 SSL_set_tlsext_Host_name(socket_.native_handle(), Host_.c_str());

this SO answer も参照してください。

3
Malick