Q: サーバーの 1 つで、Web サーバーが SSLv2 または SSLv3 をサポートするように設定されていません。どちらもサーバー側で無効になっています。 TLSv1 のみをサポートします。コマンド ラインと PHP コード内の両方から curl を動作させるにはどうすればよいですか?
答え: ほとんどの場合、curl は自動的に正しいプロトコルを選択して接続します。ただし、curl コマンドに使用する特定のプロトコルを指定することもできます。この例では、このチュートリアルで説明されているように、TLSv1 を使用するように CURL に指示する必要があります。
Curl コマンド ラインでプロトコルを指定する
以下は、curl によってコマンド ラインでサポートされているさまざまなプロトコル オプションです:
- -0 (または) HTTP 1.0 の場合は –http1.0 (H)
- TLSv1 (SSL) の場合は -1 (または) –tlsv1
- SSLv2 (SSL) の場合は -2 (または) –sslv2
- SSLv3 (SSL) の場合は -3 (または) –sslv3
この例では、この特定のサーバーは通常の HTTP で動作します。ここでは問題ありません。
$ curl http://192.168.101.1 <html><body><h1>It works!</h1></body></html>
これを参照してください:15 の実用的な Linux cURL コマンドの例
ただし、-3 オプションを使用して SSLv3 を使用すると、「sslv3 アラート ハンドシェイク エラー」エラー メッセージが返されます。
$ curl -3 https://192.168.101.1 curl: (35) error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
-2 オプションを使用して SSLv2 を使用すると、「不明な SSL プロトコル」エラー メッセージが返されます。
$ curl -2 https://192.168.101.1 curl: (35) Unknown SSL protocol error in connection to 192.168.101.1:443
この場合、この特定のサーバーでは、TLS のみがサポートされます。したがって、以下に示すように -1 オプションを使用してください。
$ curl -1 https://192.168.101.1 curl: (60) SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
この場合、IP アドレスを使用しているため、Web サーバーにインストールされている SSL 証明書と一致しません。そのため、上記の「SSL3_GET_SERVER_CERTIFICATE:証明書の検証に失敗しました」というエラー メッセージが表示されます。
デフォルトでは、Curl は SSL 証明書の検証を実行します。 CA 機関バンドルを使用している場合、デフォルトのバンドル名は curl-ca-bundle.crt です。 –cacert オプションを使用して別のバンドルを指定できます。
しかし、私たちの場合、TLSv1 プロトコルを使用したいと考えていますが、SSL 証明書の検証は必要ありません。これには、SSL 証明書の検証を実行しない -k オプション (または –insecure オプション) を使用します。
以下は -k オプションの使用法です。
$ curl -k https://192.168.101.1 curl: (35) Unknown SSL protocol error in connection to 192.168.101.1:443
CURL コマンドによってスローされたエラーの詳細を知りたい場合は、-v オプションを使用します。以下に示すとおりです。プロトコル オプションを渡さなかった場合でも、コマンド出力から、これに SSLv2 を使用しようとしていることがわかります。
$ curl -k -v https://192.168.101.1 * About to connect() to 192.168.101.1 port 443 * Trying 192.168.101.1... connected * Connected to 192.168.101.1 (192.168.101.1) port 443 * successfully set certificate verify locations: * CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none * SSLv2, Client hello (1): Unknown SSL protocol error in connection to 192.168.101.1:443 * Closing connection #0 curl: (35) Unknown SSL protocol error in connection to 192.168.101.1:443
コマンドラインからの解決策
これを参照してください:wget vs curl:wget と curl を使用してファイルをダウンロードする方法
したがって、私たちの場合、SSLv2とSSLv3はサーバー側で無効になっているため、何らかの理由でcurlが適切なプロトコルを自動的に設定しない場合、コマンドラインからcurlでTLSv1プロトコルのみを使用する場合は次のように機能します以下に示します。
$ curl -k -1 https://192.168.101.1 <html><body><h1>It works!</h1></body></html>
これが正確に何をするかの詳細を見たい場合は、以下に示すように -v オプションを渡します。
$ curl -k -1 -v https://192.168.101.1
上記は、次の代替オプションを使用して行うこともできます
$ curl --insecure --tlsv1 --verbose https://192.168.101.1
もう一度、上記のコマンドで:
- -1 (または) –TLSv1 (SSL) の場合は tlsv1
- -k (または) –証明書のない SSL サイトへの接続を許可するには安全ではありません (H)
- -v (or) –verbose 操作をよりおしゃべりにします (小文字の v)
PHP によるソリューション
PHP コードから cURL 関数を使用していて、プロトコル オプションを設定したい場合は、curl_setopt または curl_setopt_array 関数を使用する必要があります。
オプションを 1 つだけ設定する場合は、curl_setopt を使用してください。
curl_setopt($c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
上記では:
- $c は、PHP プログラムから新しい cURL リソースを作成したときに、curl_init() 関数から取得した curl 変数です。
- CURLOPT_SSLVERSION は curl オプション名です。
- CURL_SSLVERSION_TLSv1 は、パラメータ #2 の対応するオプションの curl 値です
「CURL_SSLVERSION_TLSv1」の代わりに数値を使用することもできます。この例では、これは 1 に相当します。
curl_setopt($c, CURLOPT_SSLVERSION, 1);
以下は、設定可能な CURLOPT_SSLVERSION 値です。記述定数または以下に示す対応する数値のいずれかを使用できます。
- CURL_SSLVERSION_DEFAULT (0)
- CURL_SSLVERSION_TLSv1 (1)
- CURL_SSLVERSION_SSLv2 (2)
- CURL_SSLVERSION_SSLv3 (3)
- CURL_SSLVERSION_TLSv1_0 (4)
- CURL_SSLVERSION_TLSv1_1 (5)
- CURL_SSLVERSION_TLSv1_2 (6)
複数の CURL オプションを設定する場合は、以下のように curl_setopt_array を使用します。ここでは、CURLOPT_SSLVERSION の設定とは別に、他のいくつかの curl オプションも設定します。
この場合、2 番目のパラメーターは、以下に示すように複数の CURL オプションを含む配列になります。
curl_setopt_array($c, array ( CURLOPT_SSL_VERIFYHOST => 0, CURLOPT_SSL_VERIFYPEER => 0, CURLOPT_SSLVERSION => 1 ));