CentOS7运维编译源码把yum安装的Nginx升级到1.26.3
前言
CentOS 7 的 yum 仓库里很多时候拿不到目标版本的 Nginx RPM 包。
如果漏洞扫描要求必须升级到 1.26.3,常见做法是源码编译并替换 yum 安装的旧二进制。
本文以“保留 yum 的目录结构与服务管理”为目标,把 yum 安装的旧版本升级为 1.26.3。
本文默认你当前配置目录为 /etc/nginx,服务由 systemctl 管理。
当前环境确认
确认系统版本。
1 | cat /etc/os-release |
确认当前 nginx 版本与路径。
1 | nginx -v |
查看当前编译参数用于对比升级后模块差异。
1 | nginx -V |
备份旧版本
备份配置目录。
1 | sudo cp -a /etc/nginx /etc/nginx.bak.$(date +%F) |
备份旧二进制。
通常 yum 安装的路径在 /usr/sbin/nginx。
1 | sudo cp -a /usr/sbin/nginx /usr/sbin/nginx.bak.$(date +%F) |
备份 systemd 服务文件用于回滚。
1 | sudo systemctl cat nginx > /root/nginx.service.bak.$(date +%F).txt |
升级前先确保当前配置可用。
1 | sudo nginx -t |
准备编译环境
安装编译依赖。
1 | sudo yum install -y gcc gcc-c++ make pcre pcre-devel zlib zlib-devel openssl openssl-devel |
准备源码包并下载 1.26.3。
1 | curl -LO https://nginx.org/download/nginx-1.26.3.tar.gz |
编译Nginx1.26.3
关键目标是生成一个新二进制并继续使用 /etc/nginx/nginx.conf。
下面配置把 --conf-path 指到 yum 体系的配置路径。
1 | ./configure \ |
编译。
1 | make -j"$(getconf _NPROCESSORS_ONLN)" |
不要直接 make install 覆盖全量目录。
我们只替换 nginx 二进制并保持 yum 的配置与目录不变。
编译完成后先本地自检新二进制。
1 | ./objs/nginx -V |
替换yum安装的nginx二进制
将新二进制覆盖到 /usr/sbin/nginx。
1 | sudo systemctl stop nginx |
如果替换不了文件
cp: cannot create regular file ‘/usr/sbin/nginx’: Text file busy
说明 还有进程在执行 /usr/sbin/nginx(哪怕你 systemctl stop 了也可能残留 master/worker,或者有别的 unit/守护在拉起)。
先把占用者找出来并杀掉
1 | sudo systemctl stop nginx |
如果还能看到 nginx 进程:
1 | sudo pkill -9 nginx |
验证新版本是否生效。
1 | nginx -v |
验证
查看服务状态与端口监听。
1 | sudo systemctl status nginx --no-pager |
验证本机访问。
1 | curl -I http://127.0.0.1 |
常见问题
模块差异导致配置报错
你编译的模块与 yum 包可能不同。
如果 nginx -t 报 unknown directive,通常是缺少对应模块导致。
先用 nginx -V 对比旧版本的 configure arguments,再补齐 ./configure 参数重编译。
动态模块版本不一致
典型报错如下:
1 | nginx: [emerg] module "/usr/lib64/nginx/modules/ngx_http_image_filter_module.so" version 1016001 instead of 1026003 in /usr/share/nginx/modules/mod-http-image-filter.conf:1 |
原因是你只替换了 /usr/sbin/nginx(主程序已升级到 1.26.3),但 yum 安装时提供的动态模块仍在被加载(模块是按旧版本 Nginx 编译的),从而触发版本不匹配。
这样一般是编译的时候已经加载对应模块 配置中又加载相同模块,但是版本不兼容,我们按上面的的提示注释掉配置文件中加载的代码即可。
如上就是找到/usr/share/nginx/modules/mod-http-image-filter.conf这个文件注释掉其中的配置。
也可以直接删除这个加载的配置。
SELinux导致启动失败
若启用了 SELinux,替换二进制后可能出现权限或上下文问题。
临时确认问题时可以先查看日志定位。
1 | sudo journalctl -u nginx -n 200 --no-pager |
回滚
回滚只需要把旧二进制拷回去并重启服务。
1 | sudo cp -a /usr/sbin/nginx.bak.$(date +%F) /usr/sbin/nginx |
如果你备份文件名不是当天日期,请把路径改成实际备份文件名。
总结
通过源码编译升级 yum 安装的 nginx 的核心思路。
保留
/etc/nginx配置不动并先备份旧二进制。使用
--conf-path=/etc/nginx/nginx.conf让新二进制继续读取原配置。只替换
/usr/sbin/nginx并通过systemctl reload nginx平滑生效。若出现配置报错优先对比
nginx -V的模块参数并重编译补齐。