简介:OpenSSL 1.1.1f 源代码包面向需要在 Linux、Unix 等平台自行编译部署安全通信组件的开发者与服务器管理员,用于解决 SSL/TLS 协议实现、加密算法调用及 X.509 证书管理等底层安全需求。包内为 OpenSSL 1.1.1f 完整源码,涵盖 RSA、AES、SHA 系列等加密算法实现,SSL 3.0 至 TLS 1.3 协议栈,证书生成与验证逻辑,以及 s_client、s_server、genpkey 等命令行工具和可供应用集成的库函数接口,便于按目标平台裁剪编译选项。压缩包约 9.34MB,文件总数与类型明细上游暂未提供。该版本在安全漏洞修复、加密性能、TLS 1.3 特性支持与 API 易用性上均有改进,并增强了跨系统与编译器的兼容性。资源已有 618 人学习下载,适合需要深入理解 OpenSSL 源码结构、定制编译或排查协议与证书问题的中高级开发者参考。
1. 从一次编译报错说起:为什么我还在装 openssl-1.1.1f
上周帮同事复现一个老项目的构建环境,./configure刚跑完就甩出一行error: OpenSSL 1.1.1 or later is required,系统里明明装着 3.x,可项目源码里写死了OPENSSL_VERSION_NUMBER < 0x10101000L的判断,编译直接卡死。这种场景太常见了:老代码、老中间件、老语言运行时,对 OpenSSL 的版本要求精确到小版本号,装新了不认,装旧了缺符号。openssl-1.1.1f 就是这样一个被大量存量项目钉死的版本,它属于 1.1.1 系列,支持 TLS 1.3,API 与 1.1.1 全系兼容,但又不像 3.x 那样改了 provider 架构。装不好会怎样?轻则libssl.so.1.1: cannot open shared object file,重则整个服务起不来还查不到日志。这篇笔记面向的是需要在一台机器上把 1.1.1f 从源码装起来、并且不污染系统自带库的开发者,下面按我实际操作的顺序走一遍。
2. 装前把环境列清楚:版本、依赖与安装路径的取舍
2.1 先确认系统自带的 OpenSSL 是什么状态
动手之前别急着解压,先摸清底细。系统自带的 OpenSSL 大概率被包管理器管着,ssh、curl、apt都依赖它,直接覆盖安装是血泪教训里最常见的一种翻车方式。我一般先跑三条命令看清楚:
openssl version -a which openssl ldconfig -p | grep libssl第一条输出当前openssl可执行文件的版本和编译参数,重点看OPENSSLDIR指向哪个目录;第二条确认命令来自/usr/bin还是/usr/local/bin;第三条列出动态链接器能找得到的libssl库。三条对完,你就知道系统库在/usr/lib/x86_64-linux-gnu还是/lib64,后面配置--prefix时心里有数。常见做法是把新版本装到/usr/local/openssl-1.1.1f这种独立目录,绝不碰系统路径,需要用的项目通过环境变量或编译参数指过去。
2.2 编译依赖和工具链的版本底线
openssl-1.1.1f 是 2020 年前后的源码,编译它需要一套能用的 C 工具链。最低要求是 gcc 4.8 以上、make、perl 5.x,另外zlib开发头文件建议装上,否则编译时会跳过 zlib 压缩支持。不同发行版的包名不一样,我按常见两类列一下:
# Debian / Ubuntu 系 sudo apt-get install -y build-essential perl zlib1g-dev # RHEL / CentOS 系 sudo yum install -y gcc gcc-c++ make perl zlib-develbuild-essential里包含 gcc、g++、make、libc 开发头文件,是编译的基础;zlib1g-dev或zlib-devel提供zlib.h,没有它./config阶段会提示zlib support disabled,虽然不致命,但后面某些依赖压缩的协议特性会缺。perl 必须装,因为 OpenSSL 的构建系统大量用 perl 脚本生成配置。装完用gcc --version和perl -v各确认一次,版本太老(比如 gcc 4.4)会在编译crypto/目录时报一堆语法错误,那时候再回头换工具链就晚了。
2.3 安装路径和共享库策略:装哪里、要不要 --openssldir
路径规划是这套环境里最值得花五分钟想清楚的事。--prefix决定可执行文件和库装到哪,--openssldir决定配置文件openssl.cnf和证书目录放哪。我一般让两者一致,避免以后找配置文件找半天:
| 参数 | 我常用的值 | 作用 |
|---|---|---|
--prefix | /usr/local/openssl-1.1.1f | 安装根目录,bin/lib/include 都在其下 |
--openssldir | /usr/local/openssl-1.1.1f/ssl | 配置文件和默认证书路径 |
shared | 启用 | 生成.so动态库,供其他程序链接 |
zlib | 启用 | 开启压缩支持 |
带版本号的目录好处是以后装 1.1.1w 或 3.x 可以并存,切换只改环境变量。shared一定要加,很多语言运行时(比如某些 Python 扩展、Node 原生模块)链接的是动态库,只编静态库会报cannot find -lssl。zlib加上省得后面补。这套组合我在多台机器上用过,没出过链接层面的玄学问题。
3. 从源码到安装:openssl-1.1.1f 的完整编译步骤
3.1 解压与目录检查
拿到openssl-1.1.1f.tar.gz后,先校验再解压。校验用 sha256,官方发布页会给对应哈希,手里没有的话至少确认压缩包完整:
tar -tzf openssl-1.1.1f.tar.gz > /dev/null && echo "archive ok" tar -xzf openssl-1.1.1f.tar.gz cd openssl-1.1.1f ls Configure config Makefile第一条tar -tzf只做列表测试,不落盘,能正常结束说明压缩包没坏;第二条真正解压;第三条确认目录里有Configure(大写,主配置脚本)、config(包装脚本)和Makefile(模板)。如果ls报No such file,多半是解压到了嵌套目录,cd进去再找。这一步看着琐碎,但我遇到过压缩包传输截断导致Configure缺失的情况,早发现比编译到一半报错强。
3.2 配置参数:./config 与 ./Configure 的区别
OpenSSL 有两个配置入口,./config是给普通用户用的包装脚本,会自动探测平台;./Configure是底层脚本,需要显式指定目标平台(如linux-x86_64)。日常安装用./config就够了,参数照下面这样给:
./config \ --prefix=/usr/local/openssl-1.1.1f \ --openssldir=/usr/local/openssl-1.1.1f/ssl \ shared zlib \ -Wl,-rpath,/usr/local/openssl-1.1.1f/lib逐项说:--prefix和--openssldir对应上一节的路径规划;shared生成动态库;zlib开压缩;最后那个-Wl,-rpath,...是传给链接器的,把新库目录写进二进制的运行时搜索路径,这样装完后openssl命令自己就能找到同目录的libssl.so.1.1,不用每次export LD_LIBRARY_PATH。这个 rpath 参数是我踩过坑之后固定加上的——不加的话,装完执行openssl version可能报error while loading shared libraries,因为系统链接器先找到了旧库。配置跑完会打印一段摘要,确认Shared library: True、zlib: True再往下走。
3.3 make 编译与安装:并行度与权限
配置通过后开始编译。源码树不小,单核跑要十几分钟,用-j按核数并行:
nproc make -j$(nproc)nproc先看核数,make -j$(nproc)按核数开并行。内存小的机器(比如 2G 的云主机)别开满,-j4就够,开太多会 OOM 把编译进程杀掉,报gcc: internal compiler error: Killed,那就是内存不够的信号。编译完成后安装需要写/usr/local,普通用户得加 sudo:
sudo make install安装过程会把bin/openssl、lib/libssl.so.1.1、lib/libcrypto.so.1.1、include/openssl/*.h铺到 prefix 下。装完先别急着改全局环境,下一章专门讲怎么让它生效而不影响系统。
4. 让新版本生效:环境变量、动态库与多版本共存
4.1 PATH 与 LD_LIBRARY_PATH 的正确写法
装完直接敲openssl version,大概率还是系统旧版本,因为/usr/local/openssl-1.1.1f/bin不在 PATH 里。我一般写一个独立的环境脚本,而不是直接改/etc/profile,方便回滚:
# /etc/profile.d/openssl-1.1.1f.sh export OPENSSL_HOME=/usr/local/openssl-1.1.1f export PATH=$OPENSSL_HOME/bin:$PATH export LD_LIBRARY_PATH=$OPENSSL_HOME/lib:$LD_LIBRARY_PATHOPENSSL_HOME是自定义变量,方便其他脚本引用;PATH把新 bin 放最前,保证openssl命令优先命中;LD_LIBRARY_PATH让运行时链接器优先找新库。注意LD_LIBRARY_PATH是双刃剑,全局设置可能影响其他依赖系统 OpenSSL 的程序,所以更稳妥的做法是只在需要它的 shell 里 source 这个脚本,或者依赖 3.2 节加的 rpath。写完source /etc/profile.d/openssl-1.1.1f.sh后,which openssl应该指向/usr/local/openssl-1.1.1f/bin/openssl。
4.2 ldconfig 配置与 soname 冲突处理
有些程序不读LD_LIBRARY_PATH,只认/etc/ld.so.conf里的路径。想让新库被全局动态链接器发现,可以加一个 conf 文件再刷新缓存:
echo "/usr/local/openssl-1.1.1f/lib" | sudo tee /etc/ld.so.conf.d/openssl-1.1.1f.conf sudo ldconfig ldconfig -p | grep libssltee把路径写进独立 conf 文件,ldconfig重建缓存,最后一条确认缓存里出现了libssl.so.1.1。这里有个关键点:1.1.1f 的 soname 是libssl.so.1.1,和系统自带的 1.1.1 系列同名,如果系统里已经有libssl.so.1.1,ldconfig的搜索结果会出现两条,谁生效取决于路径顺序。这就是为什么我更倾向用 rpath 或局部环境变量,而不是全局ldconfig——全局改容易让系统工具链跟着换库,属于典型的“装完能跑,重启就崩”的坑。
4.3 给编译型项目指定 OpenSSL 路径
真正要用这套库的往往是别的项目的编译过程。以常见的./configure项目为例,通过环境变量把编译和链接都指过去:
export CPPFLAGS="-I/usr/local/openssl-1.1.1f/include" export LDFLAGS="-L/usr/local/openssl-1.1.1f/lib -Wl,-rpath,/usr/local/openssl-1.1.1f/lib" ./configure --with-openssl=/usr/local/openssl-1.1.1fCPPFLAGS告诉预处理器去哪找openssl/ssl.h;LDFLAGS告诉链接器去哪找库,并再次写入 rpath;--with-openssl是很多项目自带的参数,直接指定前缀。三者一起给最保险,只给其中一个经常出现“头文件是新版、链接的是旧库”的错配,运行时报version 'OPENSSL_1_1_1' not found。如果项目用 CMake,对应的是-DOPENSSL_ROOT_DIR=/usr/local/openssl-1.1.1f,思路一样。
5. 避坑与排查:装 openssl-1.1.1f 最常见的五个翻车点
5.1 现象:装完 openssl version 还是旧版本
原因通常是 PATH 没生效或 shell 缓存了命令路径。先which -a openssl看所有命中项,再hash -r清掉 bash 的命令哈希表,然后重新 source 环境脚本。如果which已经指向新路径但版本仍旧,检查是不是别名(alias openssl=...)在作怪,type openssl能看出来。
5.2 现象:运行时报 libssl.so.1.1: cannot open shared object file
原因是动态链接器找不到新库,常见于只装了库没配 rpath、也没设LD_LIBRARY_PATH的场景。解决分两步:先用ldd $(which openssl) | grep ssl确认它到底在找哪个路径,再决定是补 rpath 重新编译,还是临时export LD_LIBRARY_PATH。长期方案我推荐重新./config加 rpath,比全局环境变量干净。
5.3 现象:make 阶段报 internal compiler error 或 Killed
这是内存不足,不是代码问题。make -j$(nproc)在低配机器上开并行会把内存吃穿。降到make -j2甚至单线程重跑即可,已经编译过的目标文件不会重编,不用make clean。如果反复出现,检查是不是 swap 没开。
5.4 现象:其他系统命令突然报 OpenSSL 符号错误
典型原因是全局ldconfig或LD_LIBRARY_PATH把系统工具的库换掉了。比如ssh启动报symbol lookup error。救法是删掉/etc/ld.so.conf.d/openssl-1.1.1f.conf再sudo ldconfig,并清理全局LD_LIBRARY_PATH,改回按项目局部指定。这也是我坚持独立 prefix 加 rpath 的原因——后悔药不好吃。
5.5 现象:configure 提示 zlib support disabled
缺zlib.h,按 2.2 节装开发包即可。装完要重新跑./config,因为 zlib 探测结果在配置阶段就定死了,只重跑make不会补上。确认配置摘要里zlib: True再编译。
6. 装完怎么验证:三条命令确认这套环境真的能用
装完不验证等于没装。我固定跑三步,从命令、库、编译链接三个层面确认。第一步看版本和编译参数:
/usr/local/openssl-1.1.1f/bin/openssl version -a输出里OpenSSL 1.1.1f开头,built on后面的日期和compiler信息对得上,OPENSSLDIR指向/usr/local/openssl-1.1.1f/ssl,说明 prefix 和 openssldir 都生效了。如果OPENSSLDIR还是系统路径,说明配置阶段参数没吃进去,得回 3.2 节重来。
第二步验证动态库能被正确解析:
ldd /usr/local/openssl-1.1.1f/bin/openssl | grep -E 'ssl|crypto'期望看到libssl.so.1.1 => /usr/local/openssl-1.1.1f/lib/libssl.so.1.1,箭头右边必须是新目录。如果指向/usr/lib下的旧库,说明 rpath 没写进去,或者被LD_LIBRARY_PATH里的旧路径抢先了。
第三步做一次真实的编译链接测试,这是最能暴露问题的验证:
cat > /tmp/t.c <<'EOF' #include <openssl/opensslv.h> #include <stdio.h> int main(void) { printf("%s\n", OPENSSL_VERSION_TEXT); return 0; } EOF gcc /tmp/t.c -I/usr/local/openssl-1.1.1f/include \ -L/usr/local/openssl-1.1.1f/lib -lssl -lcrypto \ -Wl,-rpath,/usr/local/openssl-1.1.1f/lib -o /tmp/t /tmp/t这段小程序只打印版本宏,但走完了预处理、编译、链接、运行全链路。输出OpenSSL 1.1.1f就说明头文件和库版本一致、链接器找得到、运行时也加载得到。三步全过,这套环境才算真正落地。
从那以后我每次装 OpenSSL 都强制走一遍这三步验证,尤其是第三步的编译测试——它比openssl version更能说明问题,因为版本命令只证明可执行文件能跑,编译测试才证明这套库能被别的项目用起来。希望帮到你。
本文还有配套的精品资源,点击获取