首页 / 资讯中心 / 文章详情

OpenSSL 1.1.1 离线安装包制作与内网部署实战

OpenSSL 1.1.1 离线安装包制作与内网部署实战 ★ FEATURED ARTICLE
简介本资源为 openssl 1.1.1 离线安装包面向需要在无外网或受限网络环境中部署 OpenSSL 的运维、后端开发及安全测试人员解决源码编译安装时依赖下载困难、版本不匹配等问题。压缩包共约 2000 个文件整体 11.37MB以 C 源码944 个与头文件269 个为核心辅以大量 POD 文档、Perl 脚本、配置模板及少量 PEM 证书样例、汇编与测试用例覆盖库实现、文档说明与构建脚本等模块。解压后进入目录执行 ./config --prefix/usr/local/openssl1.1 --openssldir/usr/local/openssl1.1/ssl再 make -j$(nproc) 与 sudo make install 即可完成编译安装。目前已有 957 人学习下载适合希望掌握源码编译流程、自定义安装路径并排查依赖问题的读者参考目录结构完整便于按模块查阅与二次构建。1. openssl 1.1.1 离线安装包内网机器上那套绕不开的编译活机房里有台 CentOS 7 的构建机网卡是通的但只放行了内网 yum 源yum install openssl-devel拉下来的还是 1.0.2k。业务侧编译某个中间件时直接报undefined reference to OPENSSL_init_ssl因为代码里用了 1.1.1 才引入的初始化接口。这时候你手里能用的只有一台能上网的笔记本和一个 U 盘剩下的活就是自己攒一个 openssl 1.1.1 离线安装包拷进去编译、安装、让动态库被正确找到。这篇笔记讲的就是这条链路源码包怎么选、依赖怎么备齐、configure 参数怎么定、装完为什么openssl version还是老版本、以及升级后哪些东西会连带翻车。适合经常在内网、隔离网、信创环境里做基础库替换的运维和构建工程师也适合第一次被libssl.so.1.1: cannot open shared object file卡住的开发。2. 离线包到底装什么源码、依赖和目录规划2.1 为什么是源码编译而不是找现成 rpm很多人第一反应是去搜「openssl 1.1.1 rpm 离线包」找到一堆第三方打包的.rpm拷进去rpm -ivh一装看着挺省事。但这条路在真实环境里翻车概率很高。第一第三方 rpm 的编译参数你不可控--prefix可能是/usr/local也可能是/opt装完openssl version指向哪里全看打包者心情。第二rpm 的依赖链是写死的目标机器缺libcom_err或者 glibc 版本对不上rpm -ivh直接甩一堆Failed dependencies你还得再去找依赖的离线包越滚越大。第三也是最要命的很多业务是静态链接或者指定路径链接 openssl 的rpm 装到系统默认路径反而和业务预期冲突。源码编译的好处是路径、参数、编译选项全部自己说了算产出的东西是一个自包含的目录拷到哪台机器都能用不污染系统包管理。代价是要在目标机器上装编译工具链或者在一台同架构的机器上编好再拷二进制过去。我一般选后者找一台和目标机 glibc 版本一致的编译机编完打包整个--prefix目录目标机只需要解压和配环境变量连 gcc 都不用装。这里有个前提要确认清楚目标机的 CPU 架构和 glibc 版本。uname -m看架构ldd --version看 glibc。openssl 1.1.1 对 glibc 的要求不高2.17 以上基本都能跑CentOS 7 自带 2.17没问题。但如果编译机是 glibc 2.28 编出来的拷到 2.17 的机器上大概率报GLIBC_2.28 not found这就是血泪经验——编译机和目标机的 glibc 版本必须对齐宁可找台老机器编。2.2 离线包该包含哪些文件一个能自洽的 openssl 1.1.1 离线安装包我一般按这个清单准备文件/目录作用是否必需openssl-1.1.1w.tar.gz源码包必需perlconfigure 脚本依赖 perl目标机无 perl 时必需make / gcc编译工具链目标机编译时必需zlib-devel启用 zlib 压缩支持可选但建议带编译产物目录已编译好的 prefix 目录免编译方案必需install.sh安装脚本建议源码包版本我一般锁 1.1.1w这是 1.1.1 系列的最后一个版本安全补丁最全。不要去下 1.1.1a 这种早期版本CVE 一堆。下载渠道就是 openssl 官网的 source 页面或者用wget直接拉https://www.openssl.org/source/openssl-1.1.1w.tar.gz。注意官网现在主推 3.x1.1.1 系列已经进入维护末期但很多老业务还锁在 1.1.1 的 ABI 上不能随便升 3.x因为 3.x 的 API 有破坏性变更。提示1.1.1 系列官方支持已经结束新项目建议直接上 3.x。但如果你的业务依赖 1.1.1 的 ABI升级前务必确认所有动态链接的库都兼容。2.3 目录规划prefix 选哪里--prefix的选择直接决定了后面环境变量怎么配、动态库怎么找。三种常见方案一是装到/usr/local/openssl-1.1.1独立目录不碰系统自带的/usr/bin/openssl。好处是干净坏处是业务编译时要显式指定-I和-L动态库运行时还要配LD_LIBRARY_PATH或者写进/etc/ld.so.conf.d/。二是直接覆盖/usr--prefix/usr装完系统openssl命令就变成 1.1.1 了。看着省事但风险极大——系统里其他依赖 1.0.2 的程序可能直接崩尤其是 ssh、curl 这些基础组件。除非你非常清楚系统里所有 openssl 的消费者否则别这么干。三是装到/opt/openssl然后通过 alternatives 或者软链接切换。这是比较折中的做法但 alternatives 管理的是命令动态库的查找还是得靠 ldconfig。我一般选第一种prefix 用/usr/local/openssl-1.1.1然后单独写一个openssl.sh环境脚本需要用的业务source一下就行互不干扰。3. 从源码到可用编译参数与打包步骤3.1 编译机上的完整操作流程假设编译机是 CentOS 7已经装了 gcc、make、perl。先把源码包传上去解压、配置、编译、安装一条龙# 解压源码 tar -zxvf openssl-1.1.1w.tar.gz cd openssl-1.1.1w # 配置指定 prefix启用共享库启用 zlib ./config \ --prefix/usr/local/openssl-1.1.1 \ --openssldir/usr/local/openssl-1.1.1/ssl \ shared \ zlib \ -fPIC # 编译-j 后面跟 CPU 核数加快速度 make -j$(nproc) # 安装到 prefix 目录 make install # 验证编译产物 /usr/local/openssl-1.1.1/bin/openssl version--prefix指定安装根目录--openssldir指定配置文件目录这两个最好分开写清楚不然后面找openssl.cnf会找半天。shared是关键不加这个只生成静态库libssl.a和libcrypto.a业务如果动态链接就找不到.so。zlib启用压缩支持TLS 层的数据压缩会用到虽然现在压缩在 TLS 里不推荐开有 CRIME 攻击但库层面支持着没坏处。-fPIC是位置无关代码生成共享库必须加不加在某些平台上链接会报错。make -j$(nproc)里的$(nproc)是当前 CPU 核数编译 openssl 大概需要几分钟核多的机器能快不少。make install会把bin、lib、include、ssl几个目录铺到 prefix 下。编译完先别急着打包验证一下产物# 看动态库是否生成 ls -l /usr/local/openssl-1.1.1/lib/ # 应该能看到 libssl.so.1.1 和 libcrypto.so.1.1 # 看版本 /usr/local/openssl-1.1.1/bin/openssl version -a # 输出里 OpenSSL 1.1.1w 和 built on 时间要对如果lib目录下只有.a没有.so说明shared没生效回去检查 config 那步是不是漏了。如果openssl version报error while loading shared libraries说明编译机自己都没找到库用ldd看一下依赖路径。3.2 打包成离线安装包编译验证通过后把整个 prefix 目录打包再附上安装脚本# 打包 prefix 目录 cd /usr/local tar -czvf openssl-1.1.1-offline.tar.gz openssl-1.1.1/ # 查看包大小一般在 10MB 以内 ls -lh openssl-1.1.1-offline.tar.gz安装脚本install.sh负责在目标机上解压、配环境、刷新动态库缓存#!/bin/bash set -e PREFIX/usr/local/openssl-1.1.1 PKGopenssl-1.1.1-offline.tar.gz # 解压到 /usr/local tar -xzvf $PKG -C /usr/local/ # 写 ld.so.conf让系统能找到动态库 echo $PREFIX/lib /etc/ld.so.conf.d/openssl-1.1.1.conf ldconfig # 配环境变量追加到 /etc/profile.d/ cat /etc/profile.d/openssl-1.1.1.sh EOF export PATH$PREFIX/bin:\$PATH export LD_LIBRARY_PATH$PREFIX/lib:\$LD_LIBRARY_PATH EOF chmod x /etc/profile.d/openssl-1.1.1.sh echo install done, run: source /etc/profile.d/openssl-1.1.1.shset -e让脚本遇到错误立即退出避免半装状态。ld.so.conf.d那个文件是给系统动态链接器看的ldconfig刷新缓存后所有程序运行时都能找到libssl.so.1.1。/etc/profile.d/下的脚本会在登录时自动 sourcePATH和LD_LIBRARY_PATH都配好。注意LD_LIBRARY_PATH是双刃剑全局设置可能影响其他程序如果只想给特定业务用就别写进 profile.d让业务自己 source。注意ldconfig之后如果系统里原本有 1.0.2 的库两个版本的libssl.so会共存但 soname 不同libssl.so.10vslibssl.so.1.1不会直接冲突。真正冲突的是头文件和命令所以 PATH 的顺序很重要。3.3 目标机上的安装与验证把openssl-1.1.1-offline.tar.gz和install.sh拷到目标机执行chmod x install.sh ./install.sh source /etc/profile.d/openssl-1.1.1.sh # 验证 which openssl # 应该输出 /usr/local/openssl-1.1.1/bin/openssl openssl version # 应该输出 OpenSSL 1.1.1w # 验证动态库能被找到 ldd $(which openssl) | grep ssl # 应该指向 /usr/local/openssl-1.1.1/lib/libssl.so.1.1which openssl确认 PATH 生效openssl version确认版本对ldd确认动态库路径对。这三步都过了基础安装就算成了。如果which还是/usr/bin/openssl说明 PATH 没生效检查 profile.d 脚本有没有执行权限或者当前 shell 是不是没重新登录。4. 装完为什么还是老版本路径、缓存与链接的排查4.1 openssl version 显示旧版本的四种原因这是最高频的翻车现场明明装完了openssl version还是 1.0.2k。按概率排原因有四种。第一种PATH 顺序问题。系统/usr/bin在 PATH 里排在/usr/local/openssl-1.1.1/bin前面shell 先找到旧的。echo $PATH看一眼顺序把新路径往前挪或者直接用绝对路径/usr/local/openssl-1.1.1/bin/openssl version验证。第二种hash 缓存。bash 会缓存命令路径hash -r清一下再试。这个坑很隐蔽尤其是你在同一个 shell 里先跑过旧命令再改 PATHbash 记着旧路径不放。第三种profile.d 脚本没被执行。/etc/profile.d/只在登录 shell 里 source如果你是用su切用户或者非交互式 ssh 执行命令可能不加载。手动source /etc/profile.d/openssl-1.1.1.sh一下。第四种装是装了但装错了地方。--prefix写错或者make install时权限不够装到了别处。find / -name openssl -type f 2/dev/null全局搜一下看新版本到底在哪。4.2 动态库找不到的排查链路业务启动时报error while loading shared libraries: libssl.so.1.1: cannot open shared object file说明运行时链接器找不到库。排查顺序先ldd /path/to/your/binary | grep ssl看它期望的库路径是什么。如果显示not found说明链接器搜索路径里没有。链接器的搜索路径由/etc/ld.so.conf及其include的conf.d目录决定加上LD_LIBRARY_PATH环境变量。ldconfig -p | grep libssl看当前缓存里注册了哪些版本的 libssl。如果ldconfig -p里没有 1.1说明/etc/ld.so.conf.d/openssl-1.1.1.conf没写或者没跑ldconfig。补上再跑一次。如果ldconfig -p里有但业务还是找不到检查业务的启动脚本是不是清空了LD_LIBRARY_PATH或者用了setuid导致环境变量被忽略。还有一种情况是业务编译时链接的是静态库但运行时又去找动态库这种混合链接的坑最难查。readelf -d /path/to/binary | grep NEEDED看它到底依赖哪些 so比ldd更准。4.3 升级后 ssh、curl 挂了的应急处理如果你手贱把 openssl 装到了/usr覆盖了系统库重启后 ssh 连不上、curl 报错别慌。系统里通常还留着旧版本的库文件只是软链接被改了。ls -l /usr/lib64/libssl.so*看软链接指向把指向 1.1 的链接改回 1.0.2 的实体文件。如果实体文件也被覆盖了那就得从同版本系统的另一台机器拷libssl.so.10和libcrypto.so.10回来或者进 rescue 模式用安装盘恢复。预防这个问题的办法很简单永远不要--prefix/usr永远装独立目录。系统自带的 openssl 就让它待着业务要用新版本就显式指定路径。这是最省心的策略没有之一。5. 避坑清单五个真实踩过的坑坑一编译机 glibc 版本高于目标机拷过去报GLIBC_2.28 not found。现象是二进制直接起不来ldd报版本不匹配。原因是 openssl 编译时链接了编译机的 glibc 符号。解决办法是编译机和目标机 glibc 版本对齐或者用 Docker 起一个和目标机同版本的基础镜像来编译。我一般用centos:7镜像编译产出的二进制在 CentOS 7 上跑没问题。坑二make install后openssl version正常但业务编译时#include openssl/ssl.h找不到头文件。现象是 gcc 报openssl/ssl.h: No such file or directory。原因是头文件装在 prefix 的include下但 gcc 默认不搜这个路径。解决办法是编译业务时加-I/usr/local/openssl-1.1.1/include链接时加-L/usr/local/openssl-1.1.1/lib -lssl -lcrypto。如果业务用 pkg-config把 prefix 下的lib/pkgconfig加进PKG_CONFIG_PATH。坑三ldconfig跑了但ldconfig -p里看不到新库。现象是配置文件写了命令也跑了就是没注册。原因是/etc/ld.so.conf.d/下的文件名必须以.conf结尾写成openssl-1.1.1不带后缀会被忽略。另外文件内容必须是目录路径不能写具体的.so文件路径。改成echo /usr/local/openssl-1.1.1/lib /etc/ld.so.conf.d/openssl-1.1.1.conf再ldconfig。坑四业务用 Python 的ssl模块升级后import ssl报错。现象是 Python 启动就崩报ImportError: libssl.so.1.1: cannot open shared object file。原因是 Python 的_ssl扩展模块编译时链接了特定版本的 openssl升级后 soname 对不上。解决办法是重新编译 Python或者用LD_LIBRARY_PATH指向新库。但更稳妥的做法是别动系统 Python 依赖的 openssl给业务单独配虚拟环境。坑五离线包拷到目标机解压后权限全丢脚本执行报Permission denied。现象是install.sh跑不了或者解压出来的bin/openssl没有执行权限。原因是 tar 打包时没保留权限或者 U 盘文件系统FAT32不支持 Unix 权限位。解决办法是打包时用tar -czpvfp保留权限拷贝时用scp或者打包成tar再传别直接拖 U 盘。如果已经丢了权限chmod x补一下。6. 让离线包更省心版本锁定与自动化校验装完能跑只是及格线真正省心的是让这套离线包可复现、可校验、可回滚。我现在的习惯是在打包阶段就把版本信息和校验和固化下来目标机安装前先验一遍避免拷错包或者包损坏。具体做法是在 prefix 目录下放一个BUILD_INFO文件记录编译时间、编译机、glibc 版本、configure 参数cat /usr/local/openssl-1.1.1/BUILD_INFO EOF version1.1.1w build_time$(date -u %Y-%m-%dT%H:%M:%SZ) build_host$(hostname) glibc$(ldd --version | head -1 | awk {print $NF}) configure--prefix/usr/local/openssl-1.1.1 --openssldir/usr/local/openssl-1.1.1/ssl shared zlib -fPIC EOF然后打包时生成 SHA256 校验和安装脚本里先校验再解压# 打包时生成校验和 sha256sum openssl-1.1.1-offline.tar.gz openssl-1.1.1-offline.tar.gz.sha256 # 安装脚本里校验 sha256sum -c openssl-1.1.1-offline.tar.gz.sha256 || { echo checksum mismatch, abort exit 1 }sha256sum -c会读校验和文件并比对不匹配就退出。这一步能挡住传输损坏和拷错版本的问题尤其是 U 盘拷贝场景文件损坏概率不低。回滚方案也要提前想好。因为我们是独立 prefix 安装回滚其实就是把/etc/ld.so.conf.d/openssl-1.1.1.conf删掉、ldconfig刷新、把 profile.d 脚本移走业务就回到系统自带的 openssl 了。prefix 目录留着不删下次要用再配回来。这种非侵入式安装的最大好处就是回滚成本极低不用重装系统。最后一个技巧是关于多版本共存的。如果一台机器上既要跑依赖 1.1.1 的新业务又要跑依赖 1.0.2 的老业务别去折腾全局 PATH让每个业务在自己的启动脚本里显式指定# 新业务启动脚本 export LD_LIBRARY_PATH/usr/local/openssl-1.1.1/lib:$LD_LIBRARY_PATH export PATH/usr/local/openssl-1.1.1/bin:$PATH exec /path/to/new-service # 老业务启动脚本保持原样不 source 任何 openssl 环境 exec /path/to/old-service这样两个业务各用各的库互不干扰。全局环境保持系统默认谁也别动。这套做法我在好几个隔离网环境里用了几年没再出过因为 openssl 版本导致的连环故障。编译参数和目录规划一次做对后面就是复制粘贴的活。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站