2016-07-14 4 views
10

Я бегу в следующее сообщение об ошибке от компонента PHP, который использует CURL для запроса URI с помощью SSL:Curl ошибка 35: gnutls_handshake() не

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

Эта ошибка возникает в среде travis-ci.org , но не в любой из наших тестовых сред. См. Travis-ci build 144663700.

Я выяснил, что версия PHP, работающая в рабочем месте Travis, скомпилирована снова «GnuTLS/2.12.14» на «Ubuntu 12.04.5 LTS» или с «GnuTLS/2.12.23» на «Ubuntu 14.04.3 LTS».

В наших средах разработки мы используем стандартные пакеты, составленные против «OpenSSL/1.0.1t» в Debian (различные версии).

Поэтому я предполагаю, что проблема связана с «GnuTLS/2.12.14» или «GnuTLS/2.12.23» или с параметрами, с которыми они были скомпилированы.

Я попытался ограничить версии 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) 2.12.23".

Следующая возвращает вышеупомянутую ошибку:

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 можно управлять протоколом SSL, который завиток использует с константами CURL_SSLVERSION_ *.

Устанавливая:

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 " 

Здесь мы можем ясно видеть, что «SSL-соединение с использованием TLSv1.0» правильно подключается к серверу.

Однако, работает один и тот же сценарий на 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 не доступны на PHP Travis-CI в 5.6, ни PHP 7 версии.

Подводя итог, я зациклился на всех возможных константах CURL_SSLVERSION_ *, и ни один из них не позволяет мне подключиться к api.reporting.cloud на travis-ci, независимо от того, какую версию PHP я использую.

Есть ли у кого-нибудь предложения о том, как я могу подключиться к api.reporting.cloud от travis-ci?

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, то есть просто вопрос установки вышеупомянутой константы в случае коды PHP выполняется Трэвис-CI :

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

Этот способ имеет тот недостаток, что он работает только на конкретной PHP версии, что Ubuntu испытанный предлагает (PHP 5.5). Учитывая, что PHP 5.5 достигли конца жизни 10 июля 2016 года, это решение неприемлемо.

Было бы идеально подходит для Travis-CI для обновления до Ubuntu 16.04 LTS, но Брэндон Бертон, менеджер инфраструктуры в Travis-CI wrote 28 февраля 2016 года:

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 некоторое время.

Корень этой проблемы состоит в том, что версия PHP, которая работает на travis-ci, была скомпилирована с помощью gnutls-cli (GnuTLS) 2.12.23 с 2011 года. У этой конкретной версии gnutls-cli есть проблемы с некоторыми (но не все) соединения TLS 1.2.

@ travis-ci: Можно ли перекомпилировать версии PHP, которые вы используете, с более современной версией GnuTLS - или, по крайней мере, с поддержкой TLS 1.2?

Смежные вопросы