Nginx高危漏洞批量检测自动升级脚本工具实操教程
Nginx 出现高危漏洞时,如果只有一两台机器,手工升级还应付得过来;
但服务器数量一多,逐台登录、对比版本、执行升级既慢又容易漏。
本文分享一套 Nginx 高危漏洞批量检测自动升级的脚本工具思路,包含可复制的 Shell 脚本、升级前的备份策略和升级后的效果验证,适合管理多台 Linux 服务器的零基础运维直接参考。
先判断是否真的需要这类脚本工具
如果你的服务器数量超过 5 台,或 Nginx 版本已经低于官方最新稳定版,并且担心安全问题整改时遗漏机器,就值得用脚本统一处理。
脚本工具的核心能力只有三件事:
- 批量读取服务器 IP 列表,自动探测 Nginx 版本和安装方式
- 将版本与已知高危漏洞版本范围比对,标记需要升级的目标
- 对目标服务器执行升级命令,并生成结果日志
注意:漏洞库列表需要自己维护,没有官方自动同步接口。
建议每次使用前,去 Nginx 官方安全公告页核对当前受影响版本范围,再填入脚本的数组里。
准备工作:确认环境与控制方式
先确认你有哪些机器、是否支持免密 SSH 登录。
推荐在本地跳板机或管理机上操作,执行以下命令测试:
ssh root@192.168.1.101 "nginx -v 2>&1"
能正常输出版本号,说明 SSH 可连。
如果机器较多,建议提前配置好 SSH 密钥免密登录,避免脚本执行时反复输入密码。
同时准备一个 servers.txt 文件,每行一个 IP 或域名:
192.168.1.101
192.168.1.102
192.168.1.103
另外,升级前必须确认软件源。
如果 Nginx 是通过系统源安装,直接用 yum 或 apt 升级;
如果是源码编译安装,则要保留当时的编译参数。
批量检测与自动升级脚本核心写法
下面这个脚本实现了“检测版本 → 匹配漏洞范围 → 自动升级 → 记录日志”的完整流程。
请根据实际环境调整漏洞版本数组内容。
#!/bin/bash
# nginx_vuln_scan_upgrade.sh
# 用法: bash nginx_vuln_scan_upgrade.sh
SERVERS="servers.txt"
LOG_FILE="nginx_upgrade_$(date +%Y%m%d).log"
# 已知存在高危漏洞的版本范围,按需修改
VULN_VERSIONS=("1.0.0-1.20.2" "1.21.0-1.21.5" "1.22.0-1.22.1")
compare_version() {
# 将版本号转成可比较的数字,如 1.22.1 -> 1.22.1
local v=$1
local range=$2
IFS='-' read -r start end <<< "$range"
# 这里简化处理,实际可用 rpmdev-vercmp 或 sort -V
[[ "$v" > "$start" || "$v" == "$start" ]] && [[ "$v" < "$end" || "$v" == "$end" ]]
}
while read -r ip; do
echo "========== $ip ==========" | tee -a "$LOG_FILE"
# 获取当前版本
version=$(ssh root@"$ip" "nginx -v 2>&1 | awk '{print \$3}'" | sed 's/nginx\///')
if [ -z "$version" ]; then
echo "[$ip] 未检测到 Nginx,跳过" | tee -a "$LOG_FILE"
continue
fi
echo "[$ip] 当前版本: $version" | tee -a "$LOG_FILE"
# 判断是否命中漏洞范围
need_upgrade=0
for range in "${VULN_VERSIONS[@]}"; do
if compare_version "$version" "$range"; then
need_upgrade=1
break
fi
done
if [ $need_upgrade -eq 1 ]; then
echo "[$ip] 存在高危漏洞,开始自动升级" | tee -a "$LOG_FILE"
ssh root@"$ip" "nginx -t && cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak_$(date +%F) && yum update nginx -y 2>&1 || apt-get update && apt-get install --only-upgrade nginx -y" | tee -a "$LOG_FILE"
ssh root@"$ip" "systemctl reload nginx && nginx -v" | tee -a "$LOG_FILE"
else
echo "[$ip] 版本安全,无需升级" | tee -a "$LOG_FILE"
fi
done < "$SERVERS"
脚本中的 compare_version 函数只是一个简化比较逻辑,生产环境建议用 sort -V 或 rpmdev-vercmp 做精确版本比较,
避免出现 1.9 大于 1.10 这类错误。
几个容易踩坑的细节
- 升级前一定要备份配置。脚本里已经写了
nginx.conf.bak,但建议同时备份/etc/nginx/整个目录和站点配置文件。 - 不同系统包管理器不一样。同一套脚本里写
yum和apt的条件判断,如果你管理的是 CentOS 和 Ubuntu 混合集群,建议按系统类型分开批量执行。 - 升级后必须执行
nginx -t。配置不兼容会导致 reload 失败,脚本里要先测试再 reload,这样能减少误操作。 - 不要用
kill -9升级 Nginx。使用systemctl reload可以实现平滑重载,旧 worker 进程会处理完已有请求再退出,避免中断在线业务。 - 漏洞库要定期更新。官方安全公告会随着时间变化,脚本只能覆盖你填入的版本范围,不能一劳永逸。
如何验证批量升级真的成功
执行完脚本后,别只看日志里写了“升级完成”。
建议重新扫描一遍并核对以下三点:
- 在每台机器上运行
nginx -v,确认版本号已经脱离漏洞范围。 - 用
curl -I http://服务器IP检查 HTTP 响应码,确认业务正常返回 200。 - 查看 Nginx 错误日志,通常路径为
/var/log/nginx/error.log,确认没有新增报错。
如果想形成闭环,可以把上述检查也写进脚本里,最后统一输出一份“未升级成功”的机器列表。
这样针对 Nginx 高危漏洞的批量检测和自动升级才算是真正落地。
如果你正在处理这批脚本工具,建议先在一台测试机上完整跑一遍,确认漏洞库和版本比较逻辑无误后,再批量执行。
遇到卡在 SSH 登录或包管理器报错时,优先回头检查密钥权限和系统源配置。