尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

CentOS7 修复 libssl.so.1.1 缺失:腾讯云镜像安装 openssl11-libs

CentOS7 修复 libssl.so.1.1 缺失:腾讯云镜像安装 openssl11-libs 在 CentOS7 上跑程序时屏幕上突然跳出一行error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory不管是自己编译的 nginx、Python 3还是从同事那边拷贝过来的二进制工具都会让人心头一紧。我处理过很多次这类问题经验是别急着去源码编译 OpenSSL那样往往会把系统原有的 libssl.so.10 和 PATH 搞得一团糟先用最小代价把 libssl.so.1.1 这个运行库补上再考虑要不要升级主版本。这篇文章就把排查思路、修复步骤和腾讯云镜像下载 RPM 包的方法一次性讲清楚适合正在维护 CentOS7 的运维、开发以及自建服务的同学直接照着操作。1. 问题现象报错背后其实分好几种情况1.1 我处理过的两个典型场景第一次遇到这个报错是帮同事排查一个刚编译完的 Python 3.8 解释器。他在自己开发机上跑得好好的换到一台 CentOS7 服务器上就起不来执行命令直接甩出error while loading shared libraries: libssl.so.1.1: cannot open shared object file。我下意识先看了ldd /usr/local/bin/python3.8发现确实有一个依赖指向libssl.so.1.1 not found而开发机上是有的。第二次更隐蔽是某个监控脚本依赖的二进制包从旧服务器迁移到新环境编译时链接的是 OpenSSL 1.1.1目标机器只有 CentOS7 自带的 OpenSSL 1.0.2 运行库运行时自然找不到libssl.so.1.1。这类问题在迁移、换机、容器化打包时特别常见本质都一样程序编译的时候链接了某个 soname运行环境的动态库加载器在默认搜索路径里找不到同名文件。很多人的第一反应是“升级 OpenSSL”于是去找源码包make make install结果反而把系统自带的 libssl.so.10、libcrypto.so.10 也覆盖了连 yum、curl 都开始报错。听到这话我其实特别理解因为当年我自己也踩过这个坑所以我会建议你先别升级主版本先把缺的库文件补上。1.2 先用 ldd 判断是“缺文件”还是“版本不匹配”处理这类报错第一步永远是ldd定位而不是盲目下载安装包。假设报错程序叫mytool执行ldd /path/to/mytool | grep libssl输出里面可以清楚看到它到底找的是哪个库、有没有找到。这里要区分两种情况libssl.so.1.1 not found系统加载路径里完全没有这个文件属于典型的缺库问题。libssl.so.1.1 /usr/lib64/libssl.so.1.1但程序运行时依然报错这不是缺失而是符号版本不对比如库文件太老、缺少程序需要的OPENSSL_1_1_0版本符号。对于第二种情况单纯创建软链接把libssl.so.1.0.0指到libssl.so.1.1是行不通的两个 soname 背后的 ABI 不兼容强改会有段错误风险。正确做法是安装与系统匹配的 OpenSSL 1.1 运行库 RPM 包。我习惯再补一个命令确认二进制到底是 64 位还是 32 位file /path/to/mytool如果是 32 位程序就需要找 32 位的openssl11-libs包这个细节很容易被忽略。很多人装完 64 位库后报错依旧最后才发现问题出在i686库上。2. 为什么 CentOS7 会缺 libssl.so.1.12.1 soname 和 OpenSSL 版本演进的关系要理解这个报错得先弄清楚 CentOS7 默认的 OpenSSL 版本脉络。CentOS7 发行版默认的 OpenSSL 是 1.0.2 系列它对应的动态库文件是libssl.so.10和libcrypto.so.10。而很多社区软件、新版本编程语言、以及用较新工具链编译出来的二进制链接时使用的是 OpenSSL 1.1.1 系列动态库文件名为libssl.so.1.1和libcrypto.so.1.1。这里的关键是 soname也就是.so后面那串数字。程序编译时会把 soname 写进二进制的 NEEDED 段运行时并不会聪明到“看到libssl.so.1.0.0也凑合用”而是严格按记录的名字去找。比如readelf -d mytool | grep NEEDED能看到它依赖的真实库名如果里面写的是libssl.so.1.1那么系统里只有libssl.so.1.0.0就一定会报 cannot open shared object file。打个比方这就像你平时习惯用某个型号的电池设备上明确写了“7号电池”你现在手里只有 5 号电池虽然都是电池但装不进去。所以不要把 OpenSSL 的 1.0.2 和 1.1.1 当成“版本高低问题”要当成“接口协议不同”来处理。2.2 缺的是 openssl11-libs不是 openssl-libsCentOS7 的官方仓库里openssl-libs包提供的是 OpenSSL 1.0.2 系列的运行库也就是libssl.so.10。如果你在网上搜到“安装 openssl-libs”的办法在 CentOS7 上大概率解决不了libssl.so.1.1的问题因为你装完还是只有一个 1.0.2 的库。真正对应libssl.so.1.1的包名叫openssl11-libs它会安装/usr/lib64/libssl.so.1.1和/usr/lib64/libcrypto.so.1.1同时不影响系统原有的libssl.so.10。这种设计有点像把老旧运行库和新版本运行库并排摆放两者互不干扰。我在一开始没有搞清楚这个问题时也走了一些弯路反复去源码编译 OpenSSL。后来看了 RPM 包命名才明白CentOS7 官方仓库实际上早就为你准备好了对应的运行库只是名字很容易让人误会。所以这篇修复文章的核心就是教你把openssl11-libs这个包用最快、最可靠的方式装上。3. 腾讯云镜像下载 RMP 包前的准备工作3.1 为什么推荐走腾讯云镜像源提到下载 RPM 包最常见的做法是直接yum install但 CentOS7 官方源在国外公网访问有时候非常慢尤其是一次性下载几十个依赖包时特别明显。这时用国内镜像站就非常有价值。腾讯云的镜像站地址是mirrors.cloud.tencent.com如果你是腾讯云服务器还可以用内网源mirrors.tencentyun.com内网访问速度快、不占用公网带宽还不容易出错。不只是 CentOS 的基础包很多常用软件包都能在镜像站里找到。这样做还有一个额外好处通过镜像站下载的文件与 CentOS 官方仓库保持一致RPM 的 GPG 签名都保留着安装前可以做校验比网上随便找的第三方 RPM 包靠谱得多。我在生产环境操作时一向坚持“能走 yum 就走 yum能走镜像源就走镜像源”因为可追溯、可回滚出了问题也容易查原因。3.2 下载前需要确认的三件事在开始下载安装之前我建议先快速确认几项系统信息避免装错架构、装错版本。第一确认系统版本cat /etc/redhat-release输出一般是CentOS Linux release 7.9.2009 (Core)这类内容。如果你的系统是 CentOS8 或者别的发行版下面的包名和路径就不适用千万别直接套用。第二确认架构uname -m腾讯云镜像站里 CentOS7 的os/x86_64和os/aarch64是两个不同目录如果你的机器是 ARM 架构需要去对应的 aarch64 目录下找 RPM 包。第三确认基础工具可用。修复的时候至少要能执行curl、wget、rpm这几个命令。通常情况下CentOS7 的 curl 依赖的是libssl.so.10所以不会因为缺 1.1 而挂掉可以放心使用。万一真的出现连 curl 都起不来的极端情况就得从同版本机器上拷贝 RPM 包或者挂载系统安装光盘来操作。4. 修复 libssl.so.1.1 缺失的完整实操过程4.1 方法一配置腾讯云 yum 源后直接安装 openssl11-libs如果 yum 本身还能用最快的路径是先把 yum 源切到腾讯云然后一条命令安装openssl11-libs。先备份原有源配置别嫌这一步麻烦万一后续需要回退就会感谢自己cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.cloud.tencent.com/help/centos7-base.repo下载完仓库文件后清理缓存并重建yum clean all yum makecache fast然后直接安装yum install -y openssl11-libs装完检查库文件是否出现ldconfig ls -l /usr/lib64/libssl.so.1.1如果能看到libssl.so.1.1 - libssl.so.1.1.1k之类的软链接说明已经装好了。再用ldd验证之前报错的程序ldd /path/to/mytool | grep libssl这时输出应该变成libssl.so.1.1 /usr/lib64/libssl.so.1.1程序也能正常跑起来了。4.2 方法二从腾讯云镜像站手动下载 RPM 包有些环境 yum 源配置已经改得乱七八糟或者内网环境无法访问公网这时候可以直接从腾讯云镜像站下载对应版本的 RPM 包再用rpm命令安装。CentOS7 基础镜像包的路径是https://mirrors.cloud.tencent.com/centos/7/os/x86_64/Packages/如果你想先在服务器上确认文件名可以用curl -fsSL https://mirrors.cloud.tencent.com/centos/7/os/x86_64/Packages/ | grep -o openssl11-libs-[^]*\.rpm | sort -V | tail -1这样会列出镜像目录里最新的openssl11-libs文件名。举例来说可能是openssl11-libs-1.1.1k-3.el7.x86_64.rpm。然后下载到本地wget https://mirrors.cloud.tencent.com/centos/7/os/x86_64/Packages/openssl11-libs-1.1.1k-3.el7.x86_64.rpm安装前先做校验确保包没有损坏rpm -K openssl11-libs-1.1.1k-3.el7.x86_64.rpm输出会包含digests signatures OK之类的信息确认无误后再安装。如果这个包还依赖其他东西直接rpm -ivh可能会报依赖缺失此时用 yum 的本地安装模式更省心yum localinstall -y openssl11-libs-1.1.1k-3.el7.x86_64.rpmyum localinstall会自动从已配置的源里补齐依赖这是我最推荐的手动安装方式。4.3 备份旧文件与安装后的验证如果系统里已经存在一个被改坏的libssl.so.1.1或者有人手动创建了一个错误的软链接安装前最好先备份并移除这个文件避免干扰。备份操作很简单mv /usr/lib64/libssl.so.1.1 /usr/lib64/libssl.so.1.1.bak 2/dev/null mv /usr/lib64/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1.bak 2/dev/null然后进行安装。安装完毕后不要忘记执行ldconfig它的作用是刷新动态链接库缓存让新增的库文件立刻被系统识别ldconfig验证环节我习惯做三步。第一步看缓存里有没有ldconfig -p | grep libssl第二步看程序能不能找到ldd /usr/bin/curl | grep libssl第三步直接跑之前报错的程序。如果程序还需要其他库比如libcrypto.so.1.1同样的方法也检查一下。三步都通过修复就算完成。5. 常见问题与排查技巧实录5.1 安装了 openssl11-libs 但程序还是报错这种情况我遇到不少最常见的原因是程序本身链接的是/usr/local/lib64/libssl.so.1.1而不是系统路径/usr/lib64/libssl.so.1.1。源码编译时如果不加参数很多程序会把 OpenSSL 头文件路径固定成/usr/local/ssl或/usr/local/openssl导致运行时要找的路径和系统默认加载路径不一致。排查时看ldd里的完整路径不要只看文件名。如果确实指向某个本地自定义目录可以先临时指定库路径验证export LD_LIBRARY_PATH/usr/local/openssl/lib:$LD_LIBRARY_PATH不过这只是应急措施不适合长期使用。正确做法是重新编译那个程序在 configure 或 cmake 阶段指定系统 OpenSSL 路径比如--with-opensslsystem让它链接到/usr/lib64下的库。5.2 yum 和 python 跟着一起崩了有几次我在环境极端损坏的情况下做实验发现连 yum 都跑不起来。原因在于 CentOS7 的 yum 用的是 Python 2.7而 Python 以及它的 ssl 模块依赖 OpenSSL 的库链一旦/usr/lib64/libssl.so.1.1缺失yum 也会跟着遭殃。这种时候不要试图去修 Python重点是把 OpenSSL 1.1 的库补齐。如果 yum 不行就用 rpm 直接安装本地包rpm -ivh openssl11-libs-1.1.1k-3.el7.x86_64.rpm --force如果连rpm都因为依赖问题装不上可以用rpm2cpio把 RPM 包解包手工把库文件拷贝到/usr/lib64下rpm2cpio openssl11-libs-1.1.1k-3.el7.x86_64.rpm | cpio -idmv cp usr/lib64/libssl.so.1.1 /usr/lib64/ cp usr/lib64/libcrypto.so.1.1 /usr/lib64/ ldconfig这算是最底层的兜底方法但必要时真的能救命。5.3 架构不匹配导致安装了也没用腾讯云镜像站里 CentOS7 的包分为x86_64和aarch64两套。如果你在 ARM 服务器上装了 x86_64 的 RPM虽然安装命令可能成功但运行程序时依然会报 not found因为动态库加载器根本不会加载错误架构的库。用file命令检查 RPM 包和当前系统的架构匹配情况file openssl11-libs-1.1.1k-3.el7.x86_64.rpm uname -m一个常见误区是“服务器配置看起来没变但上次是 x86这次是 ARM”。在 CentOS7 上跑 ARM 架构的设备并不少见比如某些国产芯片的云服务器、ARM 云主机所以下载前一定要做这步检查。5.4 SELinux 导致库加载异常还有一种不太容易想到的场景文件本身放在那里了ldconfig也刷新了ls -l能看到但程序就是加载失败。遇到这种诡异情况我会立刻检查 SELinux 是否拦截了库文件的读取或者文件的安全上下文不对。先看 SELinux 状态getenforce如果输出是Enforcing再看审计日志grep libssl /var/log/audit/audit.log | tail -20如果确认是 SELinux 拦截最简单的处理是恢复正确上下文restorecon -Rv /usr/lib64/libssl.so.1.1不建议直接把 SELinux 关掉除非你确定自己的环境允许。生产环境还是尽量保持安全策略开启只针对具体文件做恢复。6. 修复之后怎么避免再次踩雷6.1 不要在系统路径下随便堆放源码编译的 OpenSSL这个问题我反复强调过因为吃过太多次亏。源码编译的 OpenSSL 默认会往/usr/local下面装如果又手动把它复制到/usr/lib64很容易覆盖系统原有的符号链接导致 curl、wget、git 这些基础工具全部炸掉。如果你确实需要新版 OpenSSL 开发环境建议使用单独目录并通过环境变量隔离而不是动系统目录里的库文件。运行时库缺失时优先寻找 RPM 包来安装让包管理器替你维护文件清单和依赖关系这样后续升级、回滚都有据可查。6.2 维护一个本地 RPM 包缓存对经常要维护多台 CentOS7 的人来说我强烈建议在网络好的时候把常用依赖包提前下载到本地。可以用yumdownloader下载指定包和依赖yum install -y yum-utils yumdownloader --resolve openssl11-libs这样得到的 RPM 包可以放在内网文件服务器或本地目录里下次出现同样问题时直接安装省去到处寻找下载源的时间。特别是那些不允许连接公网的生产环境提前准备离线包几乎是必备工作。6.3 养成用 ldd、ldconfig、rpm -qf 定位问题的习惯修完这个报错后我建议你把这个处理思路沉淀成固定的排查套路。看到cannot open shared object file别慌按这个顺序走一遍ldd 程序文件 ldconfig -p | grep 缺失库名 rpm -qf /usr/lib64/libssl.so.1.1rpm -qf能告诉你某个文件属于哪个 RPM 包方便快速找到对应安装包名称。这套组合命令我用了很多年几乎能覆盖一切动态库缺失类故障。我个人在实际操作中的体会是CentOS7 上这类问题大多不是系统本身多脆弱而是我们容易在“升级依赖”这件事上用力过猛。与其去源码编译一个大版本不如先把对应的运行库补齐等确认业务依赖没有问题再考虑整体升级。最后再分享一个小细节修完库之后记得重启一下依赖该库的常驻服务比如 nginx、php-fpm、sshd否则旧进程可能仍然持有旧的内存映射看起来像没修复一样。
返回列表