F: Auf einem unserer Server ist der Webserver nicht für die Unterstützung von SSLv2 oder SSLv3 eingerichtet. Beide sind serverseitig deaktiviert. Es unterstützt nur TLSv1. Wie kann ich curl sowohl von der Befehlszeile als auch von meinem PHP-Code aus zum Laufen bringen?
A: In den meisten Fällen wählt curl automatisch das richtige Protokoll aus und verbindet sich damit. Sie können aber auch ein bestimmtes Protokoll angeben, das für den Curl-Befehl verwendet werden soll. In diesem Beispiel müssen Sie CURL anweisen, TLSv1 zu verwenden, wie in diesem Tutorial erklärt.
Protokoll in der Curl-Befehlszeile angeben
Im Folgenden sind die verschiedenen Protokolloptionen aufgeführt, die auf der Befehlszeile von curl unterstützt werden:
- -0 (oder) –http1.0 für HTTP 1.0 (H)
- -1 (oder) –tlsv1 für TLSv1 (SSL)
- -2 (oder) –sslv2 für SSLv2 (SSL)
- -3 (oder) –sslv3 für SSLv3 (SSL)
In diesem Beispiel arbeitet dieser bestimmte Server mit normalem HTTP. Keine Probleme hier.
$ curl http://192.168.101.1 <html><body><h1>It works!</h1></body></html>
Siehe:15 praktische cURL-Befehlsbeispiele für Linux
Wenn Sie jedoch SSLv3 verwenden und die Option -3 verwenden, wird die Fehlermeldung „sslv3 alert handshake failure“ zurückgegeben.
$ curl -3 https://192.168.101.1 curl: (35) error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
Wenn Sie SSLv2 mit der Option -2 verwenden, wird die Fehlermeldung „Unbekanntes SSL-Protokoll“ zurückgegeben.
$ curl -2 https://192.168.101.1 curl: (35) Unknown SSL protocol error in connection to 192.168.101.1:443
In diesem Fall wird auf diesem bestimmten Server nur TLS unterstützt. Verwenden Sie also die Option -1 wie unten gezeigt.
$ 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
In diesem Fall verwenden wir die IP-Adresse, die nicht mit dem auf dem Webserver installierten SSL-Zertifikat übereinstimmt. Wir erhalten also die obige Fehlermeldung „SSL3_GET_SERVER_CERTIFICATE:Zertifikatsüberprüfung fehlgeschlagen“.
Curl führt standardmäßig die SSL-Zertifikatsüberprüfung durch. Wenn Sie ein CA-Autoritätspaket verwenden, lautet der Standardpaketname curl-ca-bundle.crt. Sie können mit der Option –cacert ein anderes Paket angeben.
In unserem Fall möchten wir jedoch das TLSv1-Protokoll verwenden, jedoch ohne die SSL-Zertifikatsüberprüfung. Verwenden Sie dazu die Option -k (oder die Option –insecure), die keine SSL-Zertifikatsüberprüfung durchführt.
Das Folgende ist eine Verwendung der Option -k.
$ curl -k https://192.168.101.1 curl: (35) Unknown SSL protocol error in connection to 192.168.101.1:443
Wenn Sie mehr Details über den vom CURL-Befehl ausgelösten Fehler erfahren möchten, verwenden Sie die Option -v. Wie Sie unten sehen. Selbst wenn wir die Protokolloption nicht übergeben haben, können wir anhand der Befehlsausgabe sehen, dass versucht wird, SSLv2 dafür zu verwenden.
$ 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
Lösung von der Befehlszeile
Siehe dazu:wget vs curl:How to Download Files Using wget and curl
Da also in unserem Fall SSLv2 und SSLv3 auf der Serverseite deaktiviert sind und curl aus irgendeinem Grund nicht automatisch das richtige Protokoll festlegt, funktioniert Folgendes, wenn wir nur das TLSv1-Protokoll mit curl von der Befehlszeile aus verwenden möchten unten gezeigt.
$ curl -k -1 https://192.168.101.1 <html><body><h1>It works!</h1></body></html>
Wenn Sie die Details dazu sehen möchten, was genau das tut, übergeben Sie die Option -v wie unten gezeigt.
$ curl -k -1 -v https://192.168.101.1
Das Obige kann auch mit den folgenden alternativen Optionen durchgeführt werden
$ curl --insecure --tlsv1 --verbose https://192.168.101.1
Wieder im obigen Befehl:
- -1 (oder) –tlsv1 für TLSv1 (SSL)
- -k (or) –insecure, um Verbindungen zu SSL-Sites ohne Zertifikate zuzulassen (H)
- -v (or) –verbose, um die Operation gesprächiger zu machen (Kleinbuchstabe v)
Lösung von PHP
Wenn Sie in Ihrem PHP-Code die cURL-Funktionen verwenden und die Protokolloptionen festlegen möchten, sollten Sie die Funktionen curl_setopt oder curl_setopt_array verwenden.
Verwenden Sie curl_setopt, wenn Sie nur eine Option festlegen möchten.
curl_setopt($c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
Oben:
- $c ist die Curl-Variable, die Sie von der curl_init()-Funktion erhalten haben, als Sie eine neue cURL-Ressource von Ihrem PHP-Programm erstellt haben.
- CURLOPT_SSLVERSION ist ein Curl-Optionsname.
- CURL_SSLVERSION_TLSv1 ist ein Curl-Wert für die entsprechende Option in Parameter#2
Anstelle von „CURL_SSLVERSION_TLSv1“ können Sie auch eine Ziffer verwenden. In diesem Beispiel entspricht dies 1.
curl_setopt($c, CURLOPT_SSLVERSION, 1);
Die folgenden CURLOPT_SSLVERSION-Werte können Sie festlegen. Sie können entweder die beschreibende Konstante oder die entsprechende Nummer verwenden, die unten angezeigt wird.
- 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)
Wenn Sie mehrere CURL-Optionen festlegen möchten, verwenden Sie curl_setopt_array wie unten gezeigt. Hier werden neben der Einstellung von CURLOPT_SSLVERSION auch einige andere Curl-Optionen festgelegt.
In diesem Fall ist der zweite Parameter ein Array, das mehrere CURL-Optionen enthält, wie unten gezeigt.
curl_setopt_array($c, array ( CURLOPT_SSL_VERIFYHOST => 0, CURLOPT_SSL_VERIFYPEER => 0, CURLOPT_SSLVERSION => 1 ));