Apache HTTPサーバー経由でサイトにアクセスしているJavaクライアントおよびブラウザーで断続的なSSLハンドシェイクエラーが発生しました。これはめったに発生しませんが、ビルドを破り、毎日のユーザーエクスペリエンスに影響を与えます。サーバーは、安全な接続を確立するように構成されていますが、クライアントからの証明書は必要としません。Apache HTTPサーバーで断続的なSSLハンドシェイクエラーが発生しました
Javaテストクライアントとサーバーの両方でSSLデバッグ出力を有効にしました(下記参照)。私が観察しているのは、ハンドシェイクの例外が発生するたびに、サーバーはクライアント証明書の要求を送信したようです。私はなぜそれがそうするのか、なぜこれは散発的にしか起こらないのか分かりません。証明書要求を送信すると、ほとんどの場合、エラーはほとんど発生しますが、これが成功した(おそらくは1%の時間、99%が失敗した)要求を取得しました。
クライアントはJava 8(1.8.0_31-b13)を使用し、Apache HTTPサーバーのバージョンは2.2.19です。
SSLProtocol ALL -SSLv2 -SSLv3
SSLCertificateFile <path-to-pem1>
SSLCertificateChainFile <path-to-pem2>
SSLCACertificateFile <path-to-pem3>
SSLVerifyDepth 10
SSLVerifyClient none
の.pemファイルには、世界的に読み取り可能で
1)Apacheの設定の抜粋:
はここでログから抜粋されています。我々は一貫して、クライアント上で何の "*** CertificateRequest" を参照してくださいしない良い例では重度略し
2)クライアントのログ()略し
*** ClientHello, TLSv1.2
***
*** ServerHello, TLSv1
***
*** Certificate chain
***
*** Diffie-Hellman ServerKeyExchange
*** CertificateRequest
*** ServerHelloDone
*** Certificate chain
***
*** ClientKeyExchange, DH
*** Finished
***
...
main, WRITE: TLSv1 Handshake, length = 48
main, waiting for close_notify or alert: state 1
main, Exception while waiting for close java.net.SocketException: Software caused connection abort: recv failed
main, handling exception: java.net.SocketException: Software caused connection abort: recv failed
%% Invalidated: [Session-1, TLS_DHE_RSA_WITH_AES_128_CBC_SHA]
main, SEND TLSv1 ALERT: fatal, description = unexpected_message
...
main, WRITE: TLSv1 Alert, length = 32
main, Exception sending alert: java.net.SocketException: Software caused connection abort: socket write error
main, called closeSocket()
3)サーバーログ()
[info] [client x.x.x.x] Connection to child 1 established (server XXX:443)
[info] Seeding PRNG with 0 bytes of entropy
[debug] ssl_engine_kernel.c(1866): OpenSSL: Handshake: start
[debug] ssl_engine_kernel.c(1874): OpenSSL: Loop: before/accept initialization
[debug] ssl_engine_io.c(1897): OpenSSL: read 11/11 bytes from BIO#82f6820 [mem: 82c5290] (BIO dump follows)
[debug] ssl_engine_io.c(1830): +-------------------------------------------------------------------------+
[debug] ssl_engine_io.c(1869): | 0000: XX XX XX XX XX XX XX XX-XX XX XX ........... |
[debug] ssl_engine_io.c(1875): +-------------------------------------------------------------------------+
[debug] ssl_engine_io.c(1897): OpenSSL: read 245/245 bytes from BIO#82f6820 [mem: 82c529b] (BIO dump follows)
[debug] ssl_engine_io.c(1830): +-------------------------------------------------------------------------+
[debug] ssl_engine_io.c(1869): | 0000: XX XX XX XX XX XX XX XX-XX XX XX XX XX XX XX XX ................ |
...
[debug] ssl_engine_io.c(1869): | 00f0: XX XX XX XX XX ..... |
[debug] ssl_engine_io.c(1875): +-------------------------------------------------------------------------+
[debug] ssl_engine_kernel.c(1987): [client x.x.x.x] SSL virtual host for servername XXX found
[debug] ssl_engine_kernel.c(1874): OpenSSL: Loop: SSLv3 read client hello A
[debug] ssl_engine_kernel.c(1874): OpenSSL: Loop: SSLv3 write server hello A
[debug] ssl_engine_kernel.c(1874): OpenSSL: Loop: SSLv3 write certificate A
[debug] ssl_engine_kernel.c(1274): [client x.x.x.x] handing out temporary 1024 bit DH key
[debug] ssl_engine_kernel.c(1874): OpenSSL: Loop: SSLv3 write key exchange A
[debug] ssl_engine_kernel.c(1874): OpenSSL: Loop: SSLv3 write certificate request A
[debug] ssl_engine_kernel.c(1874): OpenSSL: Loop: SSLv3 flush data
[debug] ssl_engine_io.c(1897): OpenSSL: read 5/5 bytes from BIO#82f6820 [mem: 82c5290] (BIO dump follows)
[debug] ssl_engine_io.c(1830): +-------------------------------------------------------------------------+
[debug] ssl_engine_io.c(1869): | 0000: 16 03 01 00 8d ..... |
[debug] ssl_engine_io.c(1875): +-------------------------------------------------------------------------+
[debug] ssl_engine_io.c(1897): OpenSSL: read 141/141 bytes from BIO#82f6820 [mem: 82c5295] (BIO dump follows)
[debug] ssl_engine_io.c(1830): +-------------------------------------------------------------------------+
[debug] ssl_engine_io.c(1869): | 0000: XX XX XX XX XX XX XX XX-XX XX XX XX XX XX XX XX ................ |
...
[debug] ssl_engine_io.c(1869): | 0080: XX XX XX XX XX XX XX XX-XX XX XX XX XX ............. |
[debug] ssl_engine_io.c(1875): +-------------------------------------------------------------------------+
[debug] ssl_engine_kernel.c(1884): OpenSSL: Write: SSLv3 read client certificate B
[debug] ssl_engine_kernel.c(1903): OpenSSL: Exit: error in SSLv3 read client certificate B
[debug] ssl_engine_kernel.c(1903): OpenSSL: Exit: error in SSLv3 read client certificate B
[info] [client x.x.x.x] SSL library error 1 in handshake (server XXX:443)
[info] SSL Library Error: 336105671 error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a certificate No CAs known to server for verification?
[info] [client x.x.x.x] Connection closed to child 1 with abortive shutdown (server XXX:443)
とこのようなサーバー上での出力
[debug] ssl_engine_kernel.c(1987): [client x.x.x.x] SSL virtual host for servername XXX found
[debug] ssl_engine_kernel.c(1874): OpenSSL: Loop: SSLv3 read client hello A
[debug] ssl_engine_kernel.c(1874): OpenSSL: Loop: SSLv3 write server hello A
[debug] ssl_engine_kernel.c(1874): OpenSSL: Loop: SSLv3 write certificate A
[debug] ssl_engine_kernel.c(1274): [client x.x.x.x] handing out temporary 1024 bit DH key
[debug] ssl_engine_kernel.c(1874): OpenSSL: Loop: SSLv3 write key exchange A
[debug] ssl_engine_kernel.c(1874): OpenSSL: Loop: SSLv3 write server done A
[debug] ssl_engine_kernel.c(1874): OpenSSL: Loop: SSLv3 flush data
[debug] ssl_engine_io.c(1897): OpenSSL: read 5/5 bytes from BIO#82d82d8 [mem: 82c8790] (BIO dump follows)
[debug] ssl_engine_io.c(1830): +-------------------------------------------------------------------------+
[debug] ssl_engine_io.c(1869): | 0000: 16 03 01 00 86 ..... |
[debug] ssl_engine_io.c(1875): +-------------------------------------------------------------------------+
[debug] ssl_engine_io.c(1897): OpenSSL: read 134/134 bytes from BIO#82d82d8 [mem: 82c8795] (BIO dump follows)
[debug] ssl_engine_io.c(1830): +-------------------------------------------------------------------------+
[debug] ssl_engine_io.c(1869): | 0000: XX XX XX XX XX XX XX XX-XX XX XX XX XX XX XX XX ................ |
...
[debug] ssl_engine_io.c(1869): | 0080: XX XX XX XX XX XX ...... |
[debug] ssl_engine_io.c(1875): +-------------------------------------------------------------------------+
[debug] ssl_engine_kernel.c(1874): OpenSSL: Loop: SSLv3 read client key exchange A
Javaクライアントコードの概要:
URL url = new URL("https://...");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setRequestProperty("Authorization", "Basic " + DatatypeConverter.printBase64Binary((user + ":" + pass).getBytes(Charset.forName("UTF-8"))));
connection.setReadTimeout(60*1000);
connection.setUseCaches(false);
connection.connect();
java -Djavax.net.ssl.trustStore=... -Djavax.net.ssl.trustStoreType=jks -Djavax.net.ssl.trustStorePassword=... -Djavax.net.debug=all ...
質問とファイル名を指定して実行:サーバーがクライアントに ouputを "*** CertificateRequest" を引き起こして、証明書要求を送信させ何
- ?
- 設定 "SSLVerifyClient none"は証明書要求を妨げていませんか?
- 次に見たいものはありますか?
アップデート:Java 6が使用されているときにJavaクライアントがエラーを表示しないことに気付きました。この問題は、Java 7および8、Chrome、Internet Explorer、Firefoxで発生します。これは、TLSv1.1またはTLSv1.2に関する問題を指しているようです(https://serverfault.com/questions/513961/how-to-disable-tls-1-1-1-2-in-apache「OpenSSL v1.0.1にはTLSv1.2に関するいくつかの既知の問題があります」を参照)。私は少なくとも、JavaクライアントでTLSv1.1/2を無効にすると問題が解消するかどうかを確認しようとします。
これは、CertificateRequestでクライアントに送信されます。それ以外の理由で送信する必要はありません。 – EJP
@EJP - ああ、そうです。申し訳ありません。 – jww
Javaサンプルコードが追加されました。そこにはOpenSSLが使用されていません。私は実際のマシンにアクセスすることはできません。 sysadminは、 "OpenSSL 1.0.1h 5月2014年6月5日<3rdpartycompanyname> extensions 3.0.16.0"がインストールされていることを伝えます。私は、Apacheが共有ライブラリを使用していると仮定します。 – JanDasWiesel