关于 scanning-kubernetes-manifests-with-kubesec
面向使用 Kubesec 扫描 Kubernetes 清单的团队的开源安全技能,介绍风险评分和可操作的加固检查,并涵盖 CLI、Docker、kubectl、API、CI/CD 与准入 Webhook 用法。
主要功能
- 01Kubernetes 资源风险评分
- 02特权与能力检查
- 03卷挂载和资源限制检查
- 04安全上下文检查
- 05CLI、Docker 与 API 扫描
- 06CI/CD 与准入 Webhook 集成
适用场景
- 01审计 Kubernetes 清单
- 02在 CI/CD 中扫描配置
- 03部署时拒绝不安全清单
- 04检查集群中的实时资源
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill scanning-kubernetes-manifests-with-kubesec安装后在 Claude Code 中输入/scanning-kubernetes-manifests-with-kubesec确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEassets/template.mdreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.pyprocess.py详细介绍
使用 Kubesec 扫描 Kubernetes 清单
概述
Kubesec 是由 ControlPlane 开发的一款开源安全风险分析工具,用于检查 Kubernetes 资源清单中常见的可利用风险,例如权限提升、可写宿主机挂载以及过多的能力(capabilities)。它为每个资源分配一个数值型安全评分,并提供可操作的加固建议。Kubesec 可作为命令行二进制文件、Docker 容器、kubectl 插件、准入 Webhook 或 REST API 端点使用。
何时使用
- 当开展涉及使用 Kubesec 扫描 Kubernetes 清单的安全评估时
- 当遵循相关安全事件的事件响应流程时
- 当执行计划内的安全测试或审计活动时
- 当通过动手测试验证安全控制措施时
前置条件
- 用于 Deployment、Pod、DaemonSet、StatefulSet 的 Kubernetes 清单文件(YAML/JSON)
- 用于本地安装的 Docker 或 Go 运行时
- 用于扫描实时集群资源的 kubectl 访问权限
- 用于自动化扫描集成的 CI/CD 流水线访问权限
核心概念
安全评分系统
Kubesec 根据安全检查为每个 Kubernetes 资源分配一个评分:
- 正分:因增强安全的配置(readOnlyRootFilesystem、runAsNonRoot)而获得
- 零分或负分:表明缺少安全控制措施或存在危险配置
- 严重警告:被标记为构成即时安全风险的配置
检查类别
- 权限控制:检查特权容器、宿主机 PID/网络访问、root 执行
- 能力(Capabilities):识别过多的 Linux 能力(SYS_ADMIN、NET_RAW)
- 卷挂载:检测危险的宿主机路径挂载和可写的敏感路径
- 资源限制:验证是否存在 CPU/内存资源约束
- 安全上下文:验证 seccomp 配置文件、AppArmor 注解、SELinux 上下文
安装
二进制安装
# Linux/macOS
curl -sSL https://github.com/controlplaneio/kubesec/releases/latest/download/kubesec_linux_amd64.tar.gz | \
tar xz -C /usr/local/bin/ kubesec
# Verify installation
kubesec version
Docker 安装
docker pull kubesec/kubesec:v2
# Scan a manifest file
docker run -i kubesec/kubesec:v2 scan /dev/stdin < deployment.yaml
kubectl 插件
kubectl krew install kubesec-scan
kubectl kubesec-scan pod mypod -n default
实际扫描
扫描单个清单
# Scan a deployment manifest
kubesec scan deployment.yaml
# Scan with JSON output
kubesec scan -o json deployment.yaml
# Scan from stdin
cat pod.yaml | kubesec scan -
示例输出
[
{
"object": "Pod/web-app.default",
"valid": true,
"fileName": "pod.yaml",
"message": "Passed with a score of 3 points",
"score": 3,
"scoring": {
"passed": [
{
"id": "ReadOnlyRootFilesystem",
"selector": "containers[] .securityContext .readOnlyRootFilesystem == true",
"reason": "An immutable root filesystem prevents applications from writing to their local disk",
"points": 1
},
{
"id": "RunAsNonRoot",
"selector": "containers[] .securityContext .runAsNonRoot == true",
"reason": "Force the running image to run as a non-root user",
"points": 1
},
{
"id": "LimitsCPU",
"selector": "containers[] .resources .limits .cpu",
"reason": "Enforcing CPU limits prevents DOS via resource exhaustion",
"points": 1
}
],
"advise": [
{
"id": "ApparmorAny",
"selector": "metadata .annotations .\"container.apparmor.security.beta.kubernetes.io/nginx\"",
"reason": "Well defined AppArmor policies reduce the attack surface of the container",
"points": 3
},
{
"id": "ServiceAccountName",
"selector": ".spec .serviceAccountName",
"reason": "Service accounts restrict Kubernetes API access and should be configured",
"points": 3
}
]
}
}
]
扫描多个资源
# Scan all YAML files in a directory
for file in manifests/*.yaml; do
echo "=== Scanning $file ==="
kubesec scan "$file"
done
# Scan multi-document YAML
kubesec scan multi-resource.yaml
使用 HTTP API
# Scan via the public API
curl -sSX POST --data-binary @deployment.yaml \
https://v2.kubesec.io/scan
# Run a local API server
kubesec http --port 8080 &
# Scan against local server
curl -sSX POST --data-binary @deployment.yaml \
http://localhost:8080/scan
CI/CD 集成
GitHub Actions
name: Kubesec Scan
on: [pull_request]
jobs:
kubesec:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Kubesec
run: |
curl -sSL https://github.com/controlplaneio/kubesec/releases/latest/download/kubesec_linux_amd64.tar.gz | \
tar xz -C /usr/local/bin/ kubesec
- name: Scan Manifests
run: |
FAIL=0
for file in k8s/*.yaml; do
SCORE=$(kubesec scan "$file" | jq '.[0].score')
echo "$file: score=$SCORE"
if [ "$SCORE" -lt 0 ]; then
echo "FAIL: $file has critical issues (score: $SCORE)"
FAIL=1
fi
done
exit $FAIL
GitLab CI
kubesec-scan:
stage: security
image: kubesec/kubesec:v2
script:
- |
for file in k8s/*.yaml; do
kubesec scan "$file" > /tmp/result.json
SCORE=$(cat /tmp/result.json | jq '.[0].score')
if [ "$SCORE" -lt 0 ]; then
echo "CRITICAL: $file scored $SCORE"
cat /tmp/result.json | jq '.[0].scoring.critical'
exit 1
fi
done
artifacts:
paths:
- kubesec-results/
准入 Webhook
将 Kubesec 部署为 ValidatingWebhookConfiguration,以便在部署时拒绝不安全的清单:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: kubesec-webhook
webhooks:
- name: kubesec.controlplane.io
rules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
- apiGroups: ["apps"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["deployments", "daemonsets", "statefulsets"]
clientConfig:
service:
name: kubesec-webhook
namespace: kube-system
path: /scan
failurePolicy: Fail
sideEffects: None
admissionReviewVersions: ["v1"]
安全检查参考
关键检查(负分)
| 检查 | 选择器 | 风险 |
|---|---|---|
| Privileged | securityContext.privileged == true | 完全宿主机访问权限 |
| HostPID | spec.hostPID == true | 进程命名空间逃逸 |
| HostNetwork | spec.hostNetwork == true | 网络命名空间逃逸 |
| SYS_ADMIN | capabilities.add contains SYS_ADMIN | 接近 root 的能力 |
最佳实践检查(正分)
| 检查 | 得分 | 描述 |
|---|---|---|
| ReadOnlyRootFilesystem | +1 | 防止文件系统写入 |
| RunAsNonRoot | +1 | 以非 root 进程执行 |
| RunAsUser > 10000 | +1 | 高 UID 降低冲突风险 |
| LimitsCPU | +1 | 防止 CPU 资源耗尽 |
| LimitsMemory | +1 | 防止内存资源耗尽 |
| RequestsCPU | +1 | 确保调度器感知资源需求 |
| ServiceAccountName | +3 | 明确的服务账户 |
| AppArmor annotation | +3 | 内核级 MAC 强制执行 |
| Seccomp profile | +4 | 系统调用过滤 |
参考
评论
支持 Markdown