
我在 Amazon ELB 後面有 2 個相同的 ubuntu 12.04 伺服器。一台伺服器能夠使用 TLS v1.2 進行連接,而另一台伺服器無法使用 TLS v1.2 發出curl 請求
下面是我用來檢查連接性和版本的程式碼。一個簡單的捲曲請求https://www.howsmyssl.com/a/check使用傳回可用密碼套件和 tls_version 的站點php test_curl.php
<?php
function get_tls_version($sslversion = null)
{
$c = curl_init();
curl_setopt($c, CURLOPT_URL, "https://www.howsmyssl.com/a/check");
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
if ($sslversion !== null) {
curl_setopt($c, CURLOPT_SSLVERSION, $sslversion);
}
$rbody = curl_exec($c);
if ($rbody === false) {
$errno = curl_errno($c);
$msg = curl_error($c);
curl_close($c);
return "Error! errno = " . $errno . ", msg = " . $msg;
} else {
$r = json_decode($rbody);
curl_close($c);
return $r->tls_version;
}
}
echo "OS: " . PHP_OS . "\n";
echo "uname: " . php_uname() . "\n";
echo "PHP version: " . phpversion() . "\n";
$curl_version = curl_version();
echo "curl version: " . $curl_version["version"] . "\n";
echo "SSL version: " . $curl_version["ssl_version"] . "\n";
echo "SSL version number: " . $curl_version["ssl_version_number"] . "\n";
echo "OPENSSL_VERSION_NUMBER: " . dechex(OPENSSL_VERSION_NUMBER) . "\n";
echo "TLS test (default): " . get_tls_version() . "\n";
echo "TLS test (TLS_v1): " . get_tls_version(1) . "\n";
echo "TLS test (TLS_v1_2): " . get_tls_version(6) . "\n";
?>
2台伺服器給出以下回應;
伺服器1
OS: Linux
uname: Linux www-leapset-us-west-1b-n1-new 3.2.0-31-virtual #50-Ubuntu SMP Fri Sep 7 16:36:36 UTC 2012 x86_64
PHP version: 5.3.10-1ubuntu3.4
curl version: 7.22.0
SSL version: OpenSSL/1.0.1
SSL version number: 0
OPENSSL_VERSION_NUMBER: 1000100f
TLS test (default): TLS 1.1
TLS test (TLS_v1): TLS 1.0
TLS test (TLS_v1_2): TLS 1.1
伺服器2
OS: Linux
uname: Linux stag-order-ec1.leapset.com 3.2.0-40-virtual #64-Ubuntu SMP Mon Mar 25 21:42:18 UTC 2013 x86_64
PHP version: 5.3.10-1ubuntu3.11
curl version: 7.22.0
SSL version: OpenSSL/1.0.1
SSL version number: 0
OPENSSL_VERSION_NUMBER: 1000100f
TLS test (default): TLS 1.2
TLS test (TLS_v1): TLS 1.0
TLS test (TLS_v1_2): TLS 1.2
另外,我產生了一個 docker 實例,其 ubuntu 12.04 與伺服器相同,並使用執行給定的文件php curl_test.php
,它的行為方式也與伺服器2
此外,兩台伺服器上的curl --version 在兩台伺服器中給出以下輸出,它們具有相同的版本並且匹配
伺服器 1 和伺服器 2 均
curl 7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtmp rtsp smtp smtps telnet tftp
Features: GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP
另外指令:兩個伺服器中的 openssl 版本相同。 伺服器 1 和伺服器 2 均
OpenSSL 1.0.1 14 Mar 2012
ELB 中啟用的安全性策略是相同的,如這裡所述https://aws.amazon.com/about-aws/whats-new/2017/02/elastic-load-balancing-support-for-tls-1-1-and-tls-1-2-pre-defined-安全策略/它們是預設配置 ELBSecurityPolicy-2016-08,對應於預先存在的預設設置,並支援 TLS 1.0 及更高版本。
此外,我發現curl使用底層openssl來處理TLS。因此,我使用 TLS v1.2 檢查了 openssl 連接
在伺服器1中;當使用以下命令檢查 openssl 連線時
openssl s_client -connect google.com:443
它使用 TLS v1.1 連接但是,當我使用強制 TLS v1.2 時openssl s_client -connect google.com:443 -tls1_2
它能夠使用 TLS v1.2 連接到 google.com:443 並且使用ECDHE-RSA-AES256-GCM-SHA384連線的密碼方案。
然後我嘗試了;openssl s_client -cipher 'ECDHE-RSA-AES256-GCM-SHA384' -connect www.google.com:443
和它伺服器 1 失敗但在伺服器2上工作
更遠;openssl s_client -cipher 'ECDHE-RSA-AES256-GCM-SHA384' -connect www.google.com:443 -tls1_2
在伺服器 1 中運作正常並使用ECDHE-RSA-AES256-GCM-SHA384密碼方案。
我不確定為什麼伺服器1無法在curl請求中使用TLS v1.2進行連接,而且我無法更新openssl版本或curl版本,因為伺服器1是生產伺服器。
更遠,
我檢查了兩個伺服器中的 /etc/ssl/openssl.cnf 和 /usr/lib/ssl/openssl.cnf ,它們也是相同的。
非常感謝任何在伺服器 1 中調試或啟用/強制 tls 1.2 的幫助。