Debug也能骗人——Ubuntu 下 PHP curl https 段错误(或者nginx502)

今天在开发过程中使用本地服务器访问https接口,nginx报错502。
Tony's blog image

  1. 首先查看nginx错误日志,错误日志显示:
  1. [error] 2578326#0: *73 recv() failed (104: Connection reset by peer) while reading response header from upstream

Tony's blog image

通过某搜索引擎,终于找到了错误代码的含义
Tony's blog image

于是啊,更改Nginx配置,增大buffer size,增加请求时间。
再次尝试,还是502.
有人说,是PHP版本问题,换了PHP版本,依然502.
再次崩溃,因为使用的是guzzleHttp,怀疑是guzzleHttp问题,所以直接写了个脚本来通过curl访问。

  1. <?php
  2. $ch = curl_init();
  3. //设置选项,包括URL
  4. curl_setopt($ch, CURLOPT_URL, 'https://www.baodu.com');
  5. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
  6. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
  7. curl_setopt($ch, CURLOPT_HEADER, 0);
  8. //执行并获取HTML文档内容
  9. $output = curl_exec($ch);
  10. //释放curl句柄
  11. curl_close($ch);
  12. var_dump($output);
  13. ?>

再次验证,发现还是502. 于是怀疑是https缘故,将网址换为http,果然能访问了。
所以再次看curl文档,无非就是忽略ssl证书访问,无论怎么改,还是502.
更有扯淡的将请求头user-agent改为null.


寻找了一圈答案无果后,休息片刻,继续搜寻答案,终于见到了曙光: 只要链接是https的,必然出现段错误,这也是导致502的原因。而http链接可以正常访问。

  1. 首先,开启dump选项
    1. ulimit -c unlimited
  2. 然后,运行PHP生成core文件,
    1. php test.php
  3. 然后在当前目录会生成core文件,用以下命令查看dump的内容
    1. gdb php -c core
    Tony's blog image
    从截图中可以看出,libssl有问题。
    也有人出现了相同的问题,官方提示说是系统curl使用的ssl库和php编译时使用的ssl库(opsnssl)不一至导致的。
    于是查看phpinfo信息,发现php curl使用的openssl与ssl库的版本不一致。
    Tony's blog image
    Tony's blog image

一个是1.1.1i,另一个是1.0.2u。
这两个软件的openssl版本明显不一致,所以,下一步就是要重新编译安装curl,使用openssl版本1.0.2u.

  1. 下面是安装新版curl的过程。
    a. 下载新版curl
    1. wget https://curl.haxx.se/download/curl-7.70.0.tar.gz --no-check-certificate
    b. 解压
    1. tar vxzf curl-7.70.0.tar.gz && cd curl-7.70.0
    c. 编译
    1. sudo ./configure --with-ssl=/usr/local/openssl --prefix=/usr/local #php的openssl在这个目录,所以指定这个
    2. sudo make
    3. sudo make install
    d. 然后从新打开一个terminal
  1. curl -V
  2. # 输出下列信息
  3. # Release-Date: 2020-04-29
  4. # Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
  5. # Features: AsynchDNS brotli HTTPS-proxy IPv6 Largefile libz NTLM NTLM_WB SSL TLS-SRP UnixSockets

说明curl已经重装成功,然后重启php服务,再次查看phpinfo信息
Tony's blog image

e. 再运行测试文件,发现问题解决了。

Tony's blog image


事实证明: debug出来的信息也会骗人的。