php 将 cURL 与 SNI(服务器名称指示)一起使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12941703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use cURL with SNI (Server Name Indication)
提问by Justin
I am trying to use cURL to post to an API that just started using SNI (so they could host multiple ssl certs on 1 IP address).
我正在尝试使用 cURL 发布到刚开始使用 SNI 的 API(因此他们可以在 1 个 IP 地址上托管多个 ssl 证书)。
My cURL stopped working as a result of this move to SNI. They explained that it's because cURL is getting *.domain-a.com back instead of *.domain-b.com so the SSL fails.
由于迁移到 SNI,我的 cURL 停止工作。他们解释说,这是因为 cURL 正在返回 *.domain-a.com 而不是 *.domain-b.com,因此 SSL 失败。
This seems to be a bug in cURL because the API URL has no errors when visited from a browser.
这似乎是 cURL 中的一个错误,因为从浏览器访问 API URL 时没有错误。
Using this code, it does work:
使用此代码,它确实有效:
exec('curl -k -d "parameters=here", https://urlhere.com/', $output);
print_r($output);
However, using -k is bad because it doesn't verify the SSL cert.
但是,使用 -k 是不好的,因为它不验证 SSL 证书。
Using this code, does NOT work:
使用此代码,不起作用:
exec('curl -d "parameters=here", https://urlhere.com/', $output);
print_r($output);
So my question is, how can I use curl with SNI and still verify the SSL (not have to use -k). Is there another setting in PHP or a cURL option I can set to work around this?
所以我的问题是,我如何将 curl 与 SNI 一起使用并仍然验证 SSL(不必使用 -k)。我可以设置 PHP 中的其他设置或 cURL 选项来解决这个问题吗?
回答by Bruno
To be able to use SNI, three conditions are required:
为了能够使用 SNI,需要三个条件:
- Using a version of Curl that supports it, at least 7.18.1, according to the change logs.
- Using a version of Curl compiled against a library that supports SNI, e.g. OpenSSL 0.9.8j (depending on the compilation options some older versions).
- Using TLS 1.0 at least (not SSLv3).
- 根据更改日志,使用支持它的 Curl 版本,至少 7.18.1 。
- 使用针对支持 SNI 的库编译的 Curl 版本,例如 OpenSSL 0.9.8j(取决于某些旧版本的编译选项)。
- 至少使用 TLS 1.0(不是 SSLv3)。
Note that Curl's debug code (-v) only displays the major version number (mainly to distinguish between SSLv2 and SSLv3+ types of messages, see ssl_tls_trace), so it will still display "SSLv3" when you use TLS 1.0 or above (because they're effectively SSL v3.1 or above, 3 is the same major version number).
请注意,Curl 的调试代码 ( -v) 仅显示主要版本号(主要是为了区分 SSLv2 和 SSLv3+ 类型的消息,请参阅ssl_tls_trace),因此当您使用 TLS 1.0 或更高版本时,它仍然会显示“SSLv3”(因为它们实际上是 SSL v3.1 或更高版本,3 是相同的主版本号)。
You could check that your installed version of curl can use SNI using Wireshark. If you make a connection using curl -1 https://something, if you expand the "Client Hello" message, you should be able to see a "server_name" extension.
您可以使用 Wireshark 检查您安装的 curl 版本是否可以使用 SNI。如果您使用 建立连接curl -1 https://something,如果您展开“Client Hello”消息,您应该能够看到“ server_name”扩展名。
I'm not sure which SSL/TLS version is used by default (depending on your compilation options) when you use curlwithout -1(for TLS 1.0) or -3(for SSLv3), but you can try to force -1on your command, since it won't work with SSLv3 anyway.
当您curl不使用-1(对于 TLS 1.0)或-3(对于 SSLv3)时,我不确定默认使用哪个 SSL/TLS 版本(取决于您的编译选项),但是您可以尝试强制-1执行您的命令,因为它不会无论如何都不能使用 SSLv3。
回答by hardik p
Along with the required library and Curl version, the request should use resolve to send SNI in the curl:
连同所需的库和 Curl 版本,请求应该使用 resolve 在 curl 中发送 SNI:
curl -vik --resolve example.com:443:198.18.110.10 https://example.com/

