去年秋天,洞修我负责维护的洞修一台CentOS 7服务器被扫出一个OpenSSH漏洞,CVE-2023-38408。洞修当时第一反应是洞修直接yum update openssh,结果重启sshd之后,洞修所有基于密钥的洞修登录全挂了——因为新版本默认禁用了ssh-rsa算法。这件事让我意识到,洞修修复Linux漏洞从来不是洞修敲一条更新命令就完事。
你得先搞清楚漏洞到底出在哪一层。洞修是洞修内核态还是用户态?是glibc这种基础库,还是洞修某个跑在8080端口的Java应用依赖的Log4j?我见过太多人一上来就apt upgrade,把整个系统升到最新,洞修结果生产环境里某个老旧的洞修PHP扩展跟新内核不兼容,服务直接起不来。洞修正确的洞修做法是先确认漏洞编号,去NVD或者发行版的CVE追踪页看影响范围。比如Debian有自己的安全追踪器,Red Hat有RHSA公告,里面会写清楚哪个包、哪个版本区间受影响。
确认之后,别急着在生产机上动手。找一台同配置的测试机,把补丁打上去,跑一遍核心业务逻辑。去年有个朋友的公司修一个glibc的提权漏洞,补丁本身没问题,但他们没注意到新glibc对某个老版本Oracle客户端的兼容性,结果财务系统月底结账时直接崩了。测试这一步省不得,哪怕你觉得“就一个小版本更新”。
补丁来源要认准官方渠道。CentOS用yum update --security只装安全更新,Ubuntu用unattended-upgrades配置自动安全更新,但自动更新我建议只开在测试环境。生产环境最好手动控制,因为有时候补丁会引入新依赖,或者需要重启特定服务。像内核漏洞,你yum update kernel之后不重启,新内核根本没生效,漏洞还在那敞着。
有些漏洞没有官方补丁,或者补丁来得太慢。这时候得看临时缓解措施。比如那个著名的Dirty Pipe,在补丁出来之前,可以临时禁用非特权用户对某些系统调用的访问,或者用SELinux策略限制。再比如Log4j那个核弹级漏洞,如果应用不能马上升级,就得在JVM参数里加-Dlog4j2.formatMsgNoLookups=true,或者直接删掉JndiLookup.class文件。这些操作虽然治标不治本,但能给你争取时间。
修复完之后别以为就完了。我习惯在修复后跑一次lynis或者openscap做合规扫描,确认漏洞真的没了。同时检查日志,看有没有异常登录或者提权行为——有些漏洞在被修复之前可能已经被利用了,你补上漏洞不等于清除了后门。有一次我帮人修一个Sudo漏洞,补丁打完后顺手查了/var/log/auth.log,发现攻击者前一天就已经用这个漏洞拿了root,还留了一个cron任务。要不是多看了一眼,补丁就白打了。
最后说个容易被忽略的点:修复漏洞的优先级。不是所有漏洞都值得半夜爬起来处理。CVSS评分高的不一定对你威胁大,得看你的暴露面。一个只监听内网的Redis漏洞,和一个公网可访问的Nginx漏洞,紧急程度完全不同。我一般按“可利用性×暴露面×资产重要性”来排优先级。那些需要本地登录才能利用的提权漏洞,如果服务器本身访问控制就很严,可以排到常规维护窗口再处理。
修漏洞这事,说白了就是个体力活加细心活。别迷信自动化工具,也别觉得打完补丁就万事大吉。多看一眼日志,多跑一次测试,比什么都强。