在CentOS7.9上 编译安装openssl-3.3.1+编译安装Nginx1.26.2
编译安装注意事项
CentOS 7.9 系统默认安装的 OpenSSL 版本是 1.0.2k-fips ,这个1.0.2 k版本也成为了最后的7.9官方版本
[root@CentOS7.9 ~]# openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017
知识点一:openssl的重要性和强相关性
openssl
在 Linux 系统中扮演着至关重要的角色,尤其是在网络安全方面。许多服务和应用程序都依赖于 openssl
提供的加密功能,包括但不限于 web 服务器(如 Apache 和 Nginx)、数据库服务器(如 MySQL 和 PostgreSQL)、邮件服务器、VPN等。
以下列表程序(包括但不限于这些),会在安装程序时,依赖Openssl,应该都会带各种版本的openssl,请注意识别:
Nginx:
Nginx 用于提供 HTTPS 服务时,会依赖 OpenSSL 来处理 SSL/TLS 加密。
OpenSSH:
OpenSSH 用于提供安全的远程登录服务时,会依赖 OpenSSL 来处理 SSH 加密。
Apache HTTP Server:
Apache HTTP Server 用于提供 HTTPS 服务时,也会依赖 OpenSSL 来处理 SSL/TLS 加密。
MySQL/MariaDB:
MySQL 和 MariaDB 数据库管理系统可以使用 SSL 加密连接客户端与服务器之间的通信,这通常依赖于 OpenSSL。
PostgreSQL:
PostgreSQL 数据库管理系统同样可以使用 SSL 加密连接客户端与服务器之间的通信,这通常依赖于 OpenSSL。
Dovecot:
Dovecot 邮件服务器用于提供 IMAP/POP3 加密服务时,会依赖 OpenSSL。
Exim:
Exim 邮件传输代理 (MTA) 用于发送和接收邮件时,如果启用了 TLS/SSL 加密,则会依赖 OpenSSL。
OpenVPN:
OpenVPN 用于提供基于 SSL 的虚拟专用网络 (VPN) 服务时,会依赖 OpenSSL。
LibreSSL:
LibreSSL 是 OpenSSL 的一个替代品,某些服务和应用程序可能使用 LibreSSL 替代 OpenSSL。
GnuTLS:
GnuTLS 是一个替代 OpenSSL 的库,用于处理 TLS/SSL 加密,某些服务和应用程序可能使用 GnuTLS。
你如果想更新编译新的openssl版本,老的这个1.0.2版本是不能卸载的,因为生产中可能还有其他的服务依赖,比如默认安装的ssh服务。一旦你删除了旧版本,可能就会引起其他程序的异常。因为你必须确保所有依赖 OpenSSL 的应用都正确地指向了新版本的库。
所以,我们应该遵循的第一个原则就是:让新的openssl版本和老的openssl版本共存。
知识点二:源代码编译安装路径
从源代码编译安装大多数软件时,如果不指定 --prefix
参数,这些软件通常会被安装到 /usr/local
目录下。具体来说:
- 库文件 会被安装到
/usr/local/lib
。 - 头文件 会被安装到
/usr/local/include
。 - 可执行文件 会被安装到
/usr/local/bin
。
知识点三:yum安装路径
系统自带的软件 或使用 yum
或者通过其他包管理工具安装软件时,这些软件通常会被安装到 /usr
目录下。具体来说:
- 库文件 会被安装到
/usr/lib64
或/usr/lib
(32 位系统)。 - 头文件 会被安装到
/usr/include
。 - 可执行文件 会被安装到
/usr/bin
或/usr/sbin
。- /usr/bin: 这里存放的是普通用户经常使用的命令,例如文本编辑器(如
vi
)、文件处理工具(如ls
和cp
)等。 - /usr/sbin: 这里存放的是系统管理员权限(如root)或需要特殊权限(需要
sudo
执行的命令)才能运行的命令,例如网络配置工具(如ifconfig
)或其他系统管理工具。
- /usr/bin: 这里存放的是普通用户经常使用的命令,例如文本编辑器(如
对于 OpenSSL 来说,它的可执行文件 openssl
通常会被安装到 /usr/bin
,因为它是一个用户级的命令,不需要特殊的权限来运行。
以openssl 来举例,CentOS 7.9 系统默认安装的 OpenSSL 版本是 1.0.2k-fips
通过命令来查看这个系统自带的版本到底放在哪里
[root@CentOS7 lib64]# which openssl
/usr/bin/openssl
[root@CentOS7 lib64]# whereis openssl
openssl: /usr/bin/openssl /usr/lib64/openssl /usr/include/openssl /usr/share/man/man1/openssl.1ssl.gz
-
which openssl
:- 输出结果
/usr/bin/openssl
表示openssl
命令的可执行文件位于/usr/bin
目录下。这是系统默认查找命令的位置之一。
- 输出结果
-
whereis openssl
:- 输出结果表明 OpenSSL 的各个组成部分在系统中的位置:
/usr/bin/openssl
: 这是openssl
命令的可执行文件所在位置。/usr/lib64/openssl
: 这个目录通常包含 OpenSSL 的库文件。您之前看到的libcrypto.so
和libssl.so
等文件就位于这里。/usr/include/openssl
: 这个目录包含 OpenSSL 的头文件,用于编译时链接 OpenSSL 的功能。/usr/share/man/man1/openssl.1ssl.gz
: 这是一个压缩的手册页文件,提供了关于openssl
命令的帮助文档。
- 输出结果表明 OpenSSL 的各个组成部分在系统中的位置:
这些信息表明您的系统默认的 OpenSSL 安装在 /usr
目录下,并且相关的库文件、头文件和可执行文件都位于标准的位置上。
知识点四:环境变量冲突
如果要实现共存:你可能面临的问题:
-
$PATH
包含/usr/local/bin
:$PATH
是一个环境变量,用于告诉系统在查找可执行文件时应搜索哪些目录。通常在/etc/profile
文件中添加$PATH
的值。- 如果
/usr/local/bin
被包含在$PATH
中,那么当您输入一个命令时,系统会首先在这个目录中查找该命令对应的可执行文件。 - 这意味着如果您的系统中有多个版本的相同命令,系统可能会优先使用
/usr/local/bin
中的命令,而不是/usr/bin
或其他位置的命令。
-
LD_LIBRARY_PATH
包含/usr/local/lib
:LD_LIBRARY_PATH
是一个环境变量,用于告诉系统在启动程序时除了默认的库文件搜索路径之外还应查找哪些路径上的库文件。通常在/etc/environment
文件中添加LD_LIBRARY_PATH
的值 或 在用户的.bashrc
或.bash_profile
文件中设置LD_LIBRARY_PATH
- 如果
/usr/local/lib
被包含在LD_LIBRARY_PATH
中,那么当您启动一个程序时,系统会在这个目录中查找所需的库文件。 - 这意味着如果您的系统中有多个版本的库文件,系统可能会优先加载
/usr/local/lib
中的库文件,而不是/usr/lib64
或其他位置的库文件。
总结:为了让旧版本和新版本的 OpenSSL 共存,我们应该采取以下策略来实现。
1. 使用独立的安装目录
- 安装新版本的 OpenSSL 到一个特定的目录,例如
/opt/openssl-new
。 - 确保该目录下的
bin
和lib
子目录包含新版本的可执行文件和库文件。
2. 修改应用程序的路径
- 对于需要使用新版本 OpenSSL 的应用程序,修改它们的环境变量或配置文件,使其指向新的 OpenSSL 安装位置。
- 您可以通过设置
LD_LIBRARY_PATH
或者在应用程序的启动脚本中加入相应的路径来实现这一点。
3. 使用符号链接
- 创建符号链接从默认的 OpenSSL 目录到新版本的目录。
- 例如,创建
/usr/local/bin/openssl-new
指向/opt/openssl-new/bin/openssl
。
4. 编译时指定 OpenSSL 路径
- 如果您正在编译一个新的应用程序,确保在编译时使用正确的 OpenSSL 版本路径。
- 使用
--with-openssl
或--with-openssl-dir
参数指定 OpenSSL 的安装路径。
华丽的分割线
安装OpenSSL-3.3.1步骤
下载最新版本openssl-3.3.1 官网地址:Downloads | Library (openssl-library.org)
传输到/opt目录下,解压
[root@CentOS7 opt]# ls
openssl-3.3.1.tar.gz
[root@CentOS7 opt]# tar -xzf openssl-3.3.1.tar.gz
[root@CentOS7 opt]# ls
openssl-3.3.1 openssl-3.3.1.tar.gz
openssl version 命令查看默认版本
[root@CentOS7 opt]# openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017
[root@CentOS7 opt]#
安装依赖项
yum install -y make gcc autoconf automake libtool pkg-config zlib-devel perl bison flex openssl-devel perl-IPC-Cmd Perl-CPAN
必要的依赖项
-
基础构建工具:
make
:用于构建 OpenSSL。gcc
:C 和 C++ 编译器。autoconf
:用于生成配置脚本。automake
:用于生成 Makefile 文件。
-
库和工具:
libtool
:用于创建跨平台的库。pkg-config
:用于管理库的编译和链接选项。zlib
:用于数据压缩。
-
开发包:
perl
:用于某些脚本。bison
和flex
:用于解析和词法分析。openssl-devel
:用于提供开发头文件。
如果有问题,可以试这个备用的:
yum install -y gcc gcc-c++ zlib-devel libtool autoconf automake perl perl-IPC-Cmd perl-Data-Dumper perl-CPAN
配置安装选项:
cd 进入到解压缩目录
[root@CentOS7 ~ ]# cd /opt/openssl-3.3.1/
运行config脚本来配置安装选项,设置安装目录为/opt/openssl-3.3.1。这里主要是为了指定编译路径和选择
这里给出一个推荐的 ./config
命令,我们需要考虑您的具体需求和环境。正在使用 CentOS 7.9,并尝试编译安装 OpenSSL 3.3.1 版本。它包括了一些常用的选项:
./config --prefix=/opt/OpenSSL-3.3.1 \
shared \
zlib-dynamic \
enable-ec_nistp_64_gcc_128 \
enable-tls1_3 \
no-ssl3 \
no-weak-ssl-ciphers \
一些配置选项的解释:
--prefix=/opt/OpenSSL-3.3.1
: 设置 OpenSSL 的安装路径。shared
: 编译为共享库。zlib-dynamic
: 使用动态链接的 zlib 库。enable-ec_nistp_64_gcc_128
: 启用特定的椭圆曲线密码算法支持。enable-tls1_3
: 启用 TLS 1.3 协议支持。no-ssl3
: 禁用 SSLv3 协议,因为 SSLv3 存在安全漏洞。no-weak-ssl-ciphers
: 禁用弱加密套件。no-comp
: 禁用数据压缩功能,这通常不需要,除非您有特定的需求。no-zlib
: 禁用内置的 zlib 库支持,因为我们已经在zlib-dynamic
中指定了使用系统的 zlib。no-threads
: 禁用线程支持,如果您的应用程序不需要多线程,可以禁用以减少依赖。no-asm
: 禁用汇编优化,这可能会简化跨平台的编译过程。
请注意,如果你的应用程序需要特定的功能或依赖项,你可能需要调整上述命令中的选项。例如,如果您确实需要 zlib 支持并且不想使用系统 zlib,您可以移除 no-zlib
选项。
在执行 ./config
之前,请确保您的系统满足 OpenSSL 的编译要求,比如必要的开发工具和库文件。您还可以添加 --openssldir
选项来指定 OpenSSL 配置文件的存放位置。
编译:编译可以分为多线程编译或单线程编译,可以自由选择
注意事项
- 在使用多线程编译时,请确保您的系统资源足够,尤其是内存,因为多线程编译会占用更多的内存。
- 对于一些复杂的项目,过多的并行作业可能会导致编译失败或性能下降。在这种情况下,可以适当减少
-j
的值。 - 如果您不确定应该使用多少个线程,可以先尝试使用
make -j2
或make -j4
,然后根据编译速度和系统性能进行调整。
综上所述,如果您想要加快编译速度并且系统有足够的资源,推荐使用多线程编译。
多线程编译
使用 -j
选项可以让 make
并发执行多个编译任务,从而利用多核处理器的优势来加速编译过程。例如,如果您有 4 个 CPU 核心,可以使用以下命令:
make -j4
或者,为了充分利用所有可用的核心,可以使用 nproc
命令来自动确定核心数:
make -j$(nproc)
单线程编译
如果不使用 -j
选项,默认情况下 make
将采用单线程方式执行编译任务。这对于较旧的系统或特定的编译环境可能是必要的,或者在调试时需要更详细的输出信息。
make
安装:
make install
安装完成后,你会遇到2种分支选择
选择1-更新环境变量:(采用这种方法,就要把所有依赖都ssl都重新编译安装一遍,以确保所有的程序都可以正常调用新的openssl 3.3.1版本)
安装了 OpenSSL 到非标准路径(/opt/OpenSSL-3.3.1
),需要更新环境变量以确保系统能够找到 OpenSSL 的二进制文件和库文件。
# 如果您希望 OpenSSL 3.3.1 的可执行文件(如 openssl)优先于系统默认的 OpenSSL 1.0.2k-fips 版本被使用,您应该把它添加到 PATH 环境变量的前面
echo 'export PATH=/opt/OpenSSL-3.3.1/bin:$PATH' >> /etc/profile
echo 'export LD_LIBRARY_PATH=/opt/OpenSSL-3.3.1/lib64:$LD_LIBRARY_PATH' >> /etc/profile
source /etc/profile
# 如果是32位系统,应该把lib64改成lib
echo 'export LD_LIBRARY_PATH=/opt/OpenSSL-3.3.1/lib:$LD_LIBRARY_PATH' >> /etc/profile
对于下面这种方法,我持保留观点,个人觉得没有实际作用(可能是我不懂)
# 如果您希望保留系统默认的 OpenSSL 1.0.2k-fips 版本作为优先使用的版本,并且仅在需要时使用 OpenSSL 3.3.1 的可执行文件,您应该把它添加到 PATH 环境变量的后面
echo 'export PATH=$PATH:/opt/OpenSSL-3.3.1/bin' >> /etc/profile
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/OpenSSL-3.3.1/lib64' >> /etc/profile
source /etc/profile
# 如果是32位系统,应该把lib64改成lib
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/OpenSSL-3.3.1/lib' >> /etc/profile
验证安装:
使用 openssl version -a
命令来验证 OpenSSL 是否已成功安装,并确认版本信息。
openssl version -a
选择2-不更新环境变量(选择这种的话,你需要在编译安装其他软件时,指定新的 ssl 3.3.1的绝对路径,以实现你编译的软件启动使用新的ssl 3.3.1 而其他的程序默认使用自带的版本ssl1.0.2)
实际应用
如果你的需求是 编译安装&启动Nginx时 使用 OpenSSL 3.3.1 版本,而 OpenSSH或其他程序继续使用原有的 OpenSSL 1.0.2k-fips 版本,您不需要更改系统的默认 PATH
环境变量。您只需要在编译 Nginx或其他程序 时指定 OpenSSL 3.3.1 的路径即可。
还有,在编译执行前,导入临时变量,指向新的openssl 3.3.1 版本
export PATH=/opt/OpenSSL-3.3.1/bin:$PATH
export LD_LIBRARY_PATH=/opt/OpenSSL-3.3.1/lib64:$LD_LIBRARY_PATH
华丽的分割线
安装Nginx
Nginx官网 nginx: download
关于Nginx版本选择:
Mainline version :主线版(基数版本)
Stable version:稳定版(偶数版本)
Legacy versions:历史版本
一般我们生产都会选择偶数版本,一般Nginx官方也会把偶数版本定义为稳定版(如nginx-1.26.2),而基数版本为主线版(nginx-1.27.1)
因此,我们选择稳定版 Nginx-1.26.2 下载安装
安装依赖项
yum install -y make gcc autoconf automake libtool pam pam-devel openssl-devel zlib-devel ncurses-devel perl libedit-devel libssh2-devel libxcrypt-compat libxml2 libxml2-devel libxslt libxslt-devel
这个命令将会安装以下包:
pam-devel
: PAM 开发库。openssl-devel
: OpenSSL 开发库。zlib-devel
: zlib 开发库。ncurses-devel
: ncurses 开发库。perl
: Perl 解释器。libedit-devel
: libedit 开发库。libssh2-devel
: libssh2 开发库。libxcrypt-compat
: 兼容密码加密库。libxml2
: XML 解析库。libxml2-devel
: libxml2 开发库。libxslt
: XSLT 处理库。libxslt-devel
: libxslt 开发库。
基础构建工具
make
: 用于构建软件。gcc
: GNU C 编译器。autoconf
: 用于生成自动化的配置脚本。automake
: 用于生成 Makefile。libtool
: 用于简化跨平台库的构建。
库和工具
pam-devel
:用于 PAM (Pluggable Authentication Modules) 开发文件。openssl-devel
:用于 OpenSSL 开发文件。zlib-devel
:用于 zlib 开发文件。ncurses-devel
:用于 ncurses 开发文件。perl
:Perl 解释器。用于某些脚本。libedit-devel
:用于编辑支持。libssh2-devel
:用于 SSHv2 支持。pam
:用于认证模块。libxcrypt-compat
:用于密码加密支持。libxml2
: XML 解析库。libxml2-devel
: libxml2 开发库。libxslt
: XSLT 处理库。libxslt-devel
: libxslt 开发库。
下载&解压nginx-1.26.2.tar.gz
把 nginx-1.26.2.tar.gz 放到 /opt 下解压
[root@CentOS7 ~]# cd /opt/
[root@CentOS7 opt]# ls
nginx-1.26.2.tar.gz OpenSSL-3.3.1
[root@CentOS7 opt]# tar -zxf nginx-1.26.2.tar.gz
[root@CentOS7 opt]# ls
nginx-1.26.2 nginx-1.26.2.tar.gz OpenSSL-3.3.1
[root@CentOS7 opt]# cd nginx-1.26.2/
[root@CentOS7 nginx-1.26.2]#
导入SSL 3.3.1环境变量(可选)
如果你之前编译安装openssl3.3.31 使用的是选择2-不更新环境变量,则需要执行此步骤
在编译执行前,导入临时变量,指向新的openssl 3.3.1 版本
export PATH=/opt/OpenSSL-3.3.1/bin:$PATH
export LD_LIBRARY_PATH=/opt/OpenSSL-3.3.1/lib64:$LD_LIBRARY_PATH
配置安装选项:
cd 进入到解压缩目录,配置Nginx的安装目录 /opt/Nginx-1.26.2 ,选择openssl的编译安装包路径(最后一行),强烈建议写绝对路径。
./configure \
--prefix=/usr/share/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/run/nginx.pid \
--lock-path=/run/lock/subsys/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-threads \
--with-pcre-jit \
--with-mail \
--with-mail_ssl_module \
--with-stream \
--with-stream_ssl_module \
--with-openssl=/opt/openssl-3.3.1 \
--with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic' \
--with-ld-opt='-Wl,-z,relro -Wl,-E'
编译
多线程编译命令
make -j$(nproc)
或者使用单线程编译命令
make
安装
make install
验证 Nginx 的 OpenSSL 版本:
检查 Nginx 是否使用 OpenSSL 3.3.1 版本。
nginx -V
验证 OpenSSH 的 OpenSSL 版本:
检查 OpenSSH 是否仍然使用原有的 OpenSSL 1.0.2k-fips 版本。
ssh -V
通过以上步骤,您可以确保 Nginx 使用 OpenSSL 3.3.1 版本,而 OpenSSH 继续使用原有的 OpenSSL 1.0.2k-fips 版本。
创建系统服务单元文件:
- 创建 Nginx 的 systemd 单元文件,以便于管理 Nginx 服务。
vim /etc/systemd/system/nginx.service
把下列内容copy进去
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
[Install]
WantedBy=multi-user.target
启用并启动 Nginx:
- 使用
systemctl
命令启用并启动 Nginx 服务。
systemctl daemon-reload
systemctl start nginx
systemctl enable nginx
验证 Nginx 支持的 SSL/TLS 协议:
- 使用
openssl s_client
命令来测试 Nginx 支持的协议。
openssl s_client -connect localhost:443 -tls1_3