CentOS7运维编译源码把yum安装的Nginx升级到1.31.3
前言
CentOS 7 的 yum 仓库里很多时候拿不到目标版本的 Nginx RPM 包。
如果漏洞扫描要求必须升级到 1.31.3,常见做法是源码编译并替换 yum 安装的旧二进制。
本文以“保留 yum 的目录结构与服务管理”为目标,把 yum 安装的旧版本升级为 1.31.3。
本文默认你当前配置目录为 /etc/nginx,服务由 systemctl 管理。
下载地址
当前环境确认
确认系统版本。
1 | cat /etc/os-release |
确认当前 nginx 版本
1 | nginx -v |
查看当前编译参数用于对比升级后模块差异。
1 | nginx -V |
查看服务文件
1 | vi /etc/systemd/system/nginx.service |
查看Nginx配置文件路径
1 | nginx -t |
查看Nginx配置文件路径和编译参数,后面可以直接使用
1 | nginx -V |
通过YUM安装的路径是
/usr/sbin/nginx
备份旧版本
备份配置目录。
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 gd-devel |
准备源码包并下载 1.31.3。
1 | curl -LO https://nginx.org/download/nginx-1.31.3.tar.gz |
编译Nginx
编译
关键目标是生成一个新二进制并继续使用 /etc/nginx/nginx.conf。
编译参数可以直接通过nginx -V获取,最好和之前的保持一致。
下面配置把 --conf-path 指到 yum 体系的配置路径。
1 | ./configure \ |
上面的依赖gd-devel 是用于图片处理的,也可以不要http_image_filter_module
如果不是yum安装的,要注意配置中的各个路径
1 | ./configure \ |
编译。
1 | make -j"$(getconf _NPROCESSORS_ONLN)" |
不要直接 make install 覆盖全量目录。
我们只替换 nginx 二进制并保持 yum 的配置与目录不变。
查看配置文件路径
1 | nginx -t |
编译完成后先本地自检新二进制。
1 | ./objs/nginx -V |
如果路径在/usr/local/nginx/conf/nginx.conf
1 | ./objs/nginx -t -c /usr/local/nginx/conf/nginx.conf |
如果有错误按提示修复就行
比如我这报错
1 | nginx: the configuration file /etc/nginx/nginx.conf syntax is ok |
直接创建文件夹就行
1 | mkdir -p /usr/local/nginx/client_body_temp |
验证
创建后重新校验
1 | ./objs/nginx -t -c /etc/nginx/nginx.conf |
直到所有的错误修复后再替换。
参数说明
1 | # 安装基准目录,存放html、默认模块等 |
显式写死绝对路径后,不再受 --prefix 影响。
安装前手动创建对应目录,避免启动报错。
替换Nginx
替换yum安装的nginx二进制
查看运行Nginx位置
1 | ps -ef | grep nginx |
将新二进制覆盖到 /usr/sbin/nginx。
1 | sudo systemctl stop nginx |
注意Nginx的路径
1 | sudo cp -a ./objs/nginx /usr/local/nginx/sbin/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 |
回滚
回滚只需要把旧二进制拷回去并重启服务。
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的模块参数并重编译补齐。
常见问题
模块差异导致配置报错
你编译的模块与 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.31.3),但 yum 安装时提供的动态模块仍在被加载(模块是按旧版本 Nginx 编译的),从而触发版本不匹配。
这样一般是编译的时候已经加载对应模块 配置中又加载相同模块,但是版本不兼容,我们按上面的的提示注释掉配置文件中加载的代码即可。
如上就是找到/usr/share/nginx/modules/mod-http-image-filter.conf这个文件注释掉其中的配置。
也可以直接删除这个加载的配置。
SELinux导致启动失败
若启用了 SELinux,替换二进制后可能出现权限或上下文问题。
临时确认问题时可以先查看日志定位。
1 | sudo journalctl -u nginx -n 200 --no-pager |
启动卡死
查看错误日志
1 | systemctl status nginx -l |
修改服务文件
1 | vi /etc/systemd/system/nginx.service |
内容
1 | [Unit] |
启动
1 | # 杀掉所有残留nginx进程 |
验证
1 | ps -ef | grep nginx |