2016-07-14 384 views
10

我正在運行成從使用CURL經由SSL請求URI一個PHP成分如下錯誤:捲曲錯誤35:gnutls_handshake()失敗

cURL error 35: gnutls_handshake() failed: A TLS packet with unexpected length was received. 

在travis-ci.org環境中發生該錯誤,但不在我們的任何測試環境中。參見travis-ci build 144663700

我發現在Travis worker中運行的PHP版本在「Ubuntu 12.04.5 LTS」上再次編譯爲「GnuTLS/2.12.14」,或在「Ubuntu 14.04.3上編譯爲」GnuTLS/2.12.23「 LTS」。

在我們的開發環境中,我們使用針對在Debian(各種版本)「的OpenSSL/1.0.1t」編制標準封裝。

因此,我認爲這個問題是有關「的GnuTLS/14年2月12日」或「的GnuTLS/23年2月12日」,或與它們已編譯的參數。

我曾嘗試限制SSL版本使用curl不斷CURLOPT_SSLVERSION,但這並不解決問題。

根據www.ssllabs.com所討論的宿主 - api.reporting.cloud - 支持TLS 1.2,TLS 1.1和TLS 1.0。

會有人對我有任何提示或指針?

回答

0

我找到了解決問題的辦法在這個mailing list

The server doesn't like something in the TLS 1.2 support of gnutls 2.12 since if you disable it, it seems to work. The same server works with gnutls 3.2 and the only difference in the client hello of the two versions is that gnutls 3.2 has more features enabled.

我使用(需要使用) 「GNUTLS-CLI(的GnuTLS)23年2月12日」。

下面返回上述錯誤:

gnutls-cli --priority "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2" api.reporting.cloud 

然而,迫使 「TLS 1.1」 或 「TLS 1.0」,返回按預期:

gnutls-cli --priority "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.1" api.reporting.cloud 
gnutls-cli --priority "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0" api.reporting.cloud 

下一步是使該設置從PHP通過CURL(特定情況下錯誤的庫版本)。

3

在PHP中,有可能控制該捲曲與CURL_SSLVERSION_ *常量使用SSL協議。

通過設置:

curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1); 

我可以強制捲曲用 「TLS 1.1」。

通過設置:

curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); 

我可以強制捲曲用 「TLS 1.0」。

測試所有可能的SSL協議,我創建了下面的腳本,然後由特拉維斯-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慈結果相同的腳本如下所示:

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不提供特拉維斯-CI的PHP 5.6,也不是PHP 7版本。總之,我已經遍歷了所有可能的CURL_SSLVERSION_ *常量,並且沒有一個允許我連接到travis-ci上的api.reporting.cloud,而不管我使用哪個PHP版本。

有沒有人有任何建議,我怎麼可以連接到travis-ci的api.reporting.cloud?

6

解決此問題的方法是將travis-ci配置爲使用標準的Ubuntu Trusty php5-cli和php5-curl軟件包。標準軟件包提供CURL_SSLVERSION_TLSv1_1常量。

的.travis.yml文件看起來像這樣:

sudo: required 

dist: trusty 

language: php 

before_install: 
    - sudo apt-get -y install git zip php5-cli php5-curl 

before_script: 
    - php -r "printf('PHP %s', phpversion());" 
    - composer self-update 
    - composer install --no-interaction 

script: 
    - mkdir -p ./build/logs 
    - ./vendor/bin/phpunit 

在PHP源,它是然後簡單地通過特拉維斯-Cl正在執行在PHP碼的情況下設定前述恆定的事:

if (getenv('TRAVIS')) { 
    $options['curl'][CURLOPT_SSLVERSION] = CURL_SSLVERSION_TLSv1_1; 
} 

此變通辦法的缺點是它只能在Ubuntu Trusty提供的特定PHP版本(PHP 5.5)上運行。考慮到PHP 5.5在2016年7月10日達到使用壽命,該解決方案是不可接受的。

這將是理想的特拉維斯-CI更新到Ubuntu 16.04 LTS,但布蘭登·伯頓,在特拉維斯慈wrote基礎設施管理器2016年2月28日:

Given that, we are currently focused on support 12.04 and 14.04 as our primary environments. At the moment, it is unlikely that we'll be supporting 16.04 as a native environment this year.

因此,似乎我們Ubuntu Trusty停留了一段時間。

這個問題的根源在於,運行在travis-ci上的PHP版本是用2011年的gnutls-cli(GnuTLS)2.12.23編譯的。這個具體版本的gnutls-cli有一些問題全部)TLS 1.2連接。

@ travis-ci:是否有可能重新編譯針對GnuTLS的更新版本使用的PHP版本 - 或者至少有一個更好地支持TLS 1.2?