【问题标题】:php-fpm crashed when curl or file_get_contents request a https urlcurl 或 file_get_contents 请求 https url 时 php-fpm 崩溃
【发布时间】:2013-06-30 14:58:43
【问题描述】:

我的服务器是 nginx + php-fpm

下面的代码会导致错误

file_get_contents('https://github.com');

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://github.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$output = curl_exec($ch); //crash here
curl_close($ch);

网页显示502错误

nginx日志是

[error] 2656#0: *541 recv() failed (104: Connection reset by peer) while reading response header from upstream

fpm 日志是

7 月 3 日 00:37:37.619903 [通知] fpm_got_signal(),第 48 行:收到 SIGCHLD

7 月 3 日 00:37:37.619926 [警告] fpm_children_bury(),第 215 行:子 3567(池默认)在信号 11 SIGSEGV(核心转储)上退出 417.576755 秒后

7 月 3 日 00:37:37.620807 [通知] fpm_children_make(),第 352 行:子 4193(池默认)开始

如果请求 url 以 http:// 开头,则一切正常。

php配置命令是

'./configure' '--prefix=/www/nginx_php-5.2.17' '--with-config-file-path=/www/nginx_php-5.2.17/etc' '--with-mysql=/www/mysql' '--with-iconv=/usr' '--with-freetype-dir' '--with-jpeg-dir' '--with-png-dir' '--with-zlib' '--with-libxml-dir=/usr' '--enable-xml' '--disable-rpath' '--enable-discard-path' '--enable-inline-optimization' '--with-curl' '--enable-mbregex' '--enable-mbstring' '--with-mcrypt=/usr' '--with-gd' '--enable-gd-native-ttf' '--with-openssl' '--with-mhash' '--enable-ftp' '--enable-sockets' '--enable-zip' '--enable-fastcgi' '--enable-fpm' '--with-fpm-conf=/www/etc/php-fpm.conf'

【问题讨论】:

  • 崩溃检查后curl_error()你会看到更多信息
  • 我也有同样的问题。你找到解决办法了吗?
  • 我遇到了同样的问题。如果您确实找到了解决方案,请不吝赐教。

标签: curl nginx openssl php


【解决方案1】:

我最近不得不处理一个类似的问题。没有深入了解细节,问题是旧的 PHP 版本(从源代码构建)与包管理器中的新 cURL 和 OpenSSL 库的组合由于版本不兼容而导致冲突。

我最终解决此问题的基本步骤是从发行包管理器安装 cURL 和 OpenSSL。使用它们下载兼容 cURL 和 OpenSSL 版本的源包。卸载卷曲。从源代码构建 OpenSSL,然后构建 cURL,配置为使用我刚刚构建的 OpenSSL。从那里,我能够使用新构建的 cURL 和 OpenSSL 库构建 PHP。

这是我最终得到的安装脚本的 sn-p:

# [curl should have been installed from package manager before this]
# Note: This script is based on Ubuntu 18. Paths may differ for different distributions. 

cd /usr/local/src

# Download OpenSSL and cURL sources first, using the pre-installed version of cURL. 
curl -SL --progress-bar https://www.openssl.org/source/old/1.0.2/openssl-1.0.2n.tar.gz -o openssl-1.0.2n.tar.gz
curl -SL https://curl.se/download/curl-7.65.0.tar.xz -o curl-7.65.0.tar.xz

# Remove the pre-installed cURL, we'll rebuild it from the source bundle,
# using the shared libraries from the OpenSSL version we will build now. 
apt-get remove -y --purge curl

# Extract and build OpenSSL from source package, making sure to enable the `shared` option
# so that `libssl.so` and `libcrypto.so` shared libraries are built, too. 
tar xvf openssl-1.0.2n.tar.gz
cd openssl-1.0.2n
./config shared # add the `-d` flag to include debug symbols
make -j 10
make install_sw

# Add a new config file for the dynamic linker, so that it knows to look for the new shared libraries we're building. 
# The first line is for where the new cURL libs will be, and the latter is where new OpenSSL libs will be.
echo -e "/usr/local/lib \n/usr/local/ssl/lib" > /etc/ld.so.conf.d/local.conf

# Reload the linker cache
ldconfig

cd /usr/local/src

# Extract and build cURL from source package, making sure to tell it to use the OpenSSL version we just built. 
tar -xvf curl-7.65.0.tar.xz
cd curl-7.65.0
./configure --with-ssl=/usr/local/ssl # add the `--enable-debug` flag to include debug symbols
make -j 10
make install

# Reload the linker cache
ldconfig

cd /usr/local/src

# Reload utility (bin) locations; find the newly built `curl` binary. 
hash -r

curl -SL --progress-bar http://www.php.net/distributions/php-5.5.38.tar.bz2 -o php-5.5.38.tar.bz2
tar -xvf php-5.5.38.tar.bz2
cd php-5.5.38

# Make sure the `--with-openssl` flag includes a path to the SSL libs created after building it from source. 
# `--with-curl`, by default, will look in `/usr/local/lib` and `/usr/local/include`; When built from source, 
# the generated libraries WILL be placed here, so you shouldn't need to specify the path, unless you put them elsewhere
# or your distro uses different paths
./configure \
    --with-openssl=/usr/local/ssl \ 
    --with-curl \
    # Any other config flags here
    # Other flags were omitted for this example

make -j 10
make install

注意:我是为测试和开发环境编写的。即使忽略它使用的是 PHP 5.5,这也可能不适合生产环境。

【讨论】:

    【解决方案2】:

    尝试添加这两个:

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    

    它们会阻止 SSL 证书的验证。这可能是验证失败的问题。除非必须验证来源,否则在使用cURL 下载数据时始终添加这两行。

    PS不确定这是否会对你有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-05
      • 2012-10-11
      • 1970-01-01
      • 2021-05-31
      • 1970-01-01
      相关资源
      最近更新 更多