CentOS 7 和 CentOS 8 的官方内核在安全特性上往往偏向保守,默认不会开启诸如 SELinux 的完整强制模式配合、更细粒度的地址空间布局随机化或最新的 Landlock 安全模块。如果你直接使用 "yum update kernel",得到的是追求稳定通用的主线内核,缺少许多针对现代攻击面的主动防御机制。安全增强型 Linux 内核,通常指的是集成了 Grsecurity/PaX 补丁集或者启用了更激进安全配置的长期支持内核,例如 Linux 基金会维护的长期支持内核配合 Kernel Self Protection Project 的推荐配置。在 CentOS 上部署这类内核,核心思路不是简单地安装一个包,而是通过第三方仓库获取预编译的加固内核,或者从源码自行编译,将内核的安全开关调整到最高等级。
首先需要明确你的 CentOS 版本。CentOS 7 的内核基线是 3.10,CentOS 8 是 4.18,这两个版本的原生内核在安全子系统的实现上已经过时。比如 CentOS 7 的 3.10 内核缺乏对内核页表隔离的完整支持,容易受到 Meltdown 类攻击的持续威胁。因此,安装安全增强型内核的第一步,是引入 ELRepo 或长期支持内核仓库,这些仓库提供了主线长期支持内核的 RPM 包,版本通常在 5.4、5.10、5.15 或 6.1 以上,这些内核不仅修复了已知漏洞,还默认启用了许多强化编译选项。
引入 ELRepo 仓库的操作非常直接。对于 CentOS 7,执行以下命令导入 GPG 密钥并安装仓库包:
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
对于 CentOS 8,由于官方已经停止维护,你需要先处理仓库镜像问题,将基础仓库指向归档源,然后再安装 ELRepo。安装完成后,不要直接安装 "kernel-lt" 或 "kernel-ml",因为这两个包虽然版本新,但安全配置仍然是通用的。你需要检查仓库中是否提供了带有 "-hardened" 标记的内核包,某些第三方维护者会专门编译加固版本。如果没有,那么安装长期支持内核仅仅是第一步,后续必须通过内核启动参数和运行时配置来强制开启安全特性。
安装长期支持内核的命令如下,这里以 5.10 长期支持版本为例,它在性能和安全的平衡上表现优异,且对老硬件兼容性良好:
yum --enablerepo=elrepo-kernel install kernel-lt -y
安装完成后,需要调整 GRUB 引导顺序,让系统默认从新内核启动。查看当前内核菜单项:
grubby --default-kernel
设置新内核为默认启动项,假设新内核的索引为 0:
grubby --set-default /boot/vmlinuz-5.10.xxx.el7.elrepo.x86_64
重启系统后,通过 "uname -r" 确认内核版本已经切换到 5.10 或更高版本。但这只是基础,真正的安全增强在于对内核参数的深度定制。你需要编辑 "/etc/sysctl.conf" 以及 "/etc/default/grub" 中的内核命令行,开启一系列主动防御机制。
开启内核地址空间布局随机化的最高熵值CentOS 默认的随机化熵值较低,攻击者通过信息泄露绕过地址随机化的概率相对较高。在 "/etc/sysctl.conf" 中设置:
kernel.randomize_va_space = 2
这个值确保堆、栈、内存映射段都使用完全的随机化。但仅靠用户态随机化不够,内核态的地址随机化需要通过启动参数开启。编辑 "/etc/default/grub",在 "GRUB_CMDLINE_LINUX" 中加入 "randomize_kstack_offset=on" 和 "page_alloc.shuffle=1"。前者对内核栈起始位置进行随机偏移,后者打乱页面分配器的空闲链表顺序,显著增加内核漏洞利用的难度。
强制启用完整的 SLUB 分配器加固新内核支持对 SLUB 分配器的元数据保护,防止通过堆溢出篡改内核对象。在启动参数中添加 "slab_common.usercopy_fallback=0" 和 "slab_nomerge"。第一个参数禁用 usercopy 的回退机制,一旦检测到越界拷贝立即触发 panic,而不是尝试修复;第二个参数禁止内核将相似大小的 slab 缓存合并,这能防止跨缓存攻击。同时,在 "/etc/sysctl.conf" 中加入:
vm.unprivileged_userfaultfd = 0
关闭非特权用户对 userfaultfd 的访问,这是许多内核利用技术的核心依赖。
配置内核模块签名与只读数据段安全增强型内核的关键在于减少攻击面,并保护已加载的内核代码不被篡改。首先,你需要确保内核模块签名验证是强制开启的。检查内核配置,确认 "CONFIG_MODULE_SIG_FORCE=y" 已经编译进内核。对于 ELRepo 的预编译内核,这个选项通常是开启的,但你需要验证。运行:
cat /proc/cmdline | grep module.sig_enforce
如果没有,在启动参数中加入 "module.sig_enforce=1"。这会强制内核拒绝加载任何未签名的模块,rootkit 的注入路径被直接切断。同时,为了进一步锁定内核内存,加入 "rodata=on" 和 "nosmep" 的反向操作 "smep=on" 与 "smap=on"。这些参数确保内核不能执行用户态代码,也不能随意访问用户态内存,是防御 ret2usr 攻击的硬件级手段。绝大多数现代 CPU 都支持 SMEP 和 SMAP,CentOS 的内核默认开启,但显式写在启动参数中可以防止某些边缘情况下的配置回退。
启用 Landlock 和 BPF 安全限制5.10 以上内核支持 Landlock 安全模块,它允许非特权进程对自身进行沙箱化,限制文件系统访问权限。这是比 SELinux 更轻量且易于使用的强制访问控制机制。在启动参数中无需特殊配置 Landlock,因为它默认编译为模块,但你需要确认其存在:
modprobe landlock lsmod | grep landlock
如果未加载,可以通过 "modprobe" 手动加载,并在 "/etc/modules-load.d/landlock.conf" 中添加 "landlock" 使其开机自启。更重要的是限制 BPF 系统调用的滥用,BPF 虽然强大,但也是容器逃逸和权限提升的常见载体。在 "/etc/sysctl.conf" 中添加:
kernel.unprivileged_bpf_disabled = 1
这会禁止非特权用户调用 BPF 系统调用,除非绝对必要,否则应保持关闭。同时设置 "net.core.bpf_jit_harden = 2",启用 BPF JIT 编译器的加固,包括常量盲化技术,防止攻击者通过 JIT 喷射构造 shellcode。
微调 SELinux 策略以配合新内核特性CentOS 自带的 SELinux 策略是针对旧内核编写的,新内核引入的许多安全钩子和对象类别在旧策略中可能处于宽松状态。更新内核后,你需要安装与内核版本匹配的策略包,或者至少手动检查 SELinux 的布尔值设置。执行:
semanage boolean -l | grep -E "deny_ptrace|secure_mode"
确保 "deny_ptrace" 对所有非特权用户开启,这能阻止进程间注入。同时,将 SELinux 强制模式下的 "user" 域和 "staff" 域映射到最新的角色分离策略。如果你运行容器,务必开启 "selinuxuser_use_ssh_chroot" 和 "virt_sandbox_use_all_caps" 的严格限制,防止容器内进程通过新内核的特性绕过旧的 SELinux 规则。
移除不需要的内核模块和驱动安全增强不仅仅是增加功能,更重要的是做减法。CentOS 默认加载了大量针对罕见硬件和文件系统的驱动,每一个都是潜在的攻击面。进入 "/lib/modules/$(uname -r)/kernel/drivers",你可以看到诸如红外、火线、古董文件系统等模块。通过创建 "/etc/modprobe.d/blacklist-hardening.conf" 文件,禁止这些模块加载:
blacklist firewire-core blacklist firewire-ohci blacklist usb-storage blacklist cramfs blacklist freevxfs blacklist jffs2 blacklist hfs blacklist hfsplus blacklist udf install firewire-core /bin/false install usb-storage /bin/false
注意 "install" 指令比 "blacklist" 更强硬,它直接告诉内核在请求加载该模块时执行 "/bin/false",从而彻底阻断加载路径。对于服务器环境,USB 存储驱动是物理接触攻击和数据泄露的常见途径,应当坚决禁用,除非业务必须。
编译自定义加固内核的进阶操作如果预编译内核仍然无法满足你对安全的要求,或者你需要开启一些上游默认关闭的极端加固选项,那么从源码编译内核是最终方案。以 5.10 长期支持内核为例,从 kernel.org 获取源码并解压。在 "make menuconfig" 阶段,你需要重点关注以下配置项。在 “Processor type and features” 中,开启 “Randomize kernel stack offset on syscall” 和 “Randomize lower bits of the argument of the brk syscall”。在 “Memory Management” 中,开启 “Randomize free memory on boot” 和 “Enable heap memory zeroing on allocation”。在 “Security options” 中,除了开启常规的 SELinux 和 Landlock,还要启用 “Restrict unprivileged access to the kernel syslog” 和 “Harden memory copies between kernel and userspace”。
编译时,建议使用 Clang 的 Control Flow Integrity 特性,但这需要 Clang 编译器和 LTO 支持,配置较为复杂。对于大多数 CentOS 环境,使用 GCC 并开启 "-fstack-protector-strong" 和 "-D_FORTIFY_SOURCE=2" 的默认编译选项即可。编译命令如下:
make olddefconfig make -j$(nproc) make modules_install make install
编译安装后,同样需要调整 GRUB 配置,并重新生成 initramfs。新内核启动后,通过 "/proc/config.gz" 或 "/boot/config-*" 文件检查所有安全选项是否生效。
验证安全增强效果与持续监控安装和配置完成后,不能仅凭感觉判断系统已经安全。需要使用工具进行客观验证。首先,运行 "checksec" 脚本检查内核的编译时保护:
git clone https://github.com/slimm609/checksec.sh.git cd checksec.sh ./checksec --kernel
输出会显示内核是否开启了 KASLR、STACKPROTECTOR、STRICT_DEVMEM 等保护。其次,使用 "spectre-meltdown-checker" 脚本验证硬件漏洞的缓解措施是否因为新内核而全部激活:
wget https://meltdown.ovh -O spectre-meltdown-checker.sh sh spectre-meltdown-checker.sh
理想状态下,所有 CVE 条目应显示为 “NOT VULNERABLE” 或 “MITIGATED”。最后,配置 "auditd" 守护进程监控对关键内核参数的修改尝试,以及任何试图加载黑名单模块的行为。在 "/etc/audit/rules.d/audit.rules" 中添加:
-w /etc/sysctl.conf -p wa -k sysctl_changes -w /etc/modprobe.d/ -p wa -k modprobe_changes -a always,exit -F arch=b64 -S init_module -S delete_module -k modules
重启 auditd 服务后,任何对内核安全配置的篡改或模块加载操作都会被记录,结合集中式日志分析平台,可以第一时间发现入侵行为。
整个过程的核心在于,安全增强型内核不是单一软件包的替换,而是从内核版本选择、编译选项、启动参数、运行时配置、模块控制到强制访问控制策略的完整链条。CentOS 作为企业级发行版,其默认配置向兼容性妥协了太多,只有通过上述系统性的加固,才能将内核的攻击面压缩到最小,同时利用新版本的安全特性构建主动防御体系。
