内核运行时防御框架,用于应对 AF_ALG 漏洞,具备 eBPF 套接字追踪、Ansible 加固以及用于漂移检测的加密审计器功能。
一个针对 Linux AF_ALG(地址族算法,族 38)子系统的内核运行时防御框架。专为运行企业级 Linux 集群的安全运营中心(SOC)打造,在这些环境中,零信任必须深入内核,而非止步于网络边缘。
AF_ALG 通过套接字接口(socket(AF_ALG, SOCK_SEQPACKET, 0))将内核加密 API 暴露给用户空间。它最初是为没有 /dev/crypto 的嵌入式系统而添加的,此后却积累了不成比例的内核 CVE 份额,因为它将内核态加密代码暴露给了非特权调用者——这是一种典型的攻击面错配。
在典型的企业构建中:
connect()、bind() 或 DNS 的端点工具看不到任何东西——AF_ALG 流量永远不会离开内核。该框架将每一次 AF_ALG 套接字创建视为高信号事件,并缩减使这些事件可被利用的攻击面。
.
├── ebpf/ 运行时可观测性(BCC 追踪器 + 白名单)
├── ansible/ 配置即代码(sysctl + systemd drop-in)
├── systemd/ 适用于非 Ansible 主机的独立 systemd drop-in
├── auditor/ 内核状态审计器(Python)
├── schemas/ 审计报告接入的 JSON Schema
├── scripts/ 辅助 shell 脚本(由 CI 进行 lint)
├── tests/ 单元测试 + 报告夹具
└── .github/workflows/ CI:shellcheck + JSON schema 验证 + lint
ebpf/af_alg_tracer.py 将 kprobe 附加到 security_socket_create。该探针在 BPF 程序层面过滤 family == 38,因此验证器会剪除无关的套接字创建,单事件开销保持在纳秒级。每次尝试输出一条 JSON 记录:
{
"@timestamp": "2026-05-02T09:14:11.412041+00:00",
"event": {"category": "kernel", "action": "af_alg_socket_create", "severity": "high"},
"process": {"pid": 1394, "tgid": 1394, "comm": "suspicious_bin"},
"user": {"uid": 1000, "gid": 1000},
"socket": {"family": 38, "family_name": "AF_ALG", "type": 5, "protocol": 0},
"host": {"name": "web-prod-04"}
}
将标准输出管道接入 Vector、Fluent Bit 或 journald(通过 systemd-cat)。comm 名称白名单(/etc/af-alg-defense/allow.list)可抑制已知良好消费者,同时不丧失检测偏差的能力。
kprobe 目标是 LSM 钩子,因此事件在意图层面触发——即使尝试会被 seccomp 或 RestrictAddressFamilies 拒绝,仍会产生记录。这正是 SOC 进行行为基线化所需要的。
ansible/roles/af_alg_hardening/ 应用两层加固:
Sysctl drop-in(/etc/sysctl.d/90-af-alg-defense.conf):
kernel.unprivileged_userns_clone=0 — 移除大多数 AF_ALG 提权链使用的 userns 跳板。user.max_user_namespaces=0 — 发行版可移植的纵深防御。Systemd drop-in(/etc/systemd/system/<unit>.d/50-af-alg-restrict.conf):
使用 RestrictAddressFamilies 作为白名单(而非黑名单)。该单元被允许 AF_UNIX AF_INET AF_INET6 AF_NETLINK;任何其他地址族——包括 AF_ALG——都会以 EAFNOSUPPORT 失败,因为 systemd 通过 cgroup 附加的 BPF 强制执行,应用程序无法禁用。该 drop-in 还会剥离 CAP_SYS_ADMIN 并应用 ProtectKernel* 以关闭最常见的提权路径。
应用方式:
ansible-playbook -i inventory ansible/site.yml --check --diff # 预览
ansible-playbook -i inventory ansible/site.yml # 强制执行
对于没有 Ansible 的主机,将独立文件放置到位:
sudo ./scripts/deploy_dropin.sh nginx.service
auditor/crypto_auditor.py 通过检查以下内容生成 JSON 安全状态报告:
/proc/crypto — 每个已注册的 cipher / hash / aead,包含 FIPS 标志和自检状态。/sys/module/ — 加密子树中已加载的模块,包含污染标志和参数快照。/proc/sys/kernel/、/proc/sys/user/ — 控制 AF_ALG 攻击路径的 sysctl。/sys/kernel/security/lockdown — 内核 lockdown 模式。报告以稳定的发现 ID(目前为 FND-001 至 FND-005)为键,因此 SIEM 规则可以抑制单个发现而无需丢弃整个文档。漂移检测将状态与基线进行比对:
sudo ./auditor/crypto_auditor.py --output /var/log/af-alg-defense/today.json
sudo ./auditor/crypto_auditor.py \
--baseline /var/log/af-alg-defense/baseline.json \
--fail-on-drift
模式位于 schemas/audit_report.schema.json(Draft 2020-12),并在每次推送时于 CI 中验证。
.github/workflows/ci.yml 在每次推送和 PR 时运行四个任务:
*.sh 和带 shebang 的脚本。audit_report.schema.json 进行元模式检查,然后在 GH runner 内核上实时运行审计器并验证生成的报告。tests/fixtures/ 中的夹具也会被检查。ruff check .)。模式检查失败会阻止合并,从而防止下游 SIEM 解析器因静默重命名的字段而崩溃。
af_alg_socket_create 事件——首次出现即告警,不要聚合。crypto_modules 条目。hardened=false 的 sysctl——表明存在手动篡改或来自并行配置系统的漂移。lockdown 字段从 integrity/confidentiality 转变为 none——内核状态被篡改的强烈指标。allow.list,以覆盖已知良好消费者(启动时的 cryptsetup 通常是其中之一)。baseline.json。af_alg_systemd_services 设置为一个低风险单元。观察 journald 中的 EAFNOSUPPORT 错误。systemd-analyze security <unit> 应显示限制已生效。--fail-on-drift,并将非零退出路由到值班队列。af_alg 已在被使用,它不会卸载该模块。模块卸载不在范围内,因为合法的启动时消费者可能仍在运行。如果你已确认主机上没有任何程序需要它,可在内核命令行使用 modprobe.blacklist=af_alg。security_socket_create kprobe 目标)。uname -r 的内核头文件。CAP_BPF(或 root);审计器需要读取 /proc/crypto 的权限(读取无需任何特权)。Apache-2.0。参见 LICENSE。
| 零信任原则 | 本框架中的控制措施 |
|---|
| 永不信任,始终验证 | eBPF 追踪器记录每一次 AF_ALG 套接字创建尝试,包含 pid/uid/comm |
| 假设已遭入侵 | 加密审计器将内核状态与签名基线进行比对 |
| 最小权限 | systemd RestrictAddressFamilies + 受管单元上的能力边界 |
| 微隔离(内核侧) | unprivileged_userns_clone=0 移除漏洞利用所用的 userns 跳板 |
| 持续验证 | CI 在每次变更时依据版本化模式验证审计报告 |