在 PHP 中,可以通过 CURL_SSLVERSION_* 常量控制 curl 使用的 SSL 协议。
通过设置:
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1);
我可以强制 curl 使用“TLS 1.1”。
通过设置:
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
我可以强制 curl 使用“TLS 1.0”。
为了测试所有可能的 SSL 协议,我创建了以下脚本,然后由 travis-ci 执行:
<?php
$sslVersions = [
CURL_SSLVERSION_DEFAULT,
CURL_SSLVERSION_TLSv1,
CURL_SSLVERSION_TLSv1_0,
CURL_SSLVERSION_TLSv1_1,
CURL_SSLVERSION_TLSv1_2,
CURL_SSLVERSION_SSLv2,
CURL_SSLVERSION_SSLv3,
];
var_dump(curl_version());
foreach ($sslVersions as $sslVersion) {
$uri = "https://api.reporting.cloud";
printf("Trying %d", $sslVersion);
echo PHP_EOL;
$ch = curl_init($uri);
curl_setopt($ch, CURLOPT_VERBOSE , true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT , 0);
curl_setopt($ch, CURLOPT_TIMEOUT , 2);
curl_setopt($ch, CURLOPT_SSLVERSION , $sslVersion);
if (curl_exec($ch) === false) {
var_dump(curl_error($ch));
} else {
curl_close($ch);
}
echo PHP_EOL;
echo PHP_EOL;
}
exit(1);
这个脚本在我的开发环境中的输出是:
array(9) {
["version_number"]=>
int(468480)
["age"]=>
int(3)
["features"]=>
int(182173)
["ssl_version_number"]=>
int(0)
["version"]=>
string(6) "7.38.0"
["host"]=>
string(19) "x86_64-pc-linux-gnu"
["ssl_version"]=>
string(14) "OpenSSL/1.0.1t"
["libz_version"]=>
string(5) "1.2.8"
["protocols"]=>
array(21) {
[0]=>
string(4) "dict"
[1]=>
string(4) "file"
[2]=>
string(3) "ftp"
[3]=>
string(4) "ftps"
[4]=>
string(6) "gopher"
[5]=>
string(4) "http"
[6]=>
string(5) "https"
[7]=>
string(4) "imap"
[8]=>
string(5) "imaps"
[9]=>
string(4) "ldap"
[10]=>
string(5) "ldaps"
[11]=>
string(4) "pop3"
[12]=>
string(5) "pop3s"
[13]=>
string(4) "rtmp"
[14]=>
string(4) "rtsp"
[15]=>
string(3) "scp"
[16]=>
string(4) "sftp"
[17]=>
string(4) "smtp"
[18]=>
string(5) "smtps"
[19]=>
string(6) "telnet"
[20]=>
string(4) "tftp"
}
}
Trying 0
* Rebuilt URL to: https://api.reporting.cloud/
* Hostname was NOT found in DNS cache
* Trying 40.76.93.116...
* Connected to api.reporting.cloud (40.76.93.116) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA384
* Server certificate:
* subject: serialNumber=HRB 25927; 1.3.6.1.4.1.311.60.2.1.3=DE; businessCategory=Private Organization; C=DE; postalCode=28215; ST=Bremen; L=Bremen; street=Admiralstr. 54; O=Text Control GmbH; OU=ReportingCloud; OU=COMODO EV SSL; CN=api.reporting.cloud
* start date: 2016-06-17 00:00:00 GMT
* expire date: 2017-06-17 23:59:59 GMT
* subjectAltName: api.reporting.cloud matched
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Extended Validation Secure Server CA
* SSL certificate verify ok.
> GET / HTTP/1.1
Host: api.reporting.cloud
Accept: */*
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
* Server Microsoft-IIS/8.5 is not blacklisted
< Server: Microsoft-IIS/8.5
< X-AspNetMvc-Version: 5.2
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Date: Fri, 15 Jul 2016 14:22:40 GMT
< Content-Length: 952
<
* Connection #0 to host api.reporting.cloud left intact
Trying 1
* Rebuilt URL to: https://api.reporting.cloud/
* Hostname was found in DNS cache
* Trying 40.76.93.116...
* Connected to api.reporting.cloud (40.76.93.116) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA384
* Server certificate:
* subject: serialNumber=HRB 25927; 1.3.6.1.4.1.311.60.2.1.3=DE; businessCategory=Private Organization; C=DE; postalCode=28215; ST=Bremen; L=Bremen; street=Admiralstr. 54; O=Text Control GmbH; OU=ReportingCloud; OU=COMODO EV SSL; CN=api.reporting.cloud
* start date: 2016-06-17 00:00:00 GMT
* expire date: 2017-06-17 23:59:59 GMT
* subjectAltName: api.reporting.cloud matched
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Extended Validation Secure Server CA
* SSL certificate verify ok.
> GET / HTTP/1.1
Host: api.reporting.cloud
Accept: */*
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
* Server Microsoft-IIS/8.5 is not blacklisted
< Server: Microsoft-IIS/8.5
< X-AspNetMvc-Version: 5.2
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Date: Fri, 15 Jul 2016 14:22:40 GMT
< Content-Length: 952
<
* Connection #0 to host api.reporting.cloud left intact
Trying 4
* Rebuilt URL to: https://api.reporting.cloud/
* Hostname was found in DNS cache
* Trying 40.76.93.116...
* Connected to api.reporting.cloud (40.76.93.116) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSL connection using TLSv1.0 / ECDHE-RSA-AES256-SHA
* Server certificate:
* subject: serialNumber=HRB 25927; 1.3.6.1.4.1.311.60.2.1.3=DE; businessCategory=Private Organization; C=DE; postalCode=28215; ST=Bremen; L=Bremen; street=Admiralstr. 54; O=Text Control GmbH; OU=ReportingCloud; OU=COMODO EV SSL; CN=api.reporting.cloud
* start date: 2016-06-17 00:00:00 GMT
* expire date: 2017-06-17 23:59:59 GMT
* subjectAltName: api.reporting.cloud matched
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Extended Validation Secure Server CA
* SSL certificate verify ok.
> GET / HTTP/1.1
Host: api.reporting.cloud
Accept: */*
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
* Server Microsoft-IIS/8.5 is not blacklisted
< Server: Microsoft-IIS/8.5
< X-AspNetMvc-Version: 5.2
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Date: Fri, 15 Jul 2016 14:22:40 GMT
< Content-Length: 952
<
* Connection #0 to host api.reporting.cloud left intact
Trying 5
* Rebuilt URL to: https://api.reporting.cloud/
* Hostname was found in DNS cache
* Trying 40.76.93.116...
* Connected to api.reporting.cloud (40.76.93.116) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSL connection using TLSv1.1 / ECDHE-RSA-AES256-SHA
* Server certificate:
* subject: serialNumber=HRB 25927; 1.3.6.1.4.1.311.60.2.1.3=DE; businessCategory=Private Organization; C=DE; postalCode=28215; ST=Bremen; L=Bremen; street=Admiralstr. 54; O=Text Control GmbH; OU=ReportingCloud; OU=COMODO EV SSL; CN=api.reporting.cloud
* start date: 2016-06-17 00:00:00 GMT
* expire date: 2017-06-17 23:59:59 GMT
* subjectAltName: api.reporting.cloud matched
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Extended Validation Secure Server CA
* SSL certificate verify ok.
> GET / HTTP/1.1
Host: api.reporting.cloud
Accept: */*
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
* Server Microsoft-IIS/8.5 is not blacklisted
< Server: Microsoft-IIS/8.5
< X-AspNetMvc-Version: 5.2
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Date: Fri, 15 Jul 2016 14:22:41 GMT
< Content-Length: 952
<
* Connection #0 to host api.reporting.cloud left intact
Trying 6
* Rebuilt URL to: https://api.reporting.cloud/
* Hostname was found in DNS cache
* Trying 40.76.93.116...
* Connected to api.reporting.cloud (40.76.93.116) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA384
* Server certificate:
* subject: serialNumber=HRB 25927; 1.3.6.1.4.1.311.60.2.1.3=DE; businessCategory=Private Organization; C=DE; postalCode=28215; ST=Bremen; L=Bremen; street=Admiralstr. 54; O=Text Control GmbH; OU=ReportingCloud; OU=COMODO EV SSL; CN=api.reporting.cloud
* start date: 2016-06-17 00:00:00 GMT
* expire date: 2017-06-17 23:59:59 GMT
* subjectAltName: api.reporting.cloud matched
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Extended Validation Secure Server CA
* SSL certificate verify ok.
> GET / HTTP/1.1
Host: api.reporting.cloud
Accept: */*
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
* Server Microsoft-IIS/8.5 is not blacklisted
< Server: Microsoft-IIS/8.5
< X-AspNetMvc-Version: 5.2
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Date: Fri, 15 Jul 2016 14:22:41 GMT
< Content-Length: 952
<
* Connection #0 to host api.reporting.cloud left intact
Trying 2
* Rebuilt URL to: https://api.reporting.cloud/
* Hostname was found in DNS cache
* Trying 40.76.93.116...
* Connected to api.reporting.cloud (40.76.93.116) port 443 (#0)
* OpenSSL was built without SSLv2 support
* Closing connection 0
string(39) "OpenSSL was built without SSLv2 support"
Trying 3
* Rebuilt URL to: https://api.reporting.cloud/
* Hostname was found in DNS cache
* Trying 40.76.93.116...
* Connected to api.reporting.cloud (40.76.93.116) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* Unknown SSL protocol error in connection to api.reporting.cloud:443
* Closing connection 0
string(68) "Unknown SSL protocol error in connection to api.reporting.cloud:443 "
在这里,我们可以清楚地看到“使用 TLSv1.0 的 SSL 连接”正在正确连接到后端服务器。
但是,在 travi-ci 上运行相同的脚本会导致以下结果:
PHP Notice: Use of undefined constant CURL_SSLVERSION_TLSv1_0 - assumed 'CURL_SSLVERSION_TLSv1_0' in /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php on line 7
PHP Stack trace:
PHP 1. {main}() /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php:0
Notice: Use of undefined constant CURL_SSLVERSION_TLSv1_0 - assumed 'CURL_SSLVERSION_TLSv1_0' in /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php on line 7
Call Stack:
0.0002 241400 1. {main}() /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php:0
PHP Notice: Use of undefined constant CURL_SSLVERSION_TLSv1_1 - assumed 'CURL_SSLVERSION_TLSv1_1' in /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php on line 8
PHP Stack trace:
PHP 1. {main}() /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php:0
Notice: Use of undefined constant CURL_SSLVERSION_TLSv1_1 - assumed 'CURL_SSLVERSION_TLSv1_1' in /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php on line 8
Call Stack:
0.0002 241400 1. {main}() /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php:0
PHP Notice: Use of undefined constant CURL_SSLVERSION_TLSv1_2 - assumed 'CURL_SSLVERSION_TLSv1_2' in /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php on line 9
PHP Stack trace:
PHP 1. {main}() /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php:0
Notice: Use of undefined constant CURL_SSLVERSION_TLSv1_2 - assumed 'CURL_SSLVERSION_TLSv1_2' in /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php on line 9
Call Stack:
0.0002 241400 1. {main}() /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php:0
array(9) {
'version_number' =>
int(464384)
'age' =>
int(3)
'features' =>
int(50749)
'ssl_version_number' =>
int(0)
'version' =>
string(6) "7.22.0"
'host' =>
string(19) "x86_64-pc-linux-gnu"
'ssl_version' =>
string(14) "GnuTLS/2.12.14"
'libz_version' =>
string(7) "1.2.3.4"
'protocols' =>
array(18) {
[0] =>
string(4) "dict"
[1] =>
string(4) "file"
[2] =>
string(3) "ftp"
[3] =>
string(4) "ftps"
[4] =>
string(6) "gopher"
[5] =>
string(4) "http"
[6] =>
string(5) "https"
[7] =>
string(4) "imap"
[8] =>
string(5) "imaps"
[9] =>
string(4) "ldap"
[10] =>
string(4) "pop3"
[11] =>
string(5) "pop3s"
[12] =>
string(4) "rtmp"
[13] =>
string(4) "rtsp"
[14] =>
string(4) "smtp"
[15] =>
string(5) "smtps"
[16] =>
string(6) "telnet"
[17] =>
string(4) "tftp"
}
}
Trying 0
* About to connect() to api.reporting.cloud port 443 (#0)
* Trying 40.76.93.116... * connected
* found 164 certificates in /etc/ssl/certs/ca-certificates.crt
* gnutls_handshake() failed: A TLS packet with unexpected length was received.
* Closing connection #0
string(76) "gnutls_handshake() failed: A TLS packet with unexpected length was received."
Trying 1
* About to connect() to api.reporting.cloud port 443 (#0)
* Trying 40.76.93.116... * connected
* found 164 certificates in /etc/ssl/certs/ca-certificates.crt
* gnutls_handshake() failed: A TLS packet with unexpected length was received.
* Closing connection #0
string(76) "gnutls_handshake() failed: A TLS packet with unexpected length was received."
Trying 0
* About to connect() to api.reporting.cloud port 443 (#0)
* Trying 40.76.93.116... * connected
* found 164 certificates in /etc/ssl/certs/ca-certificates.crt
* gnutls_handshake() failed: A TLS packet with unexpected length was received.
* Closing connection #0
string(76) "gnutls_handshake() failed: A TLS packet with unexpected length was received."
Trying 0
* About to connect() to api.reporting.cloud port 443 (#0)
* Trying 40.76.93.116... * connected
* found 164 certificates in /etc/ssl/certs/ca-certificates.crt
* gnutls_handshake() failed: A TLS packet with unexpected length was received.
* Closing connection #0
string(76) "gnutls_handshake() failed: A TLS packet with unexpected length was received."
Trying 0
* About to connect() to api.reporting.cloud port 443 (#0)
* Trying 40.76.93.116... * connected
* found 164 certificates in /etc/ssl/certs/ca-certificates.crt
* gnutls_handshake() failed: A TLS packet with unexpected length was received.
* Closing connection #0
string(76) "gnutls_handshake() failed: A TLS packet with unexpected length was received."
Trying 2
* About to connect() to api.reporting.cloud port 443 (#0)
* Trying 40.76.93.116... * connected
* GnuTLS does not support SSLv2
* Closing connection #0
string(29) "GnuTLS does not support SSLv2"
Trying 3
* About to connect() to api.reporting.cloud port 443 (#0)
* Trying 40.76.93.116... * connected
* found 164 certificates in /etc/ssl/certs/ca-certificates.crt
* gnutls_handshake() failed: A TLS packet with unexpected length was received.
* Closing connection #0
string(76) "gnutls_handshake() failed: A TLS packet with unexpected length was received."
我还注意到常量 CURL_SSLVERSION_TLSv1_0、CURL_SSLVERSION_TLSv1_1 和 CURL_SSLVERSION_TLSv1_2 在 travis-ci 的 PHP 5.6 和 PHP 7 版本上不可用。
总而言之,我已经遍历了所有可能的 CURL_SSLVERSION_* 常量,并且没有一个允许我连接到 travis-ci 上的 api.reporting.cloud,无论我使用哪个 PHP 版本。
有人对我如何从 travis-ci 连接到 api.reporting.cloud 有任何建议吗?