最近把自己手底下那批SUSE 15服务器做了一次内核升级起因就是CVE-2025-38352这个编号的漏洞公告。做运维的看到“Kernel”和“漏洞修复”这两个词放在一起基本就知道这趟活儿省不了心升级窗口要排依赖要理顺第三方模块还要提前确认兼容性。这篇文章就把我这次从威胁研判、升级前检查到实际执行、验证回滚的完整过程拆开写一遍重点放在SUSE 15SLES 15上用zypper做内核升级的具体操作步骤以及那些官方文档里不会告诉你的坑和判断逻辑给后面需要同样操作的兄弟们做个参考。1. 漏洞背景与影响范围1.1 CVE-2025-38352到底是什么CVE-2025-38352属于内核级别的安全漏洞。虽然不同SP版本受影响的严重程度不一样但这类漏洞通常有两个共性一个是CVSS评分往往不低另一个是修复只能靠内核版本升级通过打补丁的方式去修很难完全根治因为漏洞点直接位于内核子系统内部代码里。我看到公告的第一反应不是急着去点升级按钮而是先搞清楚自己的环境是不是真的在受影响范围之内。SUSE的CVE公告页面一般会写清楚受影响的包名、修复包名、内核基准版本号。比如kernel-default包会给出完整的内核RPM包名对照当前系统里的版本号一眼就能判断出风险。这里要给刚接触SUSE的朋友补充一个点SLES 15不是只有一个内核版本它有不同的Service PackSP分支。SP1、SP2、SP3、SP4、SP5、SP6各自维护不同的内核基线所以CVE-2025-38352在不同SP分支上的“修复版本号”是完全不一样的。升级之前一定不要只记一个版本号要看你的SP版本对应的那个修复版本。1.2 受影响系统与风险评分从实际影响来看这类漏洞如果触发成功通常可能导致本地权限提升、系统崩溃严重情况下可以让攻击者获得更高的操作权限。对于跑生产业务的SLES 15环境来说权限提升意味着后续横向移动、篡改配置、窃取数据都成了可能所以风险等级我一般按高优先级处理。不过优先级高不代表要马上在生产环境上动手。正确的处理方式是把受影响的机器分个类哪些是测试环境、哪些是灰度环境、哪些是核心业务生产机。测试环境必须第一时间升级跑一遍业务回归核心生产机则放在维护窗口内执行而且要有完整的回滚方案之后才动。1.3 修复策略选型内核升级还是临时缓解SUSE官方针对有些内核漏洞会给出临时缓解措施常见的就是sysctl参数调整、限制某些内核模块加载这类操作。但我的建议很简单临时缓解只能用于争取时间最终问题还是要靠内核升级来解决。原因有三个。第一临时缓解措施只针对已知的攻击路径攻击者换一个调用链就可能绕过。第二每个缓解参数都可能影响系统性能或者业务行为不敢长时间挂着。第三内核漏洞往往会随着开发者的深入利用研究被不断发现新的变种最稳妥的做法就是直接升到修复版本上一了百了。所以这次我没有去研究那些临时参数直接把重点放到了内核升级的完整流程上。接下来的内容就是从升级前准备到实际操作再到验证回滚的全过程。2. 升级前要做的四件事2.1 确认当前内核版本和目标版本无论你多清楚内核对齐的重要性实际动手之前都要在系统里跑一遍确认命令。我自己基本上固定用下面这几条来摸底cat /etc/os-release uname -r zypper se kernel-default hostnamectl第一行看系统版本确认是SLES 15还是SLE 15 SP几第二行看当前运行的内核第三行能从仓库里看到最新的可用内核包版本最后一行能顺便确认机器角色。不要凭印象写结论必须把这些信息先抓出来。拿到当前内核版本之后对照SUSE官方CVE页面上给出的“Fixed version”字段就能确认升级目标版本。举个例子如果公告里修复版本是kernel-default-5.14.21-150500.53.1而你当前是5.14.21-150400.24.1那目标就很明确了。注意这里说的版本号只是示例实际请以你订阅的SUSE仓库里zypper se -s kernel-default输出的可用版本为准。不同SP版本的目标内核包名后缀差异很大。2.2 磁盘空间与引导空间评估内核升级最容易被忽略的就是磁盘空间检查尤其是/boot分区。很多SLES 15机器的/boot分区大小只有几百兆旧内核、新内核、initrd镜像、System.map文件全部堆在一起很容易把/boot塞满。检查命令是df -h /boot df -h /var为什么还要看/var因为zypper的缓存和下载的RPM包会放在/var/cache/zypp/packages如果/var空间不够下载中断会导致依赖解析出错。经验上/boot剩余空间建议大于500MB/var剩余空间建议大于2GB才算比较稳妥。如果空间紧张可以在升级前先用zypper clean清理缓存或者手动清理掉不再用的旧内核包。但注意不要让zypper把当前运行的内核也清理掉手动删除旧内核时务必保留当前版本。2.3 业务影响评估与维护窗口内核升级无法热切换必须重启系统才能生效这是所有人都绕不开的硬约束。所以升级前一定要跟业务方确认维护窗口。我自己一般会重点关注这几项应用是否有集群模式、多节点负载分担是否允许逐台重启。有没有长连接任务、批量任务、定时任务在维护窗口内启动。数据库等有状态服务重启前是否已经完成持久化或主备切换。是否有外接硬件依赖对应驱动模块升级后驱动是否还能加载。这些评估结果直接决定我是在凌晨操作还是可以工作时间段执行。做过几年生产环境运维的人应该都清楚内核升级本身成功率不低真正导致翻车的往往是业务侧没评估到位。2.4 回滚预案设计每次升级内核之前我都强迫自己做好回滚预案。回滚预案不是说“出问题就重启进旧内核”而是要提前确认旧内核的启动项是否还在新内核是否已经写入了GRUB配置以及如果新内核启动失败默认启动项是否指向旧内核。在SLES 15上安装完新内核后GRUB会把新内核放在启动菜单最前面。正常情况下没问题但如果新内核和机器上的某些第三方内核模块不兼容启动阶段就可能卡住或直接panic。所以升级前最好手动看一眼当前GRUB菜单里有哪些启动项grub2-once --list 2/dev/null || cat /boot/grub2/grub.cfg | grep menuentry 把输出保存下来心里有数。真到需要回滚的时候重启机器在GRUB菜单里选择旧内核的启动项进系统后检查后续状态再决定是重新排查还是保持旧内核运行。3. 内核升级实操全过程3.1 刷新仓库并确认候选内核在SLES 15上安装新内核前先把软件源刷新到最新不然仓库里的元数据可能是旧的压根看不到修复版本。zypper refresh刷新完成之后用下面的命令确认仓库里是否有修复内核包zypper se -s kernel-default | tail -5-s的作用是同时显示版本号、架构和仓库来源便于准确判断目标版本。这里我想提醒一句SLES 15的模块化仓库结构里内核包一般来自SLE-Module-Basesystem和SLE-Module-Legacy这两个模块必须启用。如果你发现zypper se kernel-default看不到任何候选版本首先检查的就是模块是否启用。检查模块状态zypper repos输出里SLE-Module-Basesystem状态应该是enabled如果不是先启用再刷新。3.2 安装新内核与相关工具包确认候选版本没问题之后执行安装命令。我建议直接指定版本号安装而不是直接zypper up全局升级。指定版本号的好处是只动内核不碰其他软件包避免依赖面被扩大。zypper in -y kernel-default-5.14.21-150500.53.1整体安装时间取决于网络和源的速度一般在几分钟到十几分钟不等。安装完成后zypper会自动触发mkinitrd生成新的initrd镜像同时更新GRUB配置。但这一步不总是可靠的尤其当你改了/etc/default/grub里的自定义参数时自动生成的引导配置可能不符合预期。所以安装完之后我都会再做一次手动检查ls -lt /boot/vmlinuz-* ls -lt /boot/initrd-*确认新内核的vmlinuz和initrd都已经生成而且文件时间是最近几分钟内的。提示SUSE 15里mkinitrd已经被dracut逻辑接管你在系统里可能看到/sbin/mkinitrd指向dracut的包装脚本这是正常的。手动重建initrd的命令是mkinitrd -k vmlinuz-xxx但正常安装流程会自动处理不手动干预。3.3 配置引导加载器SUSE 15默认使用GRUB2作为引导加载器。新内核装好后GRUB配置文件里会新增一个menuentry但我一般会手动重新生成一次配置确保万无一失。grub2-mkconfig -o /boot/grub2/grub.cfg生成完之后可以确认新内核的菜单项存在grep -E menuentry|kernel-default /boot/grub2/grub.cfg如果这一步报错最常见的原因有两个一是/boot/grub2/grub.cfg路径不一样有些服务器做了软链接指向/boot/grub.cfg二是os-prober检测其他操作系统时出现异常。路径问题用ls -l /boot/grub2就能看出来如果是软链接就按链接指向的目标路径生成。另外除非你的机器用了传统BIOS引导而不是UEFI否则不需要执行grub2-install。SLES 15默认都是UEFI或者管理程序引导改配置文件就够。3.4 重启与新内核确认一切准备就绪后确认维护窗口内可以重启然后执行reboot重启之后系统默认会加载GRUB菜单最顶层的启动项也就是最新安装的内核。登录系统后第一件事就是确认当前运行的内核版本uname -r如果输出和你安装的目标版本一致那就成功了一大半。如果不一致可能原因有三个GRUB默认启动项仍是旧内核、刚安装的内核没有出现在菜单里、或者启动过程中直接回退到了旧内核这是某些配置下出现initrd问题时会发生的。接下来还要继续做系统状态检查这一部分我在第4节展开讲。4. 升级后的验证与业务回归4.1 内核版本确认三连查版本确认这种事光靠uname -r一条还不够。我习惯性要跑三连查uname -r cat /proc/version rpm -q kernel-default第一条看当前实际运行的内核第二条看内核编译信息里包含的gcc版本和时间戳第三条看已安装的RPM包版本。正常情况下三条信息指向的内核基线一致。如果rpm -q kernel-default显示的是新版本而uname -r显示旧版本说明重启后实际加载的还是旧内核这就必须查GRUB配置和启动日志了。出现这种情况的时候先看启动过程里有没有内核对initrd的处理失败journalctl -b -0 -k | grep -Ei error|fail|panic重点看有没有类似Failed to load module、No space left on device这类报错。很多时候旧内核还在运行是因为新内核的initrd生成不完整启动时直接跳过了新内核项。4.2 系统日志与驱动状态检查内核升级完之后驱动状态是重中之重。SLES 15默认仓库里的开源网卡驱动、存储驱动一般都能跟着内核一起编译进模块但第三方厂商提供的外置驱动就不一定了。检查当前加载的模块状态lsmod dmesg | tail -50 journalctl -b -0 | grep -Ei module|driver|firmware | tail -50lsmod看到的就是系统当前加载的内核模块列表重点看网卡、磁盘控制器、文件系统相关模块是否在列表里。dmesg里如果出现大量Module version mismatch或者Unknown symbol基本可以断定是某个第三方模块没跟上新内核这时候必须在升级前就准备好的模块版本对应方案里找答案。如果发现固件缺失检查/lib/firmware里对应文件是否存在。SUSE 15升级内核时一般会同时升级kernel-firmware包但如果机器上有非标准硬件可能需要单独确认固件包版本。4.3 业务应用回归测试清单系统层面没问题之后下一步是业务回归。这一步没有统一模板因为每个环境的业务形态差别太大但我建议至少把下面这些项目过一遍基础网络ping网关、ssh登录、DNS解析是否正常。文件系统挂载点是否全部成功挂载读写权限是否正常。关键服务数据库、消息队列、中间件进程是否全部处于运行状态。性能基线重点看CPU负载、内存使用率、IO wait是否和升级前在同一水平。应用日志抽样查看应用日志中有无异常报错、连接中断记录。回归测试的时间长短取决于业务复杂度但前四项至少应该在重启后一小时内完成。如果全部通过这台机器基本可以确认修复到位后续再让它稳定运行几天观察一下。5. 升级过程中的坑与排查技巧5.1 zypper依赖冲突SLES 15内核安装过程中最常见的报错就是依赖冲突表现为zypper提示某个包被另一个包替代或者需要降级才能满足依赖关系。我碰到的典型场景是机器上装了来自第三方源的内核模块包而该包只匹配旧内核新内核安装后触发依赖崩溃。zypper会直接拒绝继续执行。处理思路有两个方向。第一个方向是先检查是否有kernel-*相关的包被锁定zypper locks如果有临时解除锁定后重新安装。第二个方向是对于第三方模块包先通过zypper rm卸载旧的不兼容版本完成内核升级后再从厂商渠道获取支持新内核的模块包版本重新安装。不建议使用zypper up --allow-vendor-change --force-resolution这种强制变更的手段因为它可能把跟内核无关的包也全部换掉产生不可控风险。5.2 第三方内核模块失效内核从旧版升到新版API和ABI都可能发生变化第三方内核模块如果还是按旧内核编译的就会在启动时加载失败。最典型的表现是启动报Module XXX not found、驱动加载失败网络或存储功能异常。排查方法是用modinfo查询模块属性modinfo /lib/modules/$(uname -r)/kernel/drivers/xxx/xxx.ko 2/dev/null如果文件本身不存在说明模块原厂包的安装脚本没有针对新内核重新编译需要回到厂商官网下载新版本。如果是开源驱动确认kernel-devel和kernel-source包已安装到新版本再用make重新编译外部模块。所以在升级前我强烈建议先跟设备厂商确认硬件驱动对新内核的支持情况。如果是老设备厂商还没有适配新版内核那就不能盲目升级需要在漏洞修复需求和业务稳定性之间做一个权衡决策。5.3 回滚怎么启动到旧内核真遇到新内核起不来的情况回滚操作并不复杂但前提是你提前做好了备份。重启时进入GRUB界面选择Advanced options for SLES实际菜单名可能略有差异在里面会看到旧版本内核的menuentry选它启动即可。进系统之后如果希望把默认启动项重新指回旧内核可以用以下命令grub2-set-default SLES 15 SP5, with Linux 5.14.21-150000.58.1 grub2-mkconfig -o /boot/grub2/grub.cfg注意grub2-set-default参数必须和GRUB菜单里的menuentry名称完全一致否则不生效。建议先执行grep menuentry /boot/grub2/grub.cfg把菜单项原样复制出来再填到命令里。回滚成功之后新内核的RPM包还在系统里之后可以慢慢排查问题找到原因后再次尝试升级。5.4 常见问题速查表把这次升级过程中以及以往经验里典型的问题整理成一个速查表方便遇到类似情况时直接对照排查。现象可能原因处理方式zypper找不到目标内核包模块仓库未启用、订阅过期启用Basesystem模块刷新仓库/boot空间不足旧内核和initrd堆满分区清理旧内核包、zypper clean重启后内核版本没变化GRUB默认启动项未更新手动grub2-mkconfiggrub2-set-default新内核启动后网卡无法工作第三方网卡驱动未适配重装/升级第三方驱动包开机报Unknown symbol模块版本不匹配重新编译或卸载不兼容模块initrd生成失败dracut依赖缺失mkinitrd手动重建检查fstab登录后磁盘挂载丢失新内核下udev规则变化检查/etc/fstab重新挂载并保存配置系统升级后应用连接数下降内核网络参数被重置按需重新设置sysctl参数并持久化这张表不用死记关键是出现问题要先判断问题层级引导层问题看GRUB内核加载问题看journalctl模块问题看lsmod和dmesg业务层问题看应用日志。一层一层往下查比乱猜要快得多。6. 一点个人实操心得内核升级这种操作本质上是一道“风险评估题”而不只是“命令执行题”。命令翻来覆去就那么几条但真正决定一次升级成败的是升级前的判断和预案你有没有确认你的SP版本对应的修复内核版本你有没有留好/boot空间你有没有提前问清楚业务方能不能接受重启你有没有把旧内核启动项保留干净。我个人的经验是每次内核升级前都先把回滚步骤打印出来放在手边哪怕这个漏洞再危险也不要省略这一步。因为漏洞修复的前提是系统还能正常用如果为了修漏洞直接把系统搞趴下那修复本身就没有意义了。另外一个小技巧升级完成之后不要马上关掉维护窗口至少让系统稳定运行一两个小时确认日志里没有持续报错再把窗口关闭。内核漏洞修复讲究的是“稳”你已经把漏洞堵上了剩下的就是给系统一点时间证明自己真的稳得住。