- 操作系统
- 云原生
- 容器运行时
【免费下载链接】linuxkit
A toolkit for building secure, portable and lean operating systems for containers
导读:本文以 projects/kspp/README.md 为骨架,系统梳理 LinuxKit(Moby 项目衍生)如何落实内核自防护项目(KSPP)的加固思路——从 KSPP 的社区背景与 Roadmap,到仓库内真实可查的
kernel_config/sysctl 落地清单,再到 CI 中用于强制校验的check-kernel-config.sh测试脚本及其调用链。读完本文,你将掌握:KSPP 推荐设置具体落在哪些内核选项与 sysctl 参数上、这些选项在 LinuxKit 各内核版本配置中的实际形态、以及如何自行复用这套配置与测试来加固自己的容器内核。
一、背景:什么是 KSPP,为什么 LinuxKit 要跟进
KSPP(Kernel Self Protection Project,内核自防护项目)是一个社区协作项目,目标是通过消除整类漏洞(classes of vulnerabilities)来加固上游 Linux 内核,而非逐个修补具体 CVE。其 wiki 维护着一份"推荐设置"清单(Recommended settings),涵盖编译期内核选项(Kconfig)与运行时 sysctl 参数。
LinuxKit 之所以主动对齐这套推荐设置,原因写在 README 中:Moby 是 Linux 内核的消费方,并且"aims to be the most secure distro it can be"。许多类似防护在其他项目中早已存在,但尚未被合入上游;作为上游 Linux 安全加固工作的直接受益者与协作者,LinuxKit 维护者选择把 KSPP 的推荐项固化进自己的内核配置。
事实依据:以上表述均出自 projects/kspp/README.md;KSPP 与推荐设置的原始出处为 kernsec.org 社区 wiki(README 中给出的外链),本文不转述其外部细节,仅聚焦本仓库内的落地证据。
二、LinuxKit 的 KSPP Roadmap
README 将 LinuxKit 的 KSPP 参与计划分为两个阶段:
- 短期(Near-term):
- 已将
kernel_config和sysctl设置与 KSPP 推荐设置对齐,且持续跟踪这些推荐的演进; - 在 CI 测试中检查这些设置是否生效——即 test/pkg/kernel-config/check-kernel-config.sh;
- 由 @tych0 牵头向 kernel-hardening 邮件列表提交 KSPP 补丁。
- 已将
- 长期(Long-term):提高对 KSPP 社区的参与度(增加贡献)。
这段 Roadmap 虽短,但"对齐配置 + CI 校验"这两条承诺在仓库中都有可验证的落地:配置侧见 kernel/ 下各版本config-*文件与 pkg/sysctl/etc/sysctl.d/00-linuxkit.conf,校验侧见 test/pkg/kernel-config/ 测试套件。
三、配置侧落地一:内核编译期选项(Kconfig)
3.1 基础完整性检查(所有架构、所有版本)
KSPP 推荐设置强调"内存破坏类漏洞"的防御。以 kernel/6.6.x/config-x86_64 为例,可确认以下选项均为=y:
| 配置项 | 作用 | 6.6.x x86_64 证据 |
|---|---|---|
CONFIG_BUG=y | 内核 BUG 处理基础设施 | 第 248 行 |
CONFIG_DEBUG_KERNEL=y | 打开内核调试选项门类 | 第 4863 行 |
CONFIG_STRICT_DEVMEM=y | 限制对 /dev/mem 的访问 | 第 5148 行 |
CONFIG_IO_STRICT_DEVMEM=y | 进一步限制对 MMIO 区域的访问 | 第 5149 行 |
CONFIG_SYN_COOKIES=y | TCP SYN cookies 抗 SYN 洪泛 | 第 1114 行 |
CONFIG_DEBUG_NOTIFIERS=y | notifier 链调试 | 第 5046 行 |
CONFIG_DEBUG_LIST=y | 链表完整性校验(防双重释放/破坏) | 第 5043 行 |
CONFIG_PANIC_ON_OOPS=y | Oops 即 panic,防止继续运行在已破坏状态 | 第 4980 行 |
CONFIG_BUG_ON_DATA_CORRUPTION=y | 检测到数据破坏立即 BUG | 第 4438 行 |
CONFIG_GENERIC_CPU_VULNERABILITIES=y | 统一的 CPU 漏洞(幽灵/熔断等)暴露接口 | 第 1832 行 |
3.2 内存与栈防护(按内核版本条件启用)
KSPP 的很多推荐项依赖内核版本(某些选项在旧内核尚未引入,或在 5.11+ 被重命名/合并)。LinuxKit 的测试脚本对此做了按版本分支,而各版本 config 文件也确实同步演进:
- 栈保护:4.18 之前为
CONFIG_CC_STACKPROTECTOR_STRONG=y,4.18+ 重命名为CONFIG_STACKPROTECTOR=y+CONFIG_STACKPROTECTOR_STRONG=y(kernel/6.6.x/config-x86_64 第 764-765 行)。 - 用户拷贝加固:
CONFIG_HARDENED_USERCOPY=y(kernel/6.6.x/config-aarch64 第 4743 行),4.8+ 引入。 - 内核/模块 RXW 分区:
CONFIG_STRICT_KERNEL_RWX=y、CONFIG_STRICT_MODULE_RWX=y(4.11+,kernel/6.6.x/config-x86_64 第 814、816 行),阻止内核页同时可写可执行。 - 页毒化:
CONFIG_PAGE_POISONING=y(4.9+,kernel/6.6.x/config-x86_64 第 4941 行),其子选项CONFIG_PAGE_POISONING_NO_SANITY/CONFIG_PAGE_POISONING_ZERO在 5.11+ 被移除。 - slab 随机化:
CONFIG_SLAB_FREELIST_RANDOM=y(4.7+,kernel/6.6.x/config-x86_64 第 971 行)。 - UBSan 未定义行为检测:
CONFIG_UBSAN=y(4.5+,kernel/6.6.x/config-aarch64 第 5302 行)。 - 凭据调试:
CONFIG_DEBUG_CREDENTIALS=y(6.x 之前)。 - 地址随机化:
CONFIG_RANDOMIZE_BASE=y(KASLR,4.5+,kernel/6.6.x/config-x86_64 第 467 行);x86_64 上另有CONFIG_RANDOMIZE_MEMORY=y(4.8+,第 471 行)。
3.3 架构相关加固(x86_64)
CONFIG_LEGACY_VSYSCALL_NONE=y:彻底禁用旧式 vsyscall 映射(kernel/6.6.x/config-x86_64 第 476 行),是 KSPP 负向清单中的重点。- 页表隔离与 Retpoline:6.11 及以前为
CONFIG_PAGE_TABLE_ISOLATION=y+CONFIG_RETPOLINE=y(第 493-494 行);6.12+ 重命名为CONFIG_MITIGATION_PAGE_TABLE_ISOLATION/CONFIG_MITIGATION_RETPOLINE,测试脚本同样做了版本分支(见下文)。
3.4 负向清单(必须"is not set")
KSPP 推荐不仅要求某些选项开启,还要求关闭一批高风险功能。在 kernel/6.6.x/config-x86_64 中对应为:
# CONFIG_COMPAT_BRK is not set(第 979 行):禁止堆地址随机化兼容性豁免;# CONFIG_KEXEC is not set(第 291 行):禁用 kexec 动态加载内核;# CONFIG_HIBERNATION is not set(第 513 行):禁用休眠(避免镜像投毒面);# CONFIG_MODIFY_LDT_SYSCALL is not set(第 478 行);# CONFIG_X86_X32_ABI is not set(第 647 行):禁用 x32 ABI(6.x 起改名,旧版为CONFIG_X86_X32);# CONFIG_DEVKMEM is not set(5.13 之前的内核):禁用 /dev/kmem。
四、配置侧落地二:运行时 sysctl 参数
编译期选项之外,KSPP 推荐还包括运行时内核参数。LinuxKit 将这些参数固化在 pkg/sysctl/etc/sysctl.d/00-linuxkit.conf,随 sysctl 包在启动早期应用。其中与安全强相关的条目:
| sysctl 参数 | 值 | 含义 |
|---|---|---|
kernel.kptr_restrict | 2 | 限制内核指针在 /proc/kallsyms 等处的暴露 |
kernel.dmesg_restrict | 1 | 仅特权进程可读 dmesg |
kernel.perf_event_paranoid | 3 | 严格限制 perf 事件(防侧信道/提权探测) |
kernel.unprivileged_bpf_disabled | 1 | 禁止非特权 eBPF(防提权,注释引用了 LWN 相关讨论) |
net.ipv4.tcp_syncookies | 1 | 与内核CONFIG_SYN_COOKIES=y配合 |
net.ipv4.conf.all/default.rp_filter | 1 | 反源地址欺骗 |
net.ipv4.conf.*.accept_redirects/accept_source_route | 0 | 关闭路由重定向/源路由 |
fs.protected_hardlinks/fs.protected_symlinks | 1 | 防硬链接/符号链接提权 |
这些条目共同构成 KSPP 推荐设置中"运行时"那一半,也印证了 README 中"aligned ourkernel_configandsysctlsettings with the KSPP recommendations"的说法。
五、CI 强制校验:check-kernel-config.sh 的完整逻辑
5.1 调用入口与镜像组装
README 提到的 CI 检查,实现在 test/pkg/kernel-config/check-kernel-config.sh,入口包装在 test/pkg/kernel-config/check.sh。测试镜像由 test/pkg/kernel-config/Dockerfile 构建:基于linuxkit/alpine基础镜像,额外拉取 moby 的contrib/check-config.sh(固定 commit38005cfc12...)用于 5.x 之前内核的兼容性检查,最终产物以scratch镜像形式运行,ENTRYPOINT为check.sh。
在 CI 编排中,该测试作为onboot阶段服务运行,见 test/hack/test.yml 第 14-15 行:
onboot: - name: check-kernel-config image: linuxkit/test-kernel-config:75b54d40268141d966b0c820e184981d3a30fac0测试镜像通过 Dockerfile 中的 LABEL("readonly": true、binds/lib/modules、/dev、/sys、capabilitiesall)获得读取宿主/被测内核配置与加载模块的权限。
5.2 配置来源与版本/架构探测
脚本开头的关键设计:
if [ -n "$1" ]; then UNZIPPED_CONFIG=$(cat "$1") # 显式传入配置文件 else UNZIPPED_CONFIG=$(zcat /proc/config.gz) # 默认读取运行中内核的 /proc/config.gz fi即默认从运行中的内核读取配置(/proc/config.gz),也支持把某个config-*文件作为参数传入做离线校验;同时解析uname -r得到kernelMajor/kernelMinor,用uname -m得到架构,以便做版本与架构分支判断。
5.3 正向断言:必须为=y
脚本逐条grep断言(任一条不满足即fail并最终退出码 1):
- 基础项(全版本):
CONFIG_BUG、CONFIG_DEBUG_KERNEL、CONFIG_STRICT_DEVMEM、CONFIG_SYN_COOKIES、CONFIG_DEBUG_NOTIFIERS、CONFIG_DEBUG_LIST、CONFIG_SECCOMP、CONFIG_SECCOMP_FILTER、CONFIG_SECURITY、CONFIG_SECURITY_YAMA、CONFIG_PANIC_ON_OOPS、CONFIG_BPF_JIT_ALWAYS_ON。 - 版本条件项:
< 6:CONFIG_DEBUG_CREDENTIALS;4.x ≤ 4.10:CONFIG_DEBUG_RODATA、CONFIG_DEBUG_SET_MODULE_RONX(旧命名);5.x或4.x ≥ 4.5:CONFIG_UBSAN;≥ 4.7:CONFIG_SLAB_FREELIST_RANDOM;≥ 4.8:CONFIG_HARDENED_USERCOPY;≥ 4.9:CONFIG_PAGE_POISONING(及其在 < 5.11 时的两个子选项);≥ 4.10:CONFIG_BUG_ON_DATA_CORRUPTION;≥ 4.11:CONFIG_STRICT_KERNEL_RWX/CONFIG_STRICT_MODULE_RWX;≥ 4.5:CONFIG_RANDOMIZE_BASE;- 栈保护新旧命名分支:≥ 4.18 断言
CONFIG_STACKPROTECTOR/CONFIG_STACKPROTECTOR_STRONG,否则断言CONFIG_CC_STACKPROTECTOR_STRONG; - x86_64 分支:
CONFIG_LEGACY_VSYSCALL_NONE、CONFIG_GENERIC_CPU_VULNERABILITIES、≥ 4.5 的CONFIG_IO_STRICT_DEVMEM、≥ 4.8 的CONFIG_RANDOMIZE_MEMORY,以及 6.12 前后的CONFIG_PAGE_TABLE_ISOLATION/CONFIG_RETPOLINE与CONFIG_MITIGATION_*新旧命名分支。
5.4 负向断言:必须"is not set"
- 全版本:
CONFIG_COMPAT_BRK、CONFIG_SCSI_PROC_FS必须关闭; - x86_64:
CONFIG_COMPAT_VDSO、CONFIG_KEXEC、CONFIG_MODIFY_LDT_SYSCALL必须关闭;≥ 4.5 时CONFIG_LEGACY_PTYS、CONFIG_HIBERNATION必须关闭;< 5.13 时CONFIG_DEVKMEM必须关闭;6.x 前后分别断言CONFIG_X86_X32与CONFIG_X86_X32_ABI关闭;< 6.12 时CONFIG_ACPI_CUSTOM_METHOD关闭。
5.5 运行期行为校验
配置检查之外,脚本还做了两类运行期验证:
- 模块加载冒烟:依次
modprobe nfs nfsd,并按版本modprobe ntfs(< 6.12)或ntfs3(≥ 6.12),验证内核模块子系统可用; - 内建文件系统清单:遍历
sysfs tmpfs bdev proc cgroup devtmpfs binfmt_misc debugfs tracefs securityfs sockfs bpf pipefs ramfs hugetlbfs rpc_pipefs devpts ext4 vfat msdos iso9660 nfs nfs4 nfsd cifs fuseblk fuse fusectl overlay udf xfs 9p pstore mqueue等,逐一在/proc/filesystems中确认存在,保证容器运行时所需的文件系统全部内建或可加载。
全部通过后输出kernel config test succeeded!,否则输出kernel config test failed!并exit 1,从而在 CI 中让加固配置"回退即失败"。
六、如何复用这套 KSPP 加固流程
6.1 离线校验任意内核配置
不启动虚拟机,直接对仓库内的 config 文件运行测试脚本:
# 以 6.6.x 的 x86_64 配置为例 ./test/pkg/kernel-config/check-kernel-config.sh kernel/6.6.x/config-x86_64 6.6.0脚本支持第二个参数传入内核版本字符串,用于触发对应的版本分支断言(如 6.12 前后的CONFIG_MITIGATION_*新旧命名判断)。
6.2 在 LinuxKit 镜像内运行时校验
按 test/hack/test.yml 的模式,在onboot阶段加入check-kernel-config服务;或直接构建 test/pkg/kernel-config/Dockerfile 的镜像,由其check.sh依次执行check-kernel-config.sh与(5.x 以下内核的)mobycheck-config.sh。
6.3 把 KSPP 推荐固化进自己的构建
- 编译期:参考 kernel/ 下
config-*文件中的 KSPP 正向/负向清单(尤其CONFIG_HARDENED_USERCOPY、CONFIG_STRICT_KERNEL_RWX、CONFIG_PAGE_POISONING、CONFIG_STACKPROTECTOR_STRONG、CONFIG_PANIC_ON_OOPS与负向的COMPAT_BRK、KEXEC、HIBERNATION); - 运行期:直接复用 pkg/sysctl/etc/sysctl.d/00-linuxkit.conf(
kptr_restrict=2、dmesg_restrict=1、perf_event_paranoid=3、unprivileged_bpf_disabled=1等),或按其格式扩展自己的 sysctl 文件。
七、小结
从 projects/kspp/README.md 的 Roadmap 出发,LinuxKit 对 KSPP 的参与形成了闭环:编译期内核配置(kernel/ 各config-*)落实静态加固,运行期 sysctl(pkg/sysctl/etc/sysctl.d/00-linuxkit.conf)落实动态加固,而CI 测试(test/pkg/kernel-config/check-kernel-config.sh + test/hack/test.yml)保证这些设置在任何一次内核变更中都不会悄然回退。对希望构建"默认安全"容器内核的团队,这套"推荐设置清单 + 自动断言 + 版本兼容分支"的组合本身就是一份可直接移植的最佳实践模板。
关键路径速查
- 关联文档:projects/kspp/README.md
- 内核配置:kernel/6.6.x/config-x86_64、kernel/6.6.x/config-aarch64(其余版本见 kernel/)
- sysctl:pkg/sysctl/etc/sysctl.d/00-linuxkit.conf
- 校验脚本:test/pkg/kernel-config/check-kernel-config.sh、test/pkg/kernel-config/check.sh、test/pkg/kernel-config/Dockerfile
- CI 编排:test/hack/test.yml
- 操作系统
- 云原生
- 容器运行时
【免费下载链接】linuxkit
A toolkit for building secure, portable and lean operating systems for containers
相关推荐
如何以 unread_dot 为例,在 Agent Zero 中创建、测试并审查一个本地 Web UI 插件?
如何以 unread_dot 为例,在 Agent Zero 中创建、测试并审查一个本地 Web UI 插件? 如果你的目标是理解 Agent Zero 的插件
操作系统云原生容器运行时从崩溃到自愈:Canal配置校验工具的终极实践指南
从崩溃到自愈:Canal配置校验工具的终极实践指南 Canal是由阿里巴巴开源的分布式数据库同步系统,主要用于实现MySQL数据库的日志解析和实时增量数据订阅与
后端变更数据捕获数据同步数据集成Changesets 自动化发布实战指南:从 CI 强制校验到 version/publish 全流程自动化
Changesets 自动化发布实战指南:从 CI 强制校验到 version/publish 全流程自动化 Changesets 是一款面向 monorepo
开发工具CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考