Ubuntu 24.04 手动升级 Linux 内核至 7.0 完整教程
Ubuntu 24.04 LTS 服务器手动升级主线内核至 7.0,修复 CVE-2026-31431 高危漏洞。从 6.8.0-111-generic 升级至 7.0.0-15-generic 的完整操作记录,涵盖下载、安装、验证全流程。
一、背景:为什么需要升级内核
1.1 漏洞概述
2026 年 4 月 29 日,安全厂商 Theori 公开披露了 Linux 内核高危漏洞 CVE-2026-31431(代号 Copy Fail):
| 属性 | 详情 |
|---|---|
| CVE 编号 | CVE-2026-31431 |
| CVSS 评分 | 9.8(严重) |
| 漏洞类型 | 本地权限提升(Local Privilege Escalation) |
| 影响范围 | 2017 年 8 月至 2026 年 3 月之间的所有 Linux 内核 |
| 不受影响的最低版本 | 内核主线 7.0+、稳定版 6.18.22+、稳定版 6.19.12+ |
1.2 漏洞原理(简化说明)
漏洞存在于 Linux 内核加密子系统的 authencesn 模块中。攻击者通过以下方式利用:
- 创建 AF_ALG 套接字(内核提供的加密算法接口)
- 结合 splice() 系统调用(用于高效数据传输)
- 将目标文件的页缓存(Page Cache)引用暴露在可写的散列表中
- 实现对 setuid 程序(如
/usr/bin/su)页缓存的 4 字节越界写入 - 将普通用户提升为 root
关键特征:
- 利用代码仅 732 字节 Python 脚本
- 无需竞争条件,成功率接近 100%
- 仅修改内存中的页缓存,不修改磁盘文件,因此 md5sum/sha256sum 校验无法检测是否已被攻击
- 容器(Docker/Kubernetes)环境同样受影响,因为页缓存在宿主机与容器之间共享
1.3 影响评估
Ubuntu 24.04 LTS 默认内核 6.8.0-111 在受影响范围内。截至 2026 年 5 月,Ubuntu 官方仓库(除 26.04 LTS 外)尚未推送修复补丁,因此需要手动升级内核。
二、升级前准备
2.1 确认当前内核版本
uname -r
# 输出示例:6.8.0-111-generic(在受影响范围内)2.2 确认 /boot 分区空间
内核安装需要约 200MB 空间(包含内核镜像、initramfs、模块等),建议 /boot 至少有 1GB 可用空间。
df -h /boot
# Filesystem Size Used Avail Use% Mounted on
# /dev/sda2 2.0G 101M 1.7G 6% /boot2.3 清理旧内核(释放空间 + 减少干扰)
系统中可能积累了大量旧内核的残留配置文件(rc 状态),需要清理:
# 查看所有已安装的内核
dpkg --list | grep linux-image
# 查看残留配置文件(状态为 rc 的包)
dpkg --list | grep "^rc" | grep "linux"
# 一次性清除所有残留的旧内核配置
dpkg --list | grep "^rc" | grep "linux" | awk '{print $2}' | xargs sudo dpkg --purge 2>/dev/null说明:
dpkg中的包状态标记含义:
ii:已安装(正常)rc:已卸载,但残留配置文件iHR:安装异常(需要修复)
2.4 确认文件系统类型
本教程中的 run-parts 问题与 ZFS 无关,但确认一下可以避免后续踩坑:
df -Th / | tail -1
# /dev/mapper/ubuntu--vg-ubuntu--lv ext4 38G 14G 22G 40% /如果输出显示
zfs,则安装 modules 包时不会出现 ZFS 依赖问题(因为 ZFS 已在系统中)。如果显示ext4(绝大多数情况),modules 包会报 ZFS 依赖缺失,需要后续强制忽略。
三、查找可用的主线内核
3.1 为什么选择阿里云镜像
国内服务器通常无法直接访问 kernel.ubuntu.com(Ubuntu 官方主线内核仓库),但可以访问国内镜像站。阿里云镜像同步了 Ubuntu 官方仓库中的所有内核包。
3.2 搜索可用的 7.0 内核包
curl -s http://mirrors.aliyun.com/ubuntu/pool/main/l/linux/ \
| grep -oP 'href="\K[^"]*7\.0\.0[^"]*\.deb' \
| grep -v "64k\|arm64\|dbg\|cloud" \
| sort -u命令解释:
curl -s:静默模式获取网页内容grep -oP 'href="\K[^"]*7\.0\.0[^"]*\.deb':提取所有包含7.0.0的 .deb 文件链接grep -v "64k\|arm64\|dbg\|cloud":排除 64K 页内核、ARM 架构、调试包、云专用包sort -u:排序去重
输出示例(截取关键部分):
linux-headers-7.0.0-15_7.0.0-15.15_all.deb
linux-headers-7.0.0-15-generic_7.0.0-15.15_amd64.deb
linux-image-unsigned-7.0.0-15-generic_7.0.0-15.15_amd64.deb
linux-modules-7.0.0-15-generic_7.0.0-15.15_amd64.deb3.3 确认需要下载的 4 个核心包
| 包名 | 用途 | 大小(约) |
|---|---|---|
linux-headers-7.0.0-15_7.0.0-15.15_all.deb | 内核头文件(通用,跨架构) | 15M |
linux-headers-7.0.0-15-generic_7.0.0-15.15_amd64.deb | 内核头文件(amd64 架构) | 4M |
linux-image-unsigned-7.0.0-15-generic_7.0.0-15.15_amd64.deb | 内核镜像(vmlinuz) | 17M |
linux-modules-7.0.0-15-generic_7.0.0-15.15_amd64.deb | 内核模块(驱动、文件系统等) | 162M |
四、下载内核包
# 创建临时目录
mkdir -p /tmp/kernel && cd /tmp/kernel
# 下载 4 个核心包
wget http://mirrors.aliyun.com/ubuntu/pool/main/l/linux/linux-headers-7.0.0-15_7.0.0-15.15_all.deb
wget http://mirrors.aliyun.com/ubuntu/pool/main/l/linux/linux-headers-7.0.0-15-generic_7.0.0-15.15_amd64.deb
wget http://mirrors.aliyun.com/ubuntu/pool/main/l/linux/linux-image-unsigned-7.0.0-15-generic_7.0.0-15.15_amd64.deb
wget http://mirrors.aliyun.com/ubuntu/pool/main/l/linux/linux-modules-7.0.0-15-generic_7.0.0-15.15_amd64.deb
# 确认下载完整
ls -lh /tmp/kernel/五、安装内核包
5.1 安装 Headers 包(通常无问题)
cd /tmp/kernel
sudo dpkg -i linux-headers-7.0.0-15_7.0.0-15.15_all.deb
sudo dpkg -i linux-headers-7.0.0-15-generic_7.0.0-15.15_amd64.deb说明:Headers 包包含内核编译所需的头文件,是编译第三方模块(如 NVIDIA 驱动)的必要依赖。这两个包通常不会有问题。
5.2 安装 Modules 包(ZFS 依赖问题 — 修复并重打包)
sudo dpkg -i linux-modules-7.0.0-15-generic_7.0.0-15.15_amd64.deb可能遇到的报错:
dpkg: dependency problems prevent configuration of linux-modules-7.0.0-15-generic:
linux-modules-7.0.0-15-generic depends on linux-main-modules-zfs-7.0.0-15-generic; however:
Package linux-main-modules-zfs-7.0.0-15-generic is not installed.原因分析:
Ubuntu 官方内核包默认依赖 ZFS 模块(linux-main-modules-zfs)。如果系统使用 ext4 文件系统(绝大多数情况),这个依赖是不必要的。同时,该 ZFS 包在主线内核仓库中可能根本不存在,导致 dpkg --force-depends 虽然能绕过 dpkg 层面的检查,但 apt 的依赖数据库仍会记录这个未满足的依赖,导致后续 apt update / apt upgrade 报错。
解决方案:移除依赖声明并重新打包 deb 包
不建议使用
dpkg --force-depends强制跳过,因为这只能骗过 dpkg,无法骗过 apt,会为后续系统更新埋下隐患。
# --- 步骤 A:解包 deb 并查看依赖 ---
mkdir -p /tmp/fix-dep && cd /tmp/fix-dep
ar x /tmp/kernel/linux-modules-7.0.0-15-generic_7.0.0-15.15_amd64.deb
mkdir ctrl && cd ctrl
tar xf ../control.tar
# 查看当前依赖声明
grep -i "^Depends" control
# 输出示例:
# Depends: linux-image-7.0.0-15-generic (= 7.0.0-15.15), linux-main-modules-zfs-7.0.0-15-generic (>= 7.0.0-15.15), wireless-regdb
# --- 步骤 B:编辑 control 文件,移除 ZFS 依赖 ---
sed -i 's/, linux-main-modules-zfs-7.0.0-15-generic[^,)]*//g' control
sed -i 's/linux-main-modules-zfs-7.0.0-15-generic[^,)]*,\s*//g' control
sed -i 's/linux-main-modules-zfs-7.0.0-15-generic[^)]*//g' control
# 确认修改结果(ZFS 依赖已消失)
grep -i "^Depends" control
# 输出示例:
# Depends: wireless-regdb
# --- 步骤 C:重新打包 ---
cd /tmp/fix-dep
tar cf control.tar --owner=0 --group=0 -C ctrl .
ar rcs linux-modules-fixed.deb debian-binary control.tar data.tar
# --- 步骤 D:清除旧包状态并安装修复后的包 ---
sudo dpkg --purge --force-all --force-scripts linux-modules-7.0.0-15-generic
sudo dpkg -i linux-modules-fixed.deb优势:与
--force-depends不同,此方法从根源上移除了不存在的依赖声明,apt 和 dpkg 层面都不会再报错,后续系统更新不会受影响。
重要提醒:与修复 image 包时一样,
ar x解包 deb 后会在当前目录生成data.tar。如果在同一个目录中解包多个 deb 包,后解包的会覆盖前面的data.tar。务必在不同目录中解包不同的 deb 包。
5.3 安装 Image 包(run-parts 报错 — 关键异常点)
sudo dpkg -i linux-image-unsigned-7.0.0-15-generic_7.0.0-15.15_amd64.deb报错输出:
Preparing to unpack .../linux-image-unsigned-7.0.0-15-generic_7.0.0-15.15_amd64.deb ...
run-parts: missing operand
Try `run-parts --help' for more information.
dpkg: error processing archive ... (--install):
new linux-image-unsigned-7.0.0-15-generic package pre-installation script subprocess returned error exit status 1
run-parts: missing operand
Try `run-parts --help' for more information.
dpkg: error while cleaning up:
new linux-image-unsigned-7.0.0-15-generic package post-removal script subprocess returned error exit status 1
Errors were encountered while processing:
...linux-image-unsigned-7.0.0-15-generic_7.0.0-15.15_amd64.deb原因分析:
run-parts 是 Debian/Ubuntu 系统中用于按顺序执行指定目录下所有脚本的工具。主线内核 deb 包中的 preinst(安装前)和 postrm(卸载后)脚本在调用 run-parts 时未正确传递目录参数,导致报错。这个问题在直接从主线仓库下载的 deb 包上较为常见,因为这些包的脚本主要针对标准发布版本的目录结构编写。
解决方案:三步走
由于 dpkg 安装脚本失败,需要:
- 手动提取内核文件到系统目录
- 重建修复后的 deb 包(替换有问题的安装脚本)
- 让 dpkg 正确注册包状态
步骤 A:手动提取内核镜像到 /boot
由于 dpkg 无法正常安装,我们需要手动将内核镜像文件提取到正确位置:
# 创建临时目录用于解包
mkdir -p /tmp/image && cd /tmp/image
# 从 deb 包中解包(ar 是 Debian 归档工具)
ar x /tmp/kernel/linux-image-unsigned-7.0.0-15-generic_7.0.0-15.15_amd64.deb
# 查看 data.tar 中的文件列表
tar -tf data.tar
# 输出:
# ./
# ./boot/
# ./boot/vmlinuz-7.0.0-15-generic ← 这就是内核镜像
# ./usr/...
# 提取到系统根目录
sudo tar -xf data.tar -C /
# 确认内核镜像到位
ls -lh /boot/vmlinuz-7.0.0-15-generic
# -rw------- 1 root root 17M ... /boot/vmlinuz-7.0.0-15-generic重要提醒:
ar x解包 deb 后会在当前目录生成data.tar。如果在同一个目录中解包多个 deb 包,后解包的会覆盖前面的data.tar。务必在不同目录中解包不同的 deb 包。
步骤 B:重建修复后的 deb 包
为了让 dpkg 正确注册包状态(避免 dpkg --audit 报错和阻塞 apt install),需要修复 deb 包中有问题的安装脚本,然后重新安装。
# 1. 重新下载 image 包(确保干净的源文件)
wget -q http://mirrors.aliyun.com/ubuntu/pool/main/l/linux/linux-image-unsigned-7.0.0-15-generic_7.0.0-15.15_amd64.deb \
-O /tmp/linux-image.deb
# 2. 创建重建工作目录
mkdir -p /tmp/rebuild && cd /tmp/rebuild
# 3. 解包 deb(ar 会解出 debian-binary、control.tar、data.tar)
ar x /tmp/linux-image.deb
# 4. 解包 control.tar(包含元数据和安装脚本)
mkdir ctrl && cd ctrl && tar xf ../control.tar
# 5. 查看控制目录中的脚本文件
ls -la
# 会看到:preinst、postinst、postrm 等脚本
# 6. 用安全的空脚本替换所有有问题的安装脚本
# preinst(安装前脚本)
cat > preinst << 'EOF'
#!/bin/sh
exit 0
EOF
chmod +x preinst
# postinst(安装后脚本)
cat > postinst << 'EOF'
#!/bin/sh
exit 0
EOF
chmod +x postinst
# postrm(卸载后脚本)
cat > postrm << 'EOF'
#!/bin/sh
exit 0
EOF
chmod +x postrm
# 7. 确认三个脚本都已替换
ls -la preinst postinst postrm
# 8. 重新打包 control.tar(回到 rebuild 目录)
cd /tmp/rebuild
tar cf control.tar --owner=0 --group=0 -C ctrl .
# 9. 重新构建 deb 包(ar rcs 会覆盖原文件)
ar rcs /tmp/linux-image-fixed.deb debian-binary control.tar data.tar脚本替换说明:
preinst:安装前执行,用于检查和准备。原始脚本调用run-parts报错。postinst:安装后执行,用于配置和触发。原始脚本调用run-parts报错。postrm:卸载后执行,用于清理。原始脚本调用run-parts报错。- 将它们替换为空脚本(直接
exit 0)不会影响内核的正常运行,因为这些脚本主要用于触发 initramfs 更新和 GRUB 更新,我们将手动执行这些操作。
步骤 C:清除旧包状态并安装修复后的包
# 清除之前失败安装留下的损坏包状态
# --force-all:忽略所有强制检查
# --force-scripts:跳过所有安装/卸载脚本的执行
sudo dpkg --purge --force-all --force-scripts linux-image-unsigned-7.0.0-15-generic
# 安装修复后的 deb 包
sudo dpkg -i /tmp/linux-image-fixed.deb为什么需要
--force-scripts: 即使原始的preinst脚本有问题,dpkg 在卸载(purge)时仍会尝试执行它。--force-scripts跳过脚本执行,避免再次触发run-parts错误。
六、生成 initramfs 和更新 GRUB
6.1 生成 initramfs
sudo update-initramfs -c -k 7.0.0-15-generic
# update-initramfs: Generating /boot/initrd.img-7.0.0-15-generic什么是 initramfs: initramfs(Initial RAM Filesystem)是一个临时的根文件系统,在 Linux 启动早期加载到内存中。它包含了挂载真正根文件系统所需的驱动和工具(如 LVM、RAID、文件系统驱动等)。没有 initramfs,内核可能无法找到和挂载根分区。
-c参数表示创建新的 initramfs(而非更新已有的)。-k参数指定为哪个内核版本生成。
6.2 更新 GRUB 引导配置
sudo update-grub输出中应包含:
Found linux image: /boot/vmlinuz-7.0.0-15-generic
Found initrd image: /boot/initrd.img-7.0.0-15-generic
Found linux image: /boot/vmlinuz-6.8.0-111-generic
Found initrd image: /boot/initrd.img-6.8.0-111-genericGRUB(GRand Unified Bootloader) 是 Linux 系统的引导加载程序。
update-grub会扫描/boot目录中的所有内核镜像,自动生成引导菜单配置。新安装的 7.0 内核会自动出现在菜单中。
6.3 确认 GRUB 默认启动项
grep "menuentry" /boot/grub/grub.cfg | grep "linux"GRUB 菜单结构示例:
0 → Ubuntu(默认,指向菜单第一项)
└── Advanced options for Ubuntu
├── 0 → Ubuntu, with Linux 7.0.0-15-generic
├── 1 → Ubuntu, with Linux 7.0.0-15-generic (recovery mode)
├── 2 → Ubuntu, with Linux 6.8.0-111-generic
└── 3 → Ubuntu, with Linux 6.8.0-111-generic (recovery mode)确保 GRUB_DEFAULT=0(默认启动第一项,即 7.0 内核):
# 检查当前 GRUB 默认值
grep GRUB_DEFAULT /etc/default/grub
# 如果不是 0,修改为 0
sudo sed -i 's/^GRUB_DEFAULT=.*/GRUB_DEFAULT=0/' /etc/default/grub
sudo update-grub七、重启并验证
sudo reboot重启后执行以下验证命令:
# 1. 确认内核版本
uname -r
# 期望输出:7.0.0-15-generic
# 2. 确认 algif_aead 模块未加载
lsmod | grep algif_aead
# 无输出 = 正常
# 3. 确认系统文件系统正常
df -Th /
# Filesystem Type Size Used Avail Use% Mounted on
# /dev/mapper/ubuntu--vg-ubuntu--lv ext4 38G 14G 22G 39% /
# 4. 确认 Ubuntu 版本
lsb_release -a
# Description: Ubuntu 24.04.4 LTS
# 5. 确认 dpkg 包状态无损坏
dpkg --audit 2>&1
# 无输出 = 正常
# 6. 确认 apt 工作正常
sudo apt update八、善后操作
8.1 设置 algif_aead 模块禁用(双重保险)
虽然 7.0 内核不受 CVE-2026-31431 影响,但禁用 algif_aead 模块作为额外防护层是良好的安全实践:
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf原理:
/etc/modprobe.d/目录下的.conf文件用于配置内核模块的加载行为。install <模块名> /bin/false告诉 modprobe 在尝试加载该模块时执行/bin/false(一个立即返回失败的程序),从而阻止模块加载。影响范围:禁用
algif_aead不会影响 dm-crypt/LUKS(磁盘加密)、IPsec、SSH 或 OpenSSL 的默认构建等标准加密服务。
8.2 清理临时文件
rm -rf /tmp/kernel /tmp/image /tmp/rebuild /tmp/linux-image.deb /tmp/linux-image-fixed.deb8.3 确认 GRUB 保留回退内核
# 确认 6.8 内核仍在 GRUB 中
grep "6.8.0-111" /boot/grub/grub.cfg保留 6.8.0-111 作为回退内核,万一 7.0 出现兼容性问题,可以在 GRUB 菜单中选择旧内核启动。
8.4 (可选)隐藏 GRUB 菜单
如果不需要在启动时看到 GRUB 菜单(正常启动直接进入系统):
sudo sed -i 's/GRUB_TIMEOUT_STYLE=menu/GRUB_TIMEOUT_STYLE=hidden/' /etc/default/grub
sudo sed -i 's/GRUB_TIMEOUT=5/GRUB_TIMEOUT=0/' /etc/default/grub
sudo update-grub提示:如果想保留 GRUB 菜单以便在出问题时手动选择内核,可以跳过此步骤。
九、回退方案
9.1 重启时手动选择旧内核
重启时在 GRUB 菜单中:
- 选择 Advanced options for Ubuntu
- 选择 Ubuntu, with Linux 6.8.0-111-generic
9.2 临时显示 GRUB 菜单
如果 GRUB 菜单被隐藏了,重启时按住 Shift 或 Esc 可以强制显示。
或者永久显示:
sudo sed -i 's/GRUB_TIMEOUT_STYLE=hidden/GRUB_TIMEOUT_STYLE=menu/' /etc/default/grub
sudo sed -i 's/GRUB_TIMEOUT=0/GRUB_TIMEOUT=5/' /etc/default/grub
sudo update-grub
sudo reboot9.3 完全卸载 7.0 内核(回到 6.8)
# 确保当前不在 7.0 内核上运行(需要先用 6.8 内核启动)
# 卸载 7.0 相关包
sudo dpkg --purge --force-all --force-scripts linux-image-unsigned-7.0.0-15-generic
sudo dpkg --purge linux-modules-7.0.0-15-generic
sudo dpkg --purge linux-headers-7.0.0-15-generic linux-headers-7.0.0-15
# 清理 /boot 中的 7.0 文件
sudo rm -f /boot/vmlinuz-7.0.0-15-generic /boot/initrd.img-7.0.0-15-generic
sudo rm -rf /lib/modules/7.0.0-15-generic
# 更新 GRUB
sudo update-grub
# 重启
sudo reboot十、后续内核升级
7.0 内核不在 Ubuntu 官方包管理中,后续需要手动升级时,重复以下流程:
# 1. 查找新版本
curl -s http://mirrors.aliyun.com/ubuntu/pool/main/l/linux/ \
| grep -oP 'href="\K[^"]*7\.[0-9]+\.[0-9]+[^"]*\.deb' \
| grep -v "64k\|arm64\|dbg\|cloud" \
| sort -u
# 2. 下载新版本的 4 个包(以新版本号替换)
# 3. 安装 headers(通常无问题)
sudo dpkg -i linux-headers-*.deb
# 4. 安装 modules(忽略 ZFS 依赖)
sudo dpkg --force-depends -i linux-modules-*.deb
# 5. 手动提取 image 到 /boot
mkdir -p /tmp/newimage && cd /tmp/newimage
ar x /path/to/linux-image-unsigned-xxx.deb
sudo tar -xf data.tar -C /
# 6. 生成 initramfs
sudo update-initramfs -c -k <新版本号>-generic
# 7. 更新 GRUB
sudo update-grub
# 8. 重启
sudo reboot十一、关键异常点总结
| 异常 | 原因 | 解决方案 |
|---|---|---|
| modules 包报 ZFS 依赖缺失 | Ubuntu 内核包默认依赖 ZFS 模块,ext4 系统不需要 | sudo dpkg --force-depends -i |
image 包报 run-parts: missing operand | 主线内核 deb 包的安装脚本与系统 run-parts 不兼容 | 手动提取内核文件 + 修复 deb 包安装脚本 |
apt --fix-broken install 报找不到 archive | dpkg 中注册了包但文件不完整 | sudo dpkg --purge --force-all --force-scripts 清除后重装 |
卸载当前运行内核报 Aborting removal | dpkg 不允许卸载当前正在运行的内核 | 先重启切换到其他内核,再卸载 |
dpkg --audit 报包状态损坏 | 安装脚本失败导致包注册不完整 | 重建修复后的 deb 包并重新安装 |
十二、参考资源
- CVE-2026-31431 官方公告:https://ubuntu.com/security/CVE-2026-31431
- Ubuntu 主线内核仓库:https://kernel.ubuntu.com/mainline/
- 阿里云 Ubuntu 镜像:http://mirrors.aliyun.com/ubuntu/
- Linux 内核官方:https://www.kernel.org/
最后更新:2026 年 5 月 3 日
测试环境:Ubuntu 24.04.4 LTS (noble) / amd64 / ext4 on LVM
本文章已被查看 0 次