"这个月爆了多少个漏洞?"——只要你关注安全公告,会发现答案永远是"很多"。一台装了常见组件的服务器,一个月收到几十个甚至上百个 CVE 是常态。如果每个都当紧急事件处理,团队会被拖垮;如果都不管,迟早中招。真正的挑战从来不是"有没有漏洞",而是"先修哪个、后修哪个、哪些可以不修"。
这就是漏洞修复优先级排序要解决的问题。它是一门"在资源有限的前提下做风险管理"的学问:同样两个高危漏洞,一个在公网可达的组件上、一个有公开利用代码、一个只在本地触发器才可用,它们的紧迫程度完全不同。光看 CVSS 分数排序是新手最容易犯的错——CVSS 高不等于对你威胁大,得结合可达性、可利用性、资产重要性综合判断。
这篇文章给一套可以落地的流程:先建立资产与漏洞台账,再用一个多维度的打分模型对漏洞排序,接着讲分级处置策略(哪些必须立刻修、哪些可以等窗口期、哪些接受风险),最后讲补丁落地的工程实践——灰度、回滚、验证,以及那些"补丁本身把业务搞挂"的坑。文中命令以 root 或 sudo 执行。
一、先建台账:不知道自己有什么,就谈不上优先级
优先级排序的前提是资产清单和漏洞清单两张表。没有资产清单,你连"这个漏洞影响的组件我有没有装"都答不上来。
资产清单要至少包含:主机名/IP、用途(对外Web/内网DB/跳板机等)、是否公网可达、操作系统与版本、运行的关键组件及版本、业务重要性等级(核心/重要/一般)、负责人。漏洞清单则来自各类扫描和公告:系统包漏洞、组件漏洞、配置缺陷。
Linux 上可以用现成工具自动收集漏洞信息:
# 1. 查看系统上有哪些需要更新的安全补丁
# RHEL/CentOS/Rocky 系:只列出安全相关更新
dnf updateinfo list security
# 或更详细,显示 CVE 编号
dnf updateinfo list --security --info
# 检查系统若干关键组件的当前版本
rpm -q openssl nginx httpd glibc 2>/dev/null
# Debian/Ubuntu 系:查看可升级的安全包
apt update
apt list --upgradable 2>/dev/null
# 安装并使用 debsecan 检查漏洞
apt install -y debsecan
debsecan --suite bookworm --format detail
对于服务器数量较多的情况,纯命令行不够用,需要引入漏洞扫描平台。主流的做法有几类:一是各发行版厂商自带的补丁元数据(dnf updateinfo、Ubuntu Security Notices);二是独立的漏洞扫描器(OpenVAS/Greenbone、Nuclei 等)做远程和本地扫描;三是云厂商的安全中心(主流云厂商都提供主机安全/入侵检测产品,能给出漏洞清单)。资产台账最好是自动化的、动态更新的,靠手工维护的 Excel 很快会过期。
下面这张表是资产清单的一个示例结构,重点在于把"重要性"和"可达性"这两列填清楚,因为它们是后续打分的关键输入:
| 主机 | 用途 | 公网可达 | 系统版本 | 关键组件 | 重要性 |
|---|---|---|---|---|---|
| web-01 | 对外Web | 是 | Rocky 9 | nginx 1.24, php 8.2 | 核心 |
| db-01 | 数据库 | 否 | Rocky 9 | MySQL 8.0 | 核心 |
| jump-01 | 跳板机 | 受限IP | Ubuntu 22.04 | openssh 8.9 | 重要 |
| app-03 | 内网应用 | 否 | Ubuntu 20.04 | java 11 | 一般 |
二、打分模型:CVSS 只是其中一维
有了台账,接下来给每个漏洞打分。这里的关键认知是:CVSS 描述的是漏洞本身有多严重,不描述它对"你的资产"有多危险。 排序必须引入资产视角。
一个实用的四维打分模型(经验做法,可按团队调整):
- 基础严重度(来自 CVSS 或厂商评级):漏洞本身的技术严重程度,0-10 分。
- 可达性:攻击者能不能通过网络触达受影响组件。公网直接可达最高,需要内网横向移动次之,仅本地触发最低。
- 可利用性:是否已有公开的利用代码(exploit)、是否已被在野利用(KEV 清单)、利用难度高低。有武器化的 PoC 要显著提权。
- 资产重要性:受影响主机承载的业务价值,核心系统加权,测试/闲置系统降权。
把这四维合成一个优先级分数,比单看 CVSS 可靠得多。一个常用的合成方式是加权求和,再映射到 P0~P3 分级:
| 优先级 | 典型特征 | 处置时限(参考) |
|---|---|---|
| P0 紧急 | 公网可达 + 有在野利用 + 核心资产 | 24 小时内 |
| P1 高 | 公网可达 + 高危 + 有 PoC,或非公网但有在野利用 | 3 天内 |
| P2 中 | 可达性一般 + 中高危 + 无公开利用 | 下一个维护窗口 |
| P3 低 | 本地触发 / 低危 / 边缘资产 | 随版本迭代合并 |
需要强调的几个判断要点:
有在野利用(KEV)的漏洞优先级要大幅提前。 一个 CVSS 7.5 但已被真实攻击利用的漏洞,比一个 CVSS 9.8 但还没有任何利用代码的漏洞,紧迫得多。CISA 维护的"已知被利用漏洞"清单是很好的参考来源。
"公网可达"是最大的放大器。 一个只在内网、需要认证才能触发的漏洞,和一个暴露在公网的未认证远程代码执行,风险差着量级。所以排序前一定要先确认:这个组件的端口是不是真的对外开着。
# 确认某端口是否监听在所有网卡(0.0.0.0 表示对外)
ss -tlnp | grep -E ':80|:443|:22'
# 确认防火墙/安全组是否放行(以 firewalld 为例)
firewall-cmd --list-all
注意"安全软件依赖库"的特殊性。 像 OpenSSL、glibc、OpenSSH、内核这类基础组件的漏洞,影响面广但修复风险也高(更新这些组件可能影响大量服务、甚至需要重启)。这类漏洞要走更谨慎的流程,而不是简单 dnf update。
三、分级处置:修、缓、接受、转嫁
排序之后是决策。不是所有漏洞都要"修",处置策略有四种:
修复(Patch):打补丁或升级组件。这是最彻底的方案,适用于 P0/P1 和大部分 P2。
缓解(Mitigate):短期打不了补丁时,用配置、防火墙、WAF、关闭功能等方式降低风险。比如某个组件有漏洞但暂时不能升级,可以用防火墙只允许特定来源访问它,或者禁用相关功能模块。缓解是"过渡手段",要设定复核时间,不能变成永久遗留。
接受(Accept):对 P3 低风险漏洞,评估后选择接受,但要书面记录接受的理由、风险评估结论和复核时间。接受不是"忘了修",而是有意识地承担可控风险。
转嫁(Transfer):通过架构手段把风险转移,比如给公网入口加 WAF/云防护、把高风险组件移到隔离网络、购买相关保险等。
实际工作中,这四种策略常常混用。比如一个刚爆出的公网组件 RCE:立刻用防火墙临时收紧访问(缓解),同时准备升级包做灰度(修复),这就是很标准的应急节奏。
四、补丁落地:灰度、窗口、回滚
决定了修哪个,接下来是"怎么修得不出事"。补丁管理的工程流程比排序更容易翻车——一次莽撞的全量升级可能让核心业务挂掉,那就本末倒置了。
第一步,测试环境验证。 生产补丁先在测试环境安装,跑通业务流程,观察是否有兼容性问题(尤其是内核、glibc、数据库、语言运行时这类组件的升级,回归风险高)。
第二步,选择维护窗口。 补丁可能引起服务重启甚至系统重启,要安排在业务低峰期。对内核更新这类需要重启的,提前通知业务方。
第三步,灰度分批。 先在一批非核心/备机上升级,观察一段时间,没问题再推核心机。分批的批量建议按"先 1 台、再 10%、再全量"的节奏,具体看集群规模。
第四步,备份与回滚预案。 升级前备份:
- 配置文件(/etc 关键文件)
- 数据库(逻辑备份或快照)
- 系统快照(如果云主机支持,升级前打快照是最省心的回滚手段)
- 记录当前版本(rpm -qa > /root/pkgs_before.txt 或 dpkg -l > /root/pkgs_before.txt),便于版本回退对比
# 升级前记录包版本清单,作为回滚参照
rpm -qa | sort > /root/pkgs_before_$(date +%F).txt # RHEL 系
dpkg -l | sort > /root/pkgs_before_$(date +%F).txt # Debian 系
# 只安装安全更新(最小改动原则)
dnf update --security # RHEL 系
# Debian 系可用 unattended-upgrades 仅做安全更新
apt install -y unattended-upgrades
dpkg-reconfigure --priority=low unattended-upgrades
第五步,验证与记录。 升级后确认服务正常、关键功能可用、版本号符合预期,并记录到台账:修了哪个 CVE、什么时候、谁操作的、有没有副作用。
对内核这类需要重启的更新,有两种策略:重启生效(简单但有业务中断),或者用 kpatch/kGraft 这类内核热补丁(不重启但覆盖有限、且需要厂商支持)。多数场景下,内核更新安排在维护窗口重启即可。
自动更新的取舍也值得一说:unattended-upgrades(Debian)能自动装安全补丁,省心,但对生产关键系统要谨慎——自动升级可能在无人值守时引入不兼容变更。更稳妥的做法是"自动下载、人工/窗口期安装",或者只在非核心机器上开自动更新。
五、为什么补丁会"帮倒忙":常见翻车场景
补丁管理做久了,一定会遇到"升级之后反而出事"。下面是几个高频翻车场景和规避思路:
内核/libc 升级导致服务异常。 依赖特定内核接口的程序(如某些监控代理、虚拟化组件、GPU 驱动)在新内核上可能不兼容。规避:这类组件先在灰度机验证;保留旧内核(不要手贱删 /boot 里的老内核),必要时可回滚选择旧内核启动。
OpenSSL 升级导致依赖它的服务无法启动。 某些程序静态链接了旧 OpenSSL 或有 ABI 依赖,升级后需要同时重启相关服务。规避:升级 openssl 后系统性重启依赖服务,并逐一验证。
数据库小版本升级引发兼容问题。 MySQL/PostgreSQL 的小版本更新一般安全,但大版本跨越要按官方升级路径走,不能直接换包。规避:数据库升级单独走专门流程,先备份、再测试、再灰度。
包管理器依赖冲突。 dnf update 或 apt upgrade 有时会因依赖关系拒绝执行,或者把本想保留的包一起升级。规避:生产环境尽量用"最小改动",只升级安全补丁而非全量 upgrade;遇到依赖冲突不要用 --force 硬来,先分析冲突原因。
磁盘空间不足导致升级失败半途。 老机器 /var 或 /boot 快满了,升级装到一半没空间,系统可能进入不稳定状态。规避:升级前 df -h 检查,尤其 /boot(内核更新要往里装文件,通常需要留出 200MB 以上,经验值)。
# 升级前必做检查
df -h /boot /var / # 磁盘空间
free -h # 内存(编译型包安装可能吃内存)
systemctl --failed # 是否已有失败的服务(先解决再升级)
常见问题
Q:只按 CVSS 分数排序不行吗?
不行。CVSS 衡量漏洞本身的技术严重度,不含"你的资产是否暴露、是否已被利用"。一个 CVSS 9.8 但只影响内网、无公开利用的漏洞,和一个 CVSS 7.5 但公网可达、已有在野利用的漏洞,后者更该先修。排序必须结合可达性、可利用性和资产重要性。
Q:漏洞太多了,根本修不过来怎么办?
这恰恰是优先级排序的意义。把 P0/P1(公网可达 + 在野利用 + 核心资产)先修掉,剩下的按窗口期批量处理,明确哪些接受风险。目标不是"清零",而是"把不可接受的风险压到最低"。同时通过架构减少暴露面(能不暴露公网就不暴露),从源头减少需要紧急处理的数量。
Q:用自动更新(unattended-upgrades / dnf-automatic)省事吗?
省事但有风险。核心生产系统建议"自动下载、受控安装",避免无人值守时因升级引入不兼容。非核心、无状态、可随时重建的机器可以开自动更新。关键是任何自动更新都要有告警和回滚能力。
Q:有的漏洞厂商一直没有补丁,怎么办?
先做缓解:收紧访问(防火墙只允许必要来源)、关闭受影响的功能、WAF 拦截利用特征。同时评估是否能换用替代组件。如果组件已停止维护(EOL),那本身就是一个需要迁移的信号,别指望它会出补丁。
Q:怎么证明我们"做了补丁管理"?
靠记录。每次补丁的决策(修/缓/接受)都要留痕:CVE 编号、评估结论、处置动作、时间、责任人。有了这份台账,既能应对合规检查,也能在下一次排序时复用历史判断。
总结
- 优先级排序的前提是两张表:资产台账(含公网可达性、资产重要性)和漏洞清单;台账要自动化、动态更新,别用会过期的 Excel。
- 排序不能只看 CVSS,要用"基础严重度 + 可达性 + 可利用性 + 资产重要性"四维模型;有在野利用(KEV)和公网可达是两个最大的加权项。
- 处置策略有四种:修复、缓解、接受、转嫁。缓解要有复核时间,接受要书面留痕,别把"忘了修"包装成"接受风险"。
- 补丁落地要工程化:测试环境验证 → 维护窗口 → 灰度分批 → 备份与回滚预案 → 验证记录,缺一步都可能翻车。
- 提前防范常见翻车:内核/libc/OpenSSL/数据库升级的兼容性、依赖冲突、
/boot磁盘空间不足;升级前先df -h、记录包版本、打快照。 - 减少暴露面本身是最省力的"漏洞治理"——能把组件从公网撤下来、能收窄访问范围的,就先做掉,这比事后追着打补丁划算得多。
企业QQ咨询




