Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
工具/GitHubGitHub/devstuff/harden-docker-seccomp
云基础设施安全防御工具容器安全漏洞分析配置审计DevSecOps
GitHubdevstuff/harden-docker-seccomp

harden-docker-seccomp

Docker 针对 CVE-2026-31431(“Copy Fail”)的缓解措施。同时包含 Kubernetes 模板。

查看仓库
2144个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

harden-docker-seccomp

幂等脚本,用于阻止宿主机上所有 Docker 容器创建 AF_ALG 套接字,以缓解 CVE-2026-31431(“Copy Fail”)。

背景

CVE-2026-31431 是 Linux 内核 authencesn 加密模板中的一个本地权限提升漏洞,影响 2017 年至上游修复可用(主线提交 a664bf3d603d)期间构建的内核。非特权用户可以将 AF_ALG 套接字操作与 splice() 链接起来,对任何可读文件的页缓存执行受控的 4 字节写入,以 setuid 二进制文件为目标获取 root shell。一个 732 字节的 Python 概念验证代码可在所有受影响的 Linux 发行版上可靠地利用此漏洞,无需竞争条件或针对各发行版的偏移量。

该漏洞利用的强制第一步是打开 AF_ALG 套接字(socket(AF_ALG, SOCK_SEQPACKET, 0))。通过 seccomp 阻止该系统调用,即使在未打补丁的内核上也能防止利用。Docker 内置的默认 seccomp 配置文件不会阻止 AF_ALG,而 RuntimeDefault 也不够——测试集群显示,在 PSS Restricted 下准入的 Pod 仍然可以打开 AF_ALG 套接字。

有关完整技术细节和各发行版的补丁可用性,请参阅原始研究人员公告 https://copy.fail 和 CERT-EU 公告 https://cert.europa.eu/publications/security-advisories/2026-005/。

本工具的范围

此脚本涵盖 Docker Engine 全局守护进程配置。对于 Kubernetes,请参阅下面的 Kubernetes 部分。对于裸机或虚拟机工作负载(非容器化),请改为禁用 algif_aead 内核模块:

root@kitploit:~
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
rmmod algif_aead 2>/dev/null || true

该方法对 dm-crypt/LUKS、kTLS、IPsec/XFRM、OpenSSL、GnuTLS、NSS 或 SSH 没有影响。

工作原理

  1. 提取 Docker 当前内置的 seccomp 配置文件,通过检查一个短暂容器的 HostConfig.SecurityOpt。这避免了对远程 URL 的任何依赖,并确保基础配置文件与实际安装的 Docker 版本匹配。仅当容器检查无结果时,才使用来自 moby/profiles 的 GitHub 获取作为后备方案。

  2. 修补配置文件,从 Docker 的允许列表条目中移除 socket,并使用 SCMP_CMP_NE 重新添加,附带一个参数过滤器,允许除 AF_ALG(值 38)之外的所有地址族。Docker 的其他默认 seccomp 行为均保持不变。

  3. 原子写入修补后的配置文件 到 /etc/seccomp/docker-block-af-alg.json(临时文件 + 重命名)。如果磁盘上的内容已相同,则跳过。

  4. 更新 /etc/docker/daemon.json,将 "seccomp-profile" 设置为修补后配置文件的路径。首次修改时,原始文件备份为 daemon.json.bak。如果已正确配置,则跳过。

  5. 通过 systemctl reload docker 重新加载 dockerd(SIGHUP——无需重启)。如果两个文件均未更改,则跳过。

该脚本是幂等的:多次运行会产生相同的结果,并且仅在发生实际更改时才重新加载 Docker。

注意: --privileged 容器会绕过所有 seccomp 配置文件,无论此配置如何。请单独审计您的 Compose 文件和特权容器的运行命令。

要求

  • Python 3.12+
  • 宿主机上运行的 Docker Engine(非 Docker Desktop)
  • PATH 中的 docker CLI
  • PATH 中的 curl(仅后备)
  • systemctl(systemd 宿主机)
  • 对 /etc/seccomp 和 /etc/docker 的写入以及 systemctl reload docker 需要 root / sudo

用法

root@kitploit:~
# 应用缓解措施并验证(常规用法)
sudo python3 harden-docker-seccomp.py

# 显示将要更改的内容,不写入任何内容或重新加载 Docker
sudo python3 harden-docker-seccomp.py --dry-run

# 仅重新运行容器验证(不更改配置)
python3 harden-docker-seccomp.py --verify-only

# 详细输出
sudo python3 harden-docker-seccomp.py --verbose

预期输出(首次运行)

root@kitploit:~
INFO Written: /etc/seccomp/docker-block-af-alg.json
INFO Updated: /etc/docker/daemon.json
INFO Reloading Docker daemon (SIGHUP)…
INFO Docker daemon reloaded.
INFO Verifying AF_ALG is blocked inside a container…
OK: AF_ALG blocked — [Errno 1] Operation not permitted
INFO All done. CVE-2026-31431 (Copy Fail) mitigation is active.

预期输出(后续运行)

root@kitploit:~
INFO Profile unchanged: /etc/seccomp/docker-block-af-alg.json
INFO daemon.json already configured correctly.
INFO No changes — Docker daemon reload not required.
INFO Verifying AF_ALG is blocked inside a container…
OK: AF_ALG blocked — [Errno 1] Operation not permitted
INFO All done. CVE-2026-31431 (Copy Fail) mitigation is active.

退出代码

代码含义
0成功——缓解措施已生效
1脚本未以 root 身份运行(修补时),或发生不可恢复的错误
2验证失败——AF_ALG 未被阻止

Kubernetes

Kubernetes Pod 共享宿主内核,因此受影响的节点上的任何 Pod 都可以访问相同的 AF_ALG 套接字原语。RuntimeDefault seccomp 不够——测试集群显示,在 PSS Restricted 下准入的 Pod 仍然可以打开 AF_ALG 套接字。需要使用带有显式拒绝规则的 Localhost 配置文件。

缓解措施需要两件事:配置文件 JSON 存在于每个节点的文件系统上,并且每个 Pod 规范都引用它。以下各节涵盖两者,包括如何在不修改单个 Pod 规范的情况下全局注入配置文件。

步骤 1 — 将配置文件分发到每个节点

kubelet 相对于其 seccomp 根目录解析 Localhost seccomp 配置文件,默认根目录为 /var/lib/kubelet/seccomp。配置文件必须存在于可能调度工作负载的每个节点上的该路径。

应用此仓库中的 ConfigMap 和 DaemonSet:

root@kitploit:~
kubectl apply -f templates/configmap-seccomp-profile.yaml
kubectl apply -f templates/daemonset-distribute-profile.yaml

DaemonSet 运行一个 init 容器,将配置文件从 ConfigMap 复制到节点的 kubelet seccomp 根目录,然后停放一个最小的 pause 容器,使 Pod 保持可见以进行健康监控。它容忍所有污点,因此也会在控制平面节点上运行。

非标准 kubelet seccomp 根目录: RKE2 使用 /var/lib/rancher/rke2/agent/kubelet/seccomp。在应用前,通过设置 DaemonSet init 容器环境中的 NODE_SECCOMP_ROOT 来覆盖该路径。

验证文件是否存在于节点上:

root@kitploit:~
kubectl -n kube-system exec -it \
  $(kubectl -n kube-system get pod -l app.kubernetes.io/name=distribute-af-alg-seccomp \
    -o jsonpath='{.items[0].metadata.name}') -- \
  cat /var/lib/kubelet/seccomp/block-af-alg.json

步骤 2 — 将配置文件注入每个 Pod(无需修改 Pod 规范)

与其修改单个 Pod 规范或 Helm chart,不如使用变更准入 Webhook 在准入时自动注入 seccompProfile。提供两个选项:Kyverno 和 OPA Gatekeeper。

两种方法仅在 Pod 尚未声明配置文件时才注入,因此具有显式配置文件的 Pod 保持不变。

重要: 现有运行中的 Pod 不会被追溯变更。应用策略后,滚动重启您的部署以获取注入的配置文件:

root@kitploit:~
kubectl rollout restart deployment -A

选项 A — Kyverno

此模板使用 MutatingPolicy API(policies.kyverno.io/v1),该 API 在 Kyverno 1.17 中达到 GA。旧版 ClusterPolicy API(kyverno.io/v1)已在 Kyverno 1.17(2026 年 1 月)中弃用,并计划在 1.20(2026 年 10 月)中移除;请勿将其用于新策略。

matchConditions CEL 表达式在变更前检查 seccompProfile 是否不存在,因此已声明配置文件的 Pod 保持不变。

root@kitploit:~
# 安装 Kyverno(如果尚未安装)
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm upgrade --install kyverno kyverno/kyverno -n kyverno --create-namespace

# 应用策略
kubectl apply -f templates/kyverno-mutate-seccomp.yaml

验证新 Pod 是否收到注入的配置文件:

root@kitploit:~
kubectl run test --image=busybox --restart=Never -- sleep 30
kubectl get pod test -o jsonpath='{.spec.securityContext.seccompProfile}'
# Expected: {"localhostProfile":"block-af-alg.json","type":"Localhost"}
kubectl delete pod test

参见 templates/kyverno-mutate-seccomp.yaml。

选项 B — OPA Gatekeeper

Gatekeeper 的 Assign 变更 CRD 使用 pathTests 条件,仅在 spec.securityContext.seccompProfile 不存在时注入配置文件。自 Gatekeeper 3.10+ 起,变更功能已稳定;无需功能标志。

root@kitploit:~
# 安装 Gatekeeper(如果尚未安装)
helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
helm repo update
helm install -n gatekeeper-system gatekeeper gatekeeper/gatekeeper \
  --create-namespace

# 应用变更
kubectl apply -f templates/gatekeeper-assign-seccomp.yaml

验证:

root@kitploit:~
kubectl run test --image=busybox --restart=Never -- sleep 30
kubectl get pod test -o jsonpath='{.spec.securityContext.seccompProfile}'
# Expected: {"localhostProfile":"block-af-alg.json","type":"Localhost"}
kubectl delete pod test

参见 templates/gatekeeper-assign-seccomp.yaml。

Gatekeeper 与 Kyverno: Assign 方法在字段级别操作,需要启用 Gatekeeper 变更 Webhook。Kyverno 的 MutatingPolicy 配合 CEL matchCondition 可内联处理条件。两者达到相同的结果——优先选择集群中已部署的方案。

此方案未涵盖的内容

具有 hostPID: true、hostNetwork: true 或 securityContext.privileged: true 的 Pod 具有 seccomp 单独无法完全控制的提升访问权限。请单独审计这些工作负载,并尽可能移除特权。

模板设计说明

ConfigMap 作为事实来源。 配置文件 JSON 位于 configmap-seccomp-profile.yaml 中,而不是嵌入 DaemonSet 或在多个文件中重复。DaemonSet 挂载它并将其复制到节点。更新配置文件意味着编辑一个 ConfigMap 并重启 DaemonSet Pod——无需更改其他文件。

DaemonSet 使用 system-node-critical 优先级。 这确保分发 Pod 不会在其保护的工作负载被调度之前被驱逐,否则会导致节点缺少配置文件,Pod 卡在 CreateContainerError 状态。

Gatekeeper 排除 kube-system 和 gatekeeper-system。 将 Localhost 配置文件注入可能早于 DaemonSet 安装的系统 Pod,如果文件尚未存在于节点上,则存在配置文件引用损坏的风险。Kyverno 策略不需要此排除,因为 Kyverno 更优雅地处理 Webhook 排序,但如有需要,也可以在那里添加 exclude 规则。

条件注入,而非覆盖。 Kyverno MutatingPolicy 的 CEL matchCondition 和 Gatekeeper 的 MustNotExist 路径测试都意味着准入策略仅在 Pod 没有现有 seccompProfile 时生效。已声明自己配置文件的工作负载——包括那些通过自定义允许列表合法需要 AF_ALG 的工作负载——保持不变。

参考

  • https://copy.fail — 原始研究人员公告(Xint)
  • https://cert.europa.eu/publications/security-advisories/2026-005/ — CERT-EU 公告
  • https://www.cve.org/CVERecord?id=CVE-2026-31431 — CVE 记录
  • https://security-tracker.debian.org/tracker/CVE-2026-31431 — Debian 安全跟踪器
  • https://docs.docker.com/engine/security/seccomp/ — Docker seccomp 文档
  • https://github.com/moby/profiles — 规范的 Docker 默认 seccomp 配置文件
  • https://kyverno.io/docs/kyverno-policies/ — Kyverno 策略文档
  • https://open-policy-agent.github.io/gatekeeper/website/docs/mutation/ — Gatekeeper 变更文档

是的,Claude 完成了大部分工作,这里是聊天记录

https://gist.github.com/devstuff/3ff3ca0139e2a2da7f1ee5875802f76f

下载工具
  • 验证阻止是否生效,在容器内运行探测,无论上述步骤是否进行了任何更改。