【问题标题】:Trying to connect to HTTPS site via IP (with known hostname) in PHP, getting "Peer certificate ... does not match expected CN ..."尝试在 PHP 中通过 IP(具有已知主机名)连接到 HTTPS 站点,得到“对等证书 ... 与预期的 CN ...不匹配”
【发布时间】:2017-11-20 23:56:00
【问题描述】:

我正在编写一个 CLI PHP 脚本,它将连接到服务器以获取和处理一些数据。运行它的系统有时互联网速度很慢,所以我想在脚本中添加一些详细信息来显示 DNS 查找、连接等。

所以,我从使用普通的file_get_contents() 切换,并付出了额外的努力来创建 TCP 套接字、手动发送 HTTP 数据等,这样我就可以将这些离散的操作与状态更新穿插在一起。

但是,初始 DNS 查找和连接仍可能需要长达 5 秒的时间,其中大部分是由于 8.8.8.8 的随机缓慢造成的。所以,我决定看看我是否可以在 DNS 查找和实际连接调用之间插入:

$ip = gethostbyname('google.com.');

$stream = stream_socket_client('tls://'.$ip.':443/');

好吧,不幸的是……

PHP Warning:  stream_socket_client(): Peer certificate CN=`*.google.com' did not 
match expected CN=`216.58.196.142' in ...

PHP Warning:  stream_socket_client(): Failed to enable crypto in ...

PHP Warning:  stream_socket_client(): unable to connect to tls://216.58.196.142:443/
(Unknown error) in ...

...这会导致 PHP 的 TLS 堆栈崩溃。 这是完全合适的,配置正确,而不是错误,因为它只看到 IP 地址而不是主机名,它有正当理由消化不良。

(...虽然 PHP 应该 然后去总结“这可能是 MITM 攻击”为“未知错误”... facepalm; 但我离题了.)

我的基本问题是 curl、sockets 或流都没有为我提供描述“即将连接”、“正在进行 DNS 查找”、“已连接”等通知的事件回调。 :(

【问题讨论】:

  • 此远程站点是否允许此类操作?
  • @nogad:你什么意思?这是一个标准的 HTTPS 服务器。在我正在做的测试中,我使用的是 google.com,这实际上是等效的。

标签: php ssl dns


【解决方案1】:

不要尝试通过 PHP 流重新实现 HTTPS。我们不应该解释为什么这是一个坏主意。

  1. 如果您想跳过 DNS 查找,请使用 /etc/hosts。 [超级坏主意]

  2. 不要跳过 DNS,这是一个非常糟糕的主意。

    PHP 和大多数 Linux 发行版都没有实现本地 DNS 解析器/缓存,这通常会导致您的 PHP 应用程序指向的任何 DNS 服务器受到攻击,如果您指向一个糟糕的 DNS 服务器,则性能会很差。 [虽然在你的情况下,我敢打赌你会因为锤击而受到限制]

    所以要么:

    1. 点缓存解析器位于本地网络中的某个位置,例如:您的提供商的。
    2. 在机器上安装一个简单的缓存 DNS 解析器,例如:nscd、dnsmasq 或 bind。

     

    如果您在此之后仍然遇到 DNS 延迟问题,那么明智的做法是将这个问题上报给您的提供商。

【讨论】:

    猜你喜欢
    • 2016-01-07
    • 2019-05-27
    • 1970-01-01
    • 2017-05-24
    • 2018-01-05
    • 1970-01-01
    • 2016-12-07
    • 1970-01-01
    • 2019-12-17
    相关资源
    最近更新 更多