尝试通过PHP(具有已知主机名)在PHP中连接到HTTPS站点,获取“对等证书...与预期的CN ...不匹配”

时间:2017-11-20 23:56:01

标签: php ssl dns

我正在编写一个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;但我离题了。)

我的基本问题是卷曲,套接字或流都没有为我提供描述“即将连接”,“进行DNS查找”,“连接”等通知的事件回调。 :(

1 个答案:

答案 0 :(得分:0)

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

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

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

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

    所以:

    1. 位于本地网络内部的点缓存解析程序,例如:您的提供商。
    2. 在计算机上安装一个简单的缓存DNS解析程序,例如:nscd,dnsmasq或bind。
    3. 如果您仍然在此之后出现DNS延迟问题,那么理所当然的事情就是将此问题上报给您的提供商。