飘在云端

东西南北,海角天涯

· webServer · · 286次浏览

宝塔 php 安装失败 文件不存在 undefined symbol: EVP_md2

前一段时间也就是 7月1号,OpenSSH 服务端有个高危 RCE 漏洞:CVE-2024-6387
赶着去给服务端升级了下,并重启了服务器

apt update && apt upgrade -y

更新系统之后,不知道为什么手贱去升级了一下 php 8.1
升级时秒报错,没有日志输出,没在意,因为当时服务没挂
结果一两天后发现跑着 php8.1 的网站寄了,检查后台发现php8.1服务掉了,无法启动,报错

/www/server/php/81/sbin/php-fpm: symbol lookup error: /www/server/php/81/sbin/php-fpm: undefined symbol: EVP_md2, version OPENSSL_1_1_0

然后还发现不只是没安装的版本也无法安装,比如 8.3,而是所有 php 版本都是会报这个错误及安装失败,文件不存在:xxxxxxx

原因是宝塔在系统安装了多个 openssl 版本,php 编译时并不是系统的版本,而是特定的 openssl 1.1.1 版本,结果 PHP-FPM 在运行时使用了非 OpenSSL 1.1.1 版本,或者说没有找到 openssl 1.1.1 版本的库路径,导致符号查找错误

我直接去改安装脚本 /www/server/panel/install/php.sh,发现宝塔没具体定义 8.1 使用的特殊编译参数,而是把它作为 if xxxx else 兜底规则的一部分进行处理,其默认参数如下

在第 645 行左右,上面是 php8.3 的 编译配置段落 if [ "${version}" == "8.3" ];then ,接着下一个的兜底处理 else 后面跟着的 ./configure xxxxxxxxxxxxxxxxxx
原本是

./configure --prefix=${php_setup_path} --with-config-file-path=${php_setup_path}/etc --enable-fpm --with-fpm-user=www --with-fpm-group=www     --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-iconv-dir --with-freetype --with-jpeg --with-zlib --with-libxml-dir=/usr --enable-xml --di    sable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-intl --enable-pcntl --enable-ftp --enable-gd --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-soap --with-gettext --enable-mbstring --disable    -fileinfo --enable-opcache --with-sodium=/usr/local/libsodium --with-webp ${i_make_args}

修改一下 --with-openssl 参数指定具体安装的 openssl 1.1.1 库路径,改成 --with-openssl=/usr/local/openssl111,修改后如下

./configure --prefix=${php_setup_path} --with-config-file-path=${php_setup_path}/etc --enable-fpm --with-fpm-user=www --with-fpm-group=www     --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-iconv-dir --with-freetype --with-jpeg --with-zlib --with-libxml-dir=/usr --enable-xml --di    sable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-intl --enable-pcntl --enable-ftp --    enable-gd --with-openssl=/usr/local/openssl111 --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-soap --with-gettext --enable-mbstring --disable    -fileinfo --enable-opcache --with-sodium=/usr/local/libsodium --with-webp ${i_make_args}

这还不够,最多就编译成功,我测试时,编译日志能看到 -I/usr/local/openssl111/include ,但是 php-fpm 还是无法启动

这里估计是没有使用编译时的 openssl 版本,手动检查下,查看 php-fpm 链接的 openssl 版本

ldd /www/server/php/81/sbin/php-fpm | grep ssl

返回内容

libssl.so.1.1 => /usr/local/openssl111/lib/libssl.so.1.1 (0x00007fc46143c000)
libcrypto.so.1.1 => /usr/local/openssl111/lib/libcrypto.so.1.1 (0x00007fc45f8fd000)
libssl.so.3 => /lib/x86_64-linux-gnu/libssl.so.3 (0x00007fc45ead3000)

可以看到 php-fpm 的确链接到了 openssl 1.1.1, libssl.so.1.1 => /usr/local/openssl111/lib/libssl.so.1.1
但是 libssl.so.3 => /lib/x86_64-linux-gnu/libssl.so.3 (0x00007fc45ead3000) 表明系统的确用的是 OpenSSL 3.0.2

启动时没有正确识别到 openssl 1.1.1,而是使用了系统的 openssl 3.0.2,这时要配置一下库路径防止它弄混了

echo "/usr/local/openssl111/lib"| tee /etc/ld.so.conf.d/openssl-1.1.1.conf

接着刷新一下更新共享库缓存

ldconfig -v

接着手动安装 php 8.1

/www/server/panel/install/php.sh install 81

最后就能用了,也能正常安装扩展了

评论 (0条)