Ubuntu 下 PHP curl https 段错误(或者nginx502)

昨天下午在平常写代码的时候遇到一个问题。就是在调用curl_exec()后出现502。而后立刻编写了一个测试脚本:php

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.baidu.com');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$res = curl_exec($ch);
print_r($res);exit;

发现,只要连接是https的,必然出现段错误,这也是致使502的缘由。而http连接能够正常访问。css

php[15304]: segfault at 7f43cf4b7c00 ip 00007f43cf4b7c00 sp 00007ffda84c57d8 error 15 in libssl.so.1.1[7f43cf4b4000+4000]

上面的日志是我经过系统的日志程序来查看的,我用的是Linux Mint操做系统,打开方式为:菜单->日志。而后搜索关键词php,以下图所示:html

clipboard.png

而后也能够经过gdp来查看段错误,linux

首先,开启dump选项git

ulimit -c unlimited

而后,运行PHP生成core文件,redis

php test.php

而后在当前目录会生成core文件,用如下命令查看dump的内容:ubuntu

gdb php -c core

这是显示结果:curl

GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from php...done.
[New LWP 11242]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `php test.php'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007fe27bd51c00 in ?? () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1

注意到最后一行了吗,提示咱们libssl有问题。测试

解决问题的灵感从这里来的:
https://bugs.php.net/bug.php?...fetch

也有人出现了相同的问题,官方提示说是系统curl使用的ssl库和php编译时使用的ssl库(opsnssl)不一至致使的。而后我查找了phpinfo信息,发现php使用的curl版本以及它使用的ssl库(openssl)版本:

clipboard.png

而后查看PHP编译时的openssl版本:

clipboard.png

这两个软件的openssl版本明显不一致,因此,下一步就是要么重新编译PHP,使用系统的openssl版本1.1.0g,要么从新编译安装curl,使用openssl版本1.0.2o,我选择了后者。

下面是安装新版curl的过程。

首先下载新版curl

wget https://curl.haxx.se/download/curl-7.62.0.tar.gz

而后解压并安装

tar vxzf curl-7.62.0.tar.gz
cd curl-7.62.0
sudo ./configure --with-ssl=/usr/local/openssl --prefix=/usr/local #php的openssl在这个目录,因此指定这个
sudo make
sudo make install

而后重新打开一个terminal

curl -V
curl 7.62.0 (x86_64-pc-linux-gnu) libcurl/7.62.0 OpenSSL/1.0.2o zlib/1.2.11
Release-Date: 2018-10-31
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP UnixSockets HTTPS-proxy

发现系统的curl版本已经升级成功,而且openssl的版本也是但愿的版本。

clipboard.png

而后咱们再运行测试文件,

➜  tests php test.php                
php: /usr/local/lib/libcurl.so.4: no version information available (required by php) #这个是新问题
<!DOCTYPE html><!--STATUS OK-->
<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <link rel="dns-prefetch" href="//s1.bdstatic.com"/>
    <link rel="dns-prefetch" href="//t1.baidu.com"/>
    <link rel="dns-prefetch" href="//t2.baidu.com"/>
    <link rel="dns-prefetch" href="//t3.baidu.com"/>
    <link rel="dns-prefetch" href="//t10.baidu.com"/>
    <link rel="dns-prefetch" href="//t11.baidu.com"/>
    <link rel="dns-prefetch" href="//t12.baidu.com"/>
    <link rel="dns-prefetch" href="//b1.bdstatic.com"/>
    <title>百度一下,你就知道</title>
    <link href="https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/static/home/css/index.css" rel="stylesheet" type="text/css" />
    <!--[if lte IE 8]><style index="index" >#content{height:480px\9}#m{top:260px\9}</style><![endif]-->
    <!--[if IE 8]><style index="index" >#u1 a.mnav,#u1 a.mnav:visited{font-family:simsun}</style><![endif]-->
    <script>var hashMatch = document.location.href.match(/#+(.*wd=[^&].+)/);if (hashMatch && hashMatch[0] && hashMatch[1]) {document.location.replace("http://"+location.host+"/s?"+hashMatch[1]);}var ns_c = function(){};</script>
    <script>function h(obj){obj.style.behavior='url(#default#homepage)';var a = obj.setHomePage('//www.baidu.com/');}</script>
    <noscript><meta http-equiv="refresh" content="0; url=/baidu.html?from=noscript"/></noscript>
    <script>window._ASYNC_START=new Date().getTime();</script>

发现能够获取https的内容了。


解决这个问题:

php: /usr/local/lib/libcurl.so.4: no version information available (required by php) #这个是新问题

解决方式
第一,把/usr/bin里的curlcurl-config替换为/usr/local/bin下的对应文件

sudo rm -rf /usr/bin/curl*
sudo ln -s /usr/local/bin/curl /usr/bin/curl
sudo ln -s /usr/local/bin/curl-config /usr/bin/curl-config

第二,因为我用的是lnmp1.5一键安装包,因此,我从新安装了下php。这个问题的缘由是php在编译的时候获得的libcurl版本是之前系统的版本,如今libcurl升级了,因此对于php来讲版本信息就消失了,因此咱们只须要从新安装一遍php:

cd lnmp1.5
sudo ./upgrade

这里会提示你输入要升级哪一个软件,你选择PHP。

而后会提示你输入PHP版本号,你输入5.6.38。

最后按回车便可。

相关文章
相关标签/搜索