我们如何在Guzzle中指定TLS/SSL选项?

18

我们开始在 PHP 中使用 Guzzle 来调用各种不同的 API,其中一些 API 不支持 TLSv1.2,而另一些则需要 TLSv1.2。

除了我们知道某些 API 不支持最新协议的情况外,强制 Guzzle 使用最新可用的协议是最好的方法。

3个回答

21

这很简单易懂。

$client = new Client();
$guzzle = new GuzzleClient('https://www.yourweb.com', array(
    'curl.options' => array(
        CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2
    )
));
$client->setClient($guzzle);
...

在 Guzzle 3.0+ 中(根据 @limos 的评论更新):
'curl' => array(
    CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2
)

可以在官方cURL页面找到可能的CURLOPT_SSLVERSION选项: http://curl.haxx.se/libcurl/c/CURLOPT_SSLVERSION.html

--- 更新(根据评论) ---

选择适当的SSL协议版本不仅涉及CURLOPT_SSLVERSION设置,还涉及许多cURL设置。期望的重要结果称为“最大前向保密性”。 这不仅适用于cURL!

您无法使用多个CURLOPT_SSLVERSION参数(至少我没有在Guzzle文档中找到这样的选项)。当您定义CURLOPT_SSLVERSION时,cURL将尝试使用该SSL版本 - 来自cURL文档(有关CURLOPT_SSLVERSION的上面提供的链接) - “传递长参数以控制要尝试使用的SSL / TLS版本。”

你可以定义多个安全密码,但只能有一个SSL版本参数。我不会使用早于TLS 1.1的任何内容。任何早期的SSL版本都容易受到攻击。版本TLS 1.1也存在漏洞,但如果您选择1.2,则可能会遇到客户端兼容性问题。目前唯一安全的(直到他们发现某些漏洞)是TLS 1.2。
如果安全性是最高优先级,请选择可用的最高TLS版本(TLS1.2)。当服务提供商承担安全责任时,客户端兼容性不是您的问题。
如果安全性很重要,这里还有其他要查看的cURL选项:

设置正确的CURLOPT_SSL_VERIFYHOSTCURLOPT_SSL_VERIFYPEER将防止中间人攻击。

CURLOPT_CAINFO - 修复错误:35-连接中未知的SSL协议错误。改善最大前向保密性。

以下是一个cURL密码列表(CURLOPT_SSL_CIPHER_LIST),可以提高最大前向保密性,请参考:

'DHE-RSA-AES256-SHA',
'DHE-DSS-AES256-SHA',
'AES256-SHA',
'ADH-AES256-SHA',
'KRB5-DES-CBC3-SHA',
'EDH-RSA-DES-CBC3-SHA',
'EDH-DSS-DES-CBC3-SHA',
'DHE-RSA-AES128-SHA',
'DHE-DSS-AES128-SHA',
'ADH-AES128-SHA',
'AES128-SHA',
'KRB5-DES-CBC-SHA',
'EDH-RSA-DES-CBC-SHA',
'EDH-DSS-DES-CBC-SHA:DES-CBC-SHA',
'EXP-KRB5-DES-CBC-SHA',
'EXP-EDH-RSA-DES-CBC-SHA',
'EXP-EDH-DSS-DES-CBC-SHA',
'EXP-DES-CBC-SHA'

这些密码已经与强大的Qualys SSL Labs列表(2014)进行了比对,弱密码已被删除。如有需要,可以自由添加/删除任何密码。
如果您仍然想追求多个CURLOPT_SSLVERSION选项,我建议编写一个脚本来实现(我认为这不是一个好的做法或必要的)。但是,如果您因为任何原因决定追求该功能,请编写一些代码,尝试使用最强大的SSL加密,如果连接失败,则回退到下一个版本。
  1. 在做决定之前,请查看Qualys SSL Labs有关安全性的项目
  2. 阅读这篇SSL Labs文章,了解完美前向保密和最佳实践。
  3. 使用SSL Labs的Web工具测试您的客户端(Web浏览器)是否存在漏洞。这将让您了解需要改进和保护服务器和应用程序的内容。
  4. 使用Qualys的SSL Labs SSL工具测试您的网站/ Web服务。

漏洞和攻击:Longjam,FREAK,POODLE等等!谁知道还有什么其他攻击或漏洞是未被发现的?是的!它们都会影响您选择SSL / TLS连接。

您无法控制客户端(除非您开发它),但可以控制服务器和服务器-客户端协商。

无论您构建什么应用程序,都应该查看最佳实践,根据您的需求和每种情况,您应该决定以下选项:
  1. 安全性
  2. 兼容性
  3. 可维护性
  4. 复杂度

如果安全性非常重要,请至少选择TLS1.1。 还要查看密码列表,我不会忽略那一部分。

这里还有一个很好的OWASP创建安全层指南

OWASP和Qualys SSL Labs是很好的起点。我甚至会研究cURL和OpenSSL以熟悉弱点、可能的安全选项和最佳实践。

有一些安全问题我没有提到并且遗漏了,但我们无法涵盖所有内容。这只是冰山一角。 这里未提到的任何内容都需要您进行研究。

祝你好运!

如果可以,我会在附近回答任何问题。


好的,所以我们可以让它自动协商(默认)或者只设置一个协议版本来接受?我希望有一种方法可以给它一组协议版本并选择最新的版本。 - MattC
没错,您不能使用多个CURLOPT_SSLVERSION参数(至少在Guzzle文档中我没有找到这样的选项)。当您定义CURLOPT_SSLVERSION时,cURL将尝试使用该SSL版本。从cURL文档(提供的链接)中可以看到:“传递一个长整型作为参数来控制要尝试使用哪个版本的SSL/TLS。” 您可以定义多个安全密码,但只能有一个ssl版本参数。我不会使用早于TLS 1.1的任何版本。任何早期的SSL版本都容易受到攻击。v1.1也存在漏洞,但是如果使用1.2,我们将遇到客户端兼容性问题。 - GTodorov
我决定更新我的答案,因为你的问题并没有简单的答案。 - GTodorov
1
只是补充一下 - 在 Guzzle 3.0 中,键名应该是 'curl' 而不是 'curl.options'。 此外,常量应该没有引号。 - limos
@limos 很好的发现。感谢你指出来!我已经更新了。 :) - GTodorov
在 Guzzle >= 7.0.1 上如何工作? - David L

12
在 Guzzle 5.3 中,我必须使用以下语法:
$guzzle = new \GuzzleHttp\Client([
    'defaults' => [
        'config' => [
            'curl' => [
                CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2
            ]
        ]
    ]
]);

3
在 Guzzle 7 中,它可以直接设置在“curl”下的请求选项中,这在文档中没有提到。请注意保留HTML标签。
$client = new \GuzzleHttp\Client();
$res = $client->request('GET', 'https://www.howsmyssl.com/a/check', [
    'curl' => [
        CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2
    ],
]);
$body = $res->getBody();
echo ($body ? json_decode($body, true)['tls_version'] : "Request failed");

此外,如果您想指定较小的TLS版本,可以使用max选项,例如CURL_SSLVERSION_MAX_TLSv1_1
CURL选项参考:CURLOPT_SSLVERSION explained 参考资料:Guzzle soruce code

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接