从 CLI 和 PHP 代码修复 Curl TLS SSL 协议问题

举报
Tiamo_T 发表于 2022/10/14 08:37:17 2022/10/14
【摘要】 在我们的一台服务器上,网络服务器未设置为支持 SSLv2 或 SSLv3。两者都在服务器端被禁用。它仅支持 TLSv1。我怎样才能让 curl 从命令行和我的 PHP 代码中工作?

在我们的一台服务器上,网络服务器未设置为支持 SSLv2 或 SSLv3。两者都在服务器端被禁用。它仅支持 TLSv1。我怎样才能让 curl 从命令行和我的 PHP 代码中工作?

在大多数情况下,curl 会自动选择正确的协议并连接到它。但是,您也可以指定用于 curl 命令的特定协议。在此示例中,您必须指示 CURL 使用 TLSv1,如本教程中所述。

在 Curl 命令行上指定协议

以下是 curl 在命令行上支持的各种协议选项:

  • -0(或)-http1.0 用于 HTTP 1.0 (H)
  • -1(或)–tlsv1 用于 TLSv1 (SSL)
  • -2 (或) –sslv2 用于 SSLv2 (SSL)
  • -3 (或) –sslv3 用于 SSLv3 (SSL)

在此示例中,此特定服务器在常规 HTTP 上运行。这里没有问题。

$ curl http://192.168.101.1
<html><body><h1>It works!</h1></body></html>

请参考:15 个实用的 Linux cURL 命令示例

但是,如果您使用 SSLv3,使用 -3 选项,它会返回“sslv3 alert handshake failure”错误消息。

$ curl -3 https://192.168.101.1
curl: (35) error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure

如果您使用 SSLv2,使用 -2 选项,它会返回“未知 SSL 协议”错误消息。

$ curl -2 https://192.168.101.1
curl: (35) Unknown SSL protocol error in connection to 192.168.101.1:443 

在这种情况下,在这个特定的服务器上,它只支持 TLS。因此,请使用 -1 选项,如下所示。

$ curl -1 https://192.168.101.1
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

在这种情况下,由于我们使用的是 IP 地址,它与安装在网络服务器上的 SSL 证书不匹配。因此,我们收到上述“SSL3_GET_SERVER_CERTIFICATE:certificate verify failed”错误消息。

Curl 默认执行 SSL 证书验证。如果您使用的是 CA 授权捆绑包,则默认捆绑包名称是 curl-ca-bundle.crt。您可以使用 –cacert 选项指定不同的捆绑包。

但是,在我们的例子中,我们想使用 TLSv1 协议,但没有 SSL 证书验证。为此,请使用 -k 选项(或 –insecure 选项),它不会执行 SSL 证书验证。

以下是 -k 选项的用法。

$ curl -k https://192.168.101.1
curl: (35) Unknown SSL protocol error in connection to 192.168.101.1:443 

如果您想了解有关 CURL 命令引发的错误的更多详细信息,请使用 -v 选项。正如你在下面看到的。即使我们没有传递协议选项,从命令输出中,我们也可以看到它正在尝试为此使用 SSLv2。

$ curl -k -v https://192.168.101.1
* About to connect() to 192.168.101.1 port 443
*   Trying 192.168.101.1... connected
* Connected to 192.168.101.1 (192.168.101.1) port 443
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSLv2, Client hello (1):
Unknown SSL protocol error in connection to 192.168.101.1:443 
* Closing connection #0
curl: (35) Unknown SSL protocol error in connection to 192.168.101.1:443 

命令行解决方案

请参阅:wget vs curl:如何使用 wget 和 curl 下载文件

因此,在我们的例子中,由于 SSLv2 和 SSLv3 在服务器端被禁用,并且由于某种原因,如果 curl 没有自动设置正确的协议,当我们只想从命令行使用带有 curl 的 TLSv1 协议时,以下工作有效如下图所示。

$ curl -k -1 https://192.168.101.1
<html><body><h1>It works!</h1></body></html>

如果您想查看其具体功能的详细信息,请传递 -v 选项,如下所示。

$ curl -k -1 -v https://192.168.101.1

以上也可以使用以下替代选项来完成

$ curl --insecure --tlsv1 --verbose https://192.168.101.1

同样,在上面的命令中:

  • -1(或)–tlsv1 用于 TLSv1 (SSL)
  • -k (or) –insecure 允许连接到没有证书的 SSL 站点 (H)
  • -v (or) –verbose 使操作更健谈(小写 v)

来自 PHP 的解决方案

从您的 PHP 代码中,如果您使用 cURL 函数,并且喜欢设置协议选项,您应该使用 curl_setopt 或 curl_setopt_array 函数。

如果您只想设置一个选项,请使用 curl_setopt。

curl_setopt($c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

在上面:

  • $c 是您从 curl_init() 函数获得的 curl 变量,当您从 PHP 程序创建新的 cURL 资源时。
  • CURLOPT_SSLVERSION 是一个 curl 选项名称。
  • CURL_SSLVERSION_TLSv1 是参数#2 中相应选项的 curl 值

您也可以使用数字代替“CURL_SSLVERSION_TLSv1”。在本例中,这等价于 1。

curl_setopt($c, CURLOPT_SSLVERSION, 1);

以下是您可以设置的可能的 CURLOPT_SSLVERSION 值。您可以使用描述性常量或下面显示的相应数字。

  • CURL_SSLVERSION_DEFAULT (0)
  • CURL_SSLVERSION_TLSv1 (1)
  • CURL_SSLVERSION_SSLv2 (2)
  • CURL_SSLVERSION_SSLv3 (3)
  • CURL_SSLVERSION_TLSv1_0 (4)
  • CURL_SSLVERSION_TLSv1_1 (5)
  • CURL_SSLVERSION_TLSv1_2 (6)

如果要设置多个 CURL 选项,请使用 curl_setopt_array ,如下所示。在这里,除了设置 CURLOPT_SSLVERSION 之外,它还设置了一些其他的 curl 选项。

在这种情况下,第二个参数将是一个包含多个 CURL 选项的数组,如下所示。

curl_setopt_array($c, array
(
  CURLOPT_SSL_VERIFYHOST => 0,
  CURLOPT_SSL_VERIFYPEER => 0,
  CURLOPT_SSLVERSION => 1
));
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。