本页目录

LSM 与访问控制

覆盖: Linux Security Modules 架构 → SELinux/AppArmor/SMACK → LSM hooks 机制 → BPF LSM → capabilities → keyring → IMA/EVM 内核版本: 2.6 ~ 6.x

概述

传统的 Unix DAC (Discretionary Access Control) 只有 owner/group/other 三级权限,无法表达"这个 web 服务器只能读 /var/www,不能碰 /home/user/.ssh"这种细粒度策略。LSM 通过在关键系统调用路径插入 hook,让安全模块可以提供额外的访问控制决策。

目前最大的两个 LSM 是 SELinux(基于 type enforcement 的强制访问控制)和 AppArmor(基于路径匹配的 profile 策略)。

LSM Hook 架构

// include/linux/lsm_hooks.h
// 200+ hooks 覆盖所有敏感操作:
struct security_hook_heads {
    struct hlist_head file_open;          // open() 最后一步 → security_file_open()
    struct hlist_head inode_create;       // 创建 inode
    struct hlist_head inode_unlink;       // unlink()
    struct hlist_head socket_create;      // socket()
    struct hlist_head socket_bind;        // bind()
    struct hlist_head task_kill;          // kill()
    struct hlist_head sb_mount;           // mount()
    // ... 200+ more
};

// 调用链:
// security_file_open(file) → call_void_hook(file_open, file)
// → 遍历所有注册模块的 hook → 任一返回 error → 拒绝操作

Hook 的插入点

LSM Hook 插入点:open() 系统调用路径 open("/etc/shadow", O_RDONLY) vfs_open() → do_dentry_open() security_file_open(file) LSM hook 插入点 SELinux: file_has_perm() 检查 type enforcement 规则 AppArmor: aa_file_perm() 检查路径 profile 同时返回 OK → 操作允许 同一个 hook 点上,SELinux 与 AppArmor 各自独立检查同一次 open 调用, 两个模块都放行,操作才被允许。

SELinux: Type Enforcement

核心概念:
  - 一切都有标签 (label): 文件, 进程, socket, ...
    → ls -Z: system_u:object_r:httpd_sys_content_t:s0
  - 策略定义"哪个 source type 可以访问哪个 target type 的哪个 class"
    → 白名单模型: 默认拒绝, 只有明确允许的才放行
  - AVC (Access Vector Cache): 策略查询结果缓存 (性能关键)

SELinux 模式:
  /sys/fs/selinux/enforce
    Enforcing (1): 拒绝 + 日志
    Permissive (0): 允许 + 日志 (调试用)
    Disabled: 完全不加载

标签存储:
  ext4/xfs: xattr security.selinux
  tmpfs/procfs: 运行时生成 (genfscon)

AppArmor: 路径匹配

路径 profile 模型:
  安全策略不基于 type,而是基于路径匹配:
    /usr/bin/nginx {
      /var/www/** r,
      /var/log/nginx/* w,
      /run/nginx.pid w,
      /tmp/** rw,
      capability net_bind_service,
    }

  优点:
    - 比 SELinux 直观 (看到路径就知道策略)
    - 策略文件独立 (每个程序一个)
  缺点:
    - 路径可以被绕过 (hardlink, bind mount)
    - 不方便表达复杂的全局约束

SMACK: 简化 Type Enforcement

类似 SELinux 但简化了 90%:
  - 只有 label, 没有 role/user/MLS
  - 规则: "subject label access object label"
  - 用于: Tizen (三星), Automotive Grade Linux

内核编译: CONFIG_SECURITY_SMACK

BPF LSM (5.7+)

// 用 BPF 程序实现 LSM hook:
// bpf(BPF_PROG_LOAD, BPF_PROG_TYPE_LSM, ...)
// attach: bpf(BPF_RAW_TRACEPOINT_OPEN, lsm/file_mprotect)

// 相比内核模块的优点:
//   - 不需要编译内核模块
//   - verifier 保证安全性 (不会 panic)
//   - 更容易分发和更新

Capabilities: 拆分 root 特权

// include/uapi/linux/capability.h
// 将 root 的全部能力拆分为细粒度 bit:
CAP_SYS_ADMIN      // 系统管理
CAP_NET_RAW        // raw socket
CAP_NET_BIND_SERVICE  // 绑定 <1024 端口
CAP_SYS_PTRACE     // ptrace 其他进程
CAP_KILL           // 给其他用户的进程发信号
// ... 40+ capabilities

// 容器安全的关键:
//   docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE
//   → 容器内 root 只能绑定端口, 不能加载模块

IMA/EVM: 文件完整性

IMA (Integrity Measurement Architecture):
  测量: 每次文件被读取时计算 hash → 记录到 TPM
  Appraisal: 验证文件 hash → 拒绝被篡改的文件

EVM (Extended Verification Module):
  保护文件的元数据 (xattr, mode, owner) 不被篡改
  基于 HMAC (用 TPM 密钥) 或数字签名

调试

# SELinux
getenforce
ausearch -m avc --start recent  # 最近的拒绝
sealert -a /var/log/audit/audit.log  # 分析拒绝原因

# AppArmor
aa-status
cat /proc/<pid>/attr/apparmor/current

# capabilities
capsh --print  # 当前 shell 的 capabilities
getpcaps <pid>

参考

  • 源码⁠: security/ (lsm, selinux, apparmor, smack, integrity), include/linux/lsm_hooks.h
  • 内核文档⁠: Documentation/admin-guide/LSM/
  • LWN: "The LSM hook interface", "BPF LSM"

关键词: LSM, SELinux, AppArmor, BPF LSM, capabilities, IMA, EVM, type enforcement, AVC