curl(およびopenssl)双方向認証が常に失敗する


4

問題 curlを使用してTomcatにデプロイされたWebサービスにPOST要求を送信しようとしていますが、ホストとクライアントの検証が必要です(双方向認証)が、常に応答が返され404 Not Foundます。openssl s_clientを使用しても同じ結果が得られます。私が間違っていることの手がかりがありません。

使用したcURLコマンド以下は、インターネットの検索と同様にcurlのマニュアルページから使用および作成したコマンドです。

curl 'https://hostURL:<port>/webservice/' -d '{"someRequest": {"name": "lol"}}' -v --cert webserver-cert.pem --key webserver-key.pem --cacert root-ca.pem

上記のコマンドの出力は次のとおりです。

*   Trying <ip>...
* Connected to <host> port <port> (#0)
* found 1 certificates in root-ca.pem
* found 872 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
*        server certificate verification OK
*        server certificate status verification SKIPPED
*        common name: <common-name> (matched)
*        server certificate expiration date OK
*        server certificate activation date OK
*        certificate public key: RSA
*        certificate version: #3
*        <data>
*        compression: NULL
* ALPN, server did not agree to a protocol
> POST /webservice/ HTTP/1.1
> Host: host:port
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Length: 32
> Content-Type: application/x-www-form-urlencoded
> 
* upload completely sent off: 32 out of 32 bytes
< HTTP/1.1 404 Not Found
< Server: Apache-Coyote/1.1
< Content-Type: text/html;charset=utf-8
< Content-Language: en
< Content-Length: 1034
< Date: Tue, 19 Sep 2017 05:42:56 GMT
< 
<!DOCTYPE html><html><head><title>Apache Tomcat/8.0.14 - Error report</title><style type="text/css">H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}.line {height: 1px; background-color: #525D76; border: none;}</style> </head><body><h1>HTTP Status 404 - /webservice/</h1><div class="line"></div><p><b>type</b> Status report</p><p><b>message</b> <u>/webservice/</u></p><p><b>description</b> <u>The requested resource is not available.</u></p><hr class="line"><h3>Apache Tomcat/8.0.14</h3></bo* Connection #0 to host host left intact
dy></html>

使用したopenssl s_clientコマンド以下は、manページを読んでインターネットを検索して作成したopensslコマンドです。

openssl s_client -connect host:port -cert webserver-cert.pem -key webserver-key.pem -CAfile root-ca.pem -msg -state

出力は次のとおりです。

CONNECTED(00000003)
SSL_connect:before/connect initialization
>>> TLS 1.2  [length 0005]
    16 03 01 01 2c
>>> TLS 1.2 Handshake [length 012c], ClientHello
    <data>
SSL_connect:SSLv2/v3 write client hello A
<<< ??? [length 0005]
    16 03 03 0c 65
<<< TLS 1.2 Handshake [length 0051], ServerHello
    <data>
SSL_connect:unknown state
<<< TLS 1.2 Handshake [length 0ac3], Certificate
    <data>
depth=1 C = FR, ST = state, L = name, O = name, CN = name CA
verify return:1
depth=0 C = FR, ST = country, L = state, O = host, OU = Web server, CN = host
verify return:1
SSL_connect:unknown state
<<< TLS 1.2 Handshake [length 014d], ServerKeyExchange
    <data>
SSL_connect:unknown state
<<< TLS 1.2 Handshake [length 0004], ServerHelloDone
    0e 00 00 00
SSL_connect:unknown state
>>> ??? [length 0005]
    16 03 03 00 46
>>> TLS 1.2 Handshake [length 0046], ClientKeyExchange
    <data>
SSL_connect:unknown state
>>> ??? [length 0005]
    14 03 03 00 01
>>> TLS 1.2 ChangeCipherSpec [length 0001]
    01
SSL_connect:unknown state
>>> ??? [length 0005]
    16 03 03 00 28
>>> TLS 1.2 Handshake [length 0010], Finished
    14 00 00 0c 86 20 94 8c f1 d2 32 1d 95 10 40 7c
SSL_connect:unknown state
SSL_connect:unknown state
<<< ??? [length 0005]
    14 03 03 00 01
<<< TLS 1.2 ChangeCipherSpec [length 0001]
    01
<<< ??? [length 0005]
    16 03 03 00 28
<<< TLS 1.2 Handshake [length 0010], Finished
    14 00 00 0c 04 c9 ef 15 6e cf 7f 28 2b 8f b3 4e
SSL_connect:unknown state
---
Certificate chain
 0 s:/C=FR/ST=country/L=state/O=host/OU=Web server/CN=host
   i:/C=FR/ST=state/L=name/O=name/CN=name CA
 1 s:/C=FR/ST=state/L=name/O=name/CN=name CA
   i:/C=FR/ST=state/L=name/O=name/CN=name CA
---
Server certificate
-----BEGIN CERTIFICATE-----
<data>
-----END CERTIFICATE-----
subject=<data>
issuer=<data>
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3229 bytes and written 431 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure RenFRotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN nFRotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: <data>
    Session-ID-ctx: 
    Master-Key: <data>
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1505765192
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

次に、次のように投稿リクエストを入力します。

POST /webservice/ HTTP/1.1
Host: <host>:<port>
Accept: */*
Content-Length: 86
Content-Type: application/json

{request:{"username":"lol"}}

その後も同じ404エラーが発生します。

詳細

  • Webサービスへのパスが存在すると確信しています。実際、Webサービスと正常に通信しているJavaで構築されたクライアントがあります。(これは、Tomcatが正しく構成されていることも意味します)

  • URLとポート、およびCA証明書が正しいと確信しています。クライアント認証を必要としない別のWebサービスと通信するためにそれらを使用し、正常に機能しました。

  • 以下はcurlとopensslのバージョンです。

カール

curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3

openssl

OpenSSL 1.0.2g  1 Mar 2016
built on: reproducible build, date unspecified
platform: debian-amd64
options:  bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx) 
compiler: cc -I. -I.. -I../include  -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
OPENSSLDIR: "/usr/lib/ssl"

私が入力したすべての文字が正しいことを確認するためにコマンドを調べてきたので、私はここで狂っています。これを複数回行っています。インターネットを検索し、使用しているコマンドが正しいことを学びました(少なくとも、これまでのところ私は考えています)。

また、なぜALPN, server did not agree to a protocolcurlとSSL_connect:unknown stateopensslから取得するのですか?

この問題に関する助けをいただければ幸いです。

前もって感謝します。


私はこれとまったく同じ問題を抱えており、私が保守しているいくつかのスクリプトを使用して数年間それと戦ってきました。問題は、Ubuntu 16.04のcurlがOpenSSLではなくGnuTLSにリンクされており、何らかの理由でGnuTLSがリクエストでクライアント証明書を送信しないことです。
petrsnd

これを解決したことはありますか?クライアント認証を無効にすると、カール出力はどのようになりますか?
ヤリトゥルキア

@JariTurkia、はい。サーバーは、使用しているポートとは異なるポートで動作するように構成されていることがわかりました。
ジョーカー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.