系列:Linux 内核深度实战系列 #15

Linux 内核安全机制深度实战:从 LSM 框架到零信任内核的防御体系

操作系统安全是计算体系中最底层的防线。Linux 内核构建了一套纵深防御的安全架构——从强制访问控制(LSM)到完整性度量(IMA/EVM),从系统调用过滤(seccomp)到内核密钥管理,从审计子系统的全链路追踪到基于 eBPF 的运行时安全监控。本文深入剖析 Linux 内核安全子系统的核心架构、关键数据结构与生产级部署实践。


一、LSM(Linux Security Module)安全框架

1.1 架构演进

LSM 是 Linux 内核安全子系统的核心框架,通过在关键内核路径上插入安全钩子(Security Hooks),允许安全模块以可加载模块的形式实施细粒度的访问控制。LSM 的设计哲学是"不改变内核主代码,仅通过钩子拦截",确保了框架的可扩展性。

内核在主分支中集成了多个 LSM 模块:SELinux(基于 Flask 架构的 MAC)、AppArmor(基于路径的 MAC)、Smack(简化的 MAC)、TOMOYO(基于学习的 MAC)以及 Yama(ptrace 限制)。除了这些"主要" LSM,内核还有 LoadPin、SafeSetID、Lockdown 等"次要" LSM,它们可以同时启用。

1.2 安全钩子的类型

LSM 钩子按照功能可分为几个大类:

类别 典型钩子 作用
权限前置 inode_permission、file_permission 文件访问前拦截
任务安全 task_alloc、task_free 进程安全上下文的创建与回收
IPC 安全 shm_shmat、msg_queue_msgsnd IPC 操作安全检查
套接字安全 socket_create、socket_bind 网络操作安全检查
模块安全 kernel_module_request 模块加载控制
BPF 安全 bpf、bpf_map BPF 程序与映射控制

1.3 SELinux 深度解析

SELinux 是最广泛使用的 LSM 实现,基于 Flask 架构实现了类型强制(TE)、角色访问控制(RBAC)和多级安全(MLS/MCS)三层安全模型。

SELinux 的核心数据结构包括 struct task_security_struct 和 struct inode_security_struct 等,统称安全上下文(Security Context)。一个 SELinux 上下文通常表示为 user:role:type:level,其中 type 是最常用的策略维度。

SELinux 的策略规则通过 Access Vector Cache (AVC) 加速。AVC 是已缓存的访问决策结果,当相同请求再次出现时可以直接返回。SCST(Security Compute Table)存储了具体的策略决策。

1.4 AppArmor 机制与部署

AppArmor 基于路径名匹配实现 MAC 管理,相比 SELinux 更轻量且配置直观。其规则包含能力(Capabilities)、网络规则和文件访问规则三大类。

AppArmor 的域转换机制是核心功能之一:当进程通过 execve() 执行一个二进制文件时,可以根据目标文件的规则切换域,实现进程行为的即时切换。Profile 可以处于 enforce、complain 三种模式。

在实际部署中,AppArmor 特别适合容器化环境——它的路径匹配模式不依赖文件系统标签,对容器卷(bind mount)的支持也更为友好。Ubuntu、Debian、SUSE 发行版以 AppArmor 作为默认 LSM。

1.5 Lockdown 与内核完整性

Linux 4.14 引入的 Lockdown LSM 是保护内核完整性最底层的机制。通过不同的锁定模式,限制 root 对内核内存的直接修改:

  • none:默认无锁定
  • integrity:禁止通过 /dev/mem 和 /dev/kmem 修改内核内存,禁止 kexec 加载未签名内核
  • confidentiality:在 integrity 基础上,进一步禁止读取内核内存(如禁止 kcore),防止机密信息泄露
  • confidentiality 模式在启用可信启动(Secure Boot)后由固件自动激活,保护硬件密钥等敏感数据

二、IMA/EVM 完整性度量体系

2.1 IMA(Integrity Measurement Architecture)

IMA 是 Linux 内核的文件完整性度量框架,其工作流程如下:当进程对一个文件执行操作(open/exec/mmap)时,IMA 利用钩子捕获访问事件,计算文件哈希(默认 SHA-256),将度量值扩展到 TPM 的 PCR 寄存器中。

IMA 度量策略通过内核命令行或 securityfs 配置:

ima_policy=measure func=BPRM_CHECK mask=MMAP_CHECK ima_hash=sha256

IMA 记录可以包含以下关键字段:模板哈希(template hash)、文件哈希(file hash)、文件路径(file path)、IMA 签名(ima-sig)。每次度量都会产生一个 IMA 日志条目,存储在 securityfs 的 ima/binary_runtime_measurements 中。

在生产环境中,IMA 常被用于构建远程证明(Remote Attestation)机制:远端服务读取 IMA 日志后验证 PCR 值,确认系统完整性。

2.2 EVM(Extended Verification Module)

EVM 在 IMA 的基础上扩展,为文件扩展属性提供完整性保护。EVM 保护的目标包括:

  • security.ima:IMA 度量哈希
  • security.selinux:SELinux 安全上下文
  • security.smack:Smack 标签
  • security.capability:文件能力属性

EVM 使用 HMAC(密钥以内核密钥环中的 evm-key 存储)对扩展属性签名,确保任何对安全属性的篡改都会被检测到。HMAC 的密钥来源有两种:用户空间可信密钥(trusted key)和 TPM 派生的密钥(encrypted key)。

2.3 IMA-Measure 与 IMA-Appraise

IMA 有两个主要运行阶段:

Measure 模式:记录度量值,用于事后审计。适合合规性场景(如三级等保要求)。

Appraise 模式:在文件访问时验证签名或哈希与预期值匹配。不匹配的文件访问将被拒绝,形成主动防护。适合高完整性要求的系统(如支付终端、关键基础设施)。


三、seccomp 系统调用过滤

3.1 seccomp-bpf

seccomp 通过 BPF 过滤器限制进程可使用的系统调用,是最有效的进程隔离机制之一。seccomp-bpf 的基本原理是:进程调用 prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) 安装 BPF 过滤器后,后续所有系统调用都会经过过滤器的判定。

BPF 过滤器可以检查系统调用号(syscall number)、参数值。典型的 allow 策略是显式放行 read/write/exit 等必要调用,拒绝其他所有调用。典型的 syscall-allowlist 通常只包含十几个系统调用。

3.2 推荐的 BPF 过滤器模式

struct sock_filter filter[] = {
    /* 验证架构(防止跨架构攻击) */
    BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
             (offsetof(struct seccomp_data, arch))),
    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AUDIT_ARCH_X86_64, 1, 0),
    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
    /* 加载系统调用号 */
    BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
             (offsetof(struct seccomp_data, nr))),
    /* 允许的调用列表 */
    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_read, 0, 1),
    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
    ...
    /* 默认策略:拒绝其他 */
    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (EPERM & 0xffff))
};

3.3 seccomp 与容器的结合

seccomp 是 Docker、Kubernetes 等容器平台默认启用的安全层。Docker 的默认 seccomp 配置文件阻止了约 44 个高危系统调用,包括 reboot、kexec_load、init_module、delete_module、bpf 等可能威胁宿主机安全的系统调用。

生产环境中建议通过 securityContext.seccompProfileType 在 Pod 级别配置自定义 seccomp Profile。对于需要高度隔离的工作负载(如多租户环境),可以使用 RuntimeDefault 或自定义 Profile。


四、内核密钥保留服务

4.1 密钥类型与命名空间

内核密钥保留服务(Key Retention Service)提供持久化的密钥管理,核心类型包括:

类型 用途
.asymmetric 非对称密钥(用于验证、签名)
.symmetric 对称密钥(用于加密/解密)
.rxrpc RxRPC 认证
.rxrpc_s RxRPC 服务器端
.keyring 密钥环(可以包含其他密钥引用)
.logon 用户自定义(使用密码派生)
.user 通用对称密钥
.encrypted 加密型密钥(由用户或信任密钥包装)

密钥通过三层路径可见:用户空间的 keyctl 系统调用、内核密钥环接口、securityfs 的 /proc/keys 文件。密钥令牌保存在 key_user 结构上,通过 UID 和 GID 控制访问权限。

4.2 信任密钥与加密密钥

内核支持信任密钥(Trusted Key)和加密密钥(Encrypted Key)链式信任模型。信任密钥基于 TPM 的存储根密钥(SRK)封装,提供硬件级保护。加密密钥由信任密钥或用户密钥包装,启用后可以将加密密钥持久化到磁盘,仅在内存中解密。

4.3 应用场景

内核密钥服务在以下场景中是核心组件:

  • EFS(Encrypted File System):文件内容的对称加密密钥
  • EVM 保护:HMAC 签名密钥
  • IMA 签名:IMA 签名验证公钥
  • NFSv4/Kerberos:RPC GSS 认证密钥
  • -wireless WPA/WPA2:Wi-Fi 握手密钥
  • tls 认证:内核 TLS 握手的预共享密钥

五、Audit 审计子系统

5.1 架构设计

Linux Audit 子系统从 2.6 内核开始集成,提供系统的审计框架。其架构包含用户空间的 auditd 和内核中的 netlink 通信通道。内核根据审计规则通过 netlink socket 发送审计事件到用户空间的 auditd 守护进程。

5.2 审计规则类型

审计规则分为三大类:

文件规则:监控特定文件的访问。

-w /etc/passwd -p wa -k identity
-w /etc/shadow -p rwa -k shadow-access

系统调用规则:拦截特定系统调用。

-a always,exit -F arch=b64 -S execve -k execution
-a always,exit -F arch=b64 -S openat -F exit=-EACCES -k access-denied

文件属性过滤器:

  • -F uid=0:按 UID 过滤
  • -F auid=1000:按原始登录 UID 过滤
  • -F dir=/etc:按目录路径过滤

5.3 审计事件格式

审计日志包含固定的字段结构,关键字段包括:type(事件类型)、msg(时间戳和序号)、pid/uid/gid(进程身份)、comm(命令行)、exe(可执行文件路径)、syscall(系统调用号)、success(成功/失败)、exit(错误码)、a0~a3(参数)、items(路径项)。

对于安全分析而言,最有价值的审计事件类型有:SYSCALL(系统调用记录)、PATH(文件路径记录)、USER_CMD(用户命令)、ANOM_PROMISCUOUS(混杂模式异常)、CRYPTO_KEY_USER(密钥操作)。

5.4 生产环境审计策略

对关键系统(数据库服务器、网关、认证服务器等),建议审计规则包括:

  1. 监控系统调用的执行(execve、fork 等)
  2. 监控关键文件修改(/etc/passwd、/etc/shadow、/etc/sudoers)
  3. 监控权限提升(setuid、setgid 和 capability 变化)
  4. 监控内核模块操作(init_module、finit_module、delete_module)
  5. 监控时间变化(settimeofday、clock_settime、adjtimex)
  6. 监控网络配置(socketcall、setsockopt 与防火墙变更)
  7. 监控用户/组修改(add_user、add_group 等 PAM 相关调用)

  8. 六、Capabilities 与 Namespace 的安全边界

    6.1 POSIX Capabilities

    Linux 将 root 特权拆分为 40+ 个细粒度的能力(Capability),进程可以仅拥有所需的能力而不需要完整的 root 权限。关键能力包括:

    • CAP_SYS_ADMIN:超级用户权限(挂载、ptrace 多数操作)
    • CAP_NET_ADMIN:网络配置(路由、防火墙等)
    • CAP_SYS_MODULE:加载内核模块
    • CAP_SYS_RAWIO:原始 IO 操作
    • CAP_SETUID/CAP_SETGID:修改进程 UID/GID
    • CAP_SYS_PTRACE:调试其他进程
    • CAP_SYS_ADMIN:文件系统管理(许多 chroot 相关)
    • CAP_CHOWN:修改文件所有者

    容器运行时(如 runc)默认丢弃绝大多数能力,只保留必要的几个(如 CAP_SETUID、CAP_SETGID、CAP_CHOWN、CAP_NET_BIND_SERVICE)。通过 --cap-add 和 --cap-drop 可以在容器级别精确控制。

    6.2 User Namespace

    User Namespace 实现了 UID/GID 的隔离映射,使得命名空间内 root(UID 0)在外部是普通用户。这个特性是 unprivileged 容器(rootless container)的基石。

    用户命名空间的典型映射方式是将外部 UID 范围(如 100000-165536)映射到内部 UID 范围(0-65535),使得容器内的 root 在宿主机上只是一个普通用户,大幅减少了攻击面。


    七、eBPF 安全监控

    7.1 BPF LSM

    Linux 5.7 引入了 BPF LSM 支持,允许通过 BPF 程序实现自定义的安全策略检查点。这比传统 LSM 模块更轻量,可以动态加载和更新,不需要重新编译内核。

    BPF LSM 钩子覆盖常见 LSM 钩子,包括 bpf、bpf_map、bpf_prog、file_permission、socket_bind 等。安全团队可以使用 bpftool 加载 BPF LSM 程序实现灵活的安全监控。

    7.2 Falco 与运行时安全

    Falco 是 CNCF 孵化的开源运行时安全工具,通过 eBPF 驱动监控容器与进程行为。其规则引擎支持 YAML 格式的规则,可以识别异常行为如非预期的 shell 执行(容器反弹 shell 检测)、敏感文件读取(/etc/shadow 非授权读取)、特权操作(mount、unshare)等。

    生产环境中 Falco 的典型部署是与 Kubernetes + FalcoSidekick 集成,通过 webhook 将告警推送到 Slack、PagerDuty、Elasticsearch 等目标。


    八、生产级安全加固实践

    8.1 内核参数加固

    针对生产服务器的安全加固,推荐以下内核参数:

    # 禁用 IP 源路由(防止 IP 欺骗)
    net.ipv4.conf.all.accept_source_route = 0
    net.ipv6.conf.all.accept_source_route = 0
    
    # 禁用 ICMP 重定向(防止路由劫持)
    net.ipv4.conf.all.accept_redirects = 0
    net.ipv4.conf.all.send_redirects = 0
    
    # 启用 SYN Flood 防护
    net.ipv4.tcp_syncookies = 1
    
    # 禁用 IPv6(如无需要)
    net.ipv6.conf.all.disable_ipv6 = 1
    
    # 限制核心转储(防止内存泄漏)
    kernel.core_pattern = |/bin/false
    fs.suid_dumpable = 0
    
    # 限制 ptrace 范围(Yama LSM)
    kernel.yama.ptrace_scope = 2

    8.2 Secure Boot 与 measured boot

    可信启动(Secure Boot)验证启动链上每个组件的数字签名:UEFI 固件验证 shim→GRUB→内核→initramfs。Linux 内核的 Lockdown LSM 在 Secure Boot 环境下自动进入 Integrity 模式。

    度量启动(Measured Boot)将启动过程中每个组件的度量值扩展到 TPM 的远程 PCR 寄存器。与可信启动不同,度量启动不阻止恶意组件的运行,而是通过 IMA 日志供远程验证。两者结合使用(Secure Boot + IMA Remote Attestation)可形成"防篡改 + 可证明"的完整信任链。

    8.3 KSPP(Kernel Self-Protection Project)

    KSPP 是 Linux 内核安全加固的长期目标清单,关键项目包括:

    • STACKPROTECTOR:栈溢出保护,GCC -fstack-protector-strong 编译
    • SLAB_FREELIST_RANDOM:SLAB 分配器随机化,对抗堆喷射(heap spray)
    • SLAB_FREELIST_HARDENED:SLAB 自由列表指针混淆
    • PAGE_TABLE_ISOLATION:KPTI,内核/用户页表分离(Meltdown 补丁)
    • VMAP_STACK:虚拟映射内核栈,防止栈溢出覆盖相邻数据
    • STATIC_USERMODEHELPER:固定 usermode helper 路径
    • REFCOUNT_FULL:引用计数溢出保护
    • HARDENED_USERCOPY:用户空间拷贝验证

    通过检查 /proc/config.gz 或 /boot/config-$(uname -r) 可以验证特定内核的 KSPP 项目启用状态。


    总结

    Linux 内核安全是一个纵深防御的多层架构。LSM(SELinux/AppArmor)提供强制访问控制的基础层;IMA/EVM 保证文件和系统扩展属性的完整性;seccomp-bpf 将进程可用的系统调用限制到最小集合;内核密钥服务保护加密资产的硬件级安全;审计子系统提供不可抵赖的运行时追踪;User Namespace + Capabilities 实现特权分离;BPF LSM 则为安全策略提供了可编程的运行时扩展。

    生产环境的安全加固需要从可信启动到应用沙箱逐层构建——Secure Boot 验证启动链,IMA/EVM 保护内核与文件完整性,SELinux/AppArmor 实施 MAC 策略,seccomp 限制容器系统调用,Audit 记录安全事件,eBPF 提供实时威胁检测。没有单一的银弹,唯有纵深防御才能在面对不断演化的安全威胁时有足够的弹性。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部