scanning-kubernetes-manifests-with-kubesec
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseScanning Kubernetes Manifests with Kubesec
使用Kubesec扫描Kubernetes资源清单
Overview
概述
Kubesec is an open-source security risk analysis tool developed by ControlPlane that inspects Kubernetes resource manifests for common exploitable risks such as privilege escalation, writable host mounts, and excessive capabilities. It assigns a numerical security score to each resource and provides actionable recommendations for hardening. Kubesec can be used as a CLI binary, Docker container, kubectl plugin, admission webhook, or REST API endpoint.
Kubesec是ControlPlane开发的一款开源安全风险分析工具,用于检查Kubernetes资源清单中常见的可利用风险,如权限提升、可写主机挂载和过度权限。它为每个资源分配一个数值安全评分,并提供可操作的加固建议。Kubesec可作为CLI二进制文件、Docker容器、kubectl插件、准入Webhook或REST API端点使用。
When to Use
使用场景
- When conducting security assessments that involve scanning kubernetes manifests with kubesec
- When following incident response procedures for related security events
- When performing scheduled security testing or auditing activities
- When validating security controls through hands-on testing
- 开展涉及用Kubesec扫描Kubernetes资源清单的安全评估时
- 遵循相关安全事件的应急响应流程时
- 执行定期安全测试或审计活动时
- 通过实操测试验证安全控制措施时
Prerequisites
前置条件
- Kubernetes manifest files (YAML/JSON) for Deployments, Pods, DaemonSets, StatefulSets
- Docker or Go runtime for local installation
- kubectl access for scanning live cluster resources
- CI/CD pipeline access for automated scanning integration
- 用于Deployment、Pod、DaemonSet、StatefulSet的Kubernetes资源清单文件(YAML/JSON格式)
- 用于本地安装的Docker或Go运行时
- 用于扫描集群实时资源的kubectl访问权限
- 用于集成自动化扫描的CI/CD流水线访问权限
Core Concepts
核心概念
Security Scoring System
安全评分系统
Kubesec assigns a score to each Kubernetes resource based on security checks:
- Positive scores: Awarded for security-enhancing configurations (readOnlyRootFilesystem, runAsNonRoot)
- Zero or negative scores: Indicate missing security controls or dangerous configurations
- Critical advisories: Flagged configurations that represent immediate security risks
Kubesec基于安全检查为每个Kubernetes资源分配评分:
- 正分数:授予具备安全增强配置的资源(如ReadOnlyRootFilesystem、runAsNonRoot)
- 零分或负分数:表示缺少安全控制措施或存在危险配置
- 关键警告:标记代表即时安全风险的配置
Check Categories
检查类别
- Privilege Controls: Checks for privileged containers, host PID/network access, root execution
- Capabilities: Identifies excessive Linux capabilities (SYS_ADMIN, NET_RAW)
- Volume Mounts: Detects dangerous host path mounts and writable sensitive paths
- Resource Limits: Validates presence of CPU/memory resource constraints
- Security Context: Verifies seccomp profiles, AppArmor annotations, SELinux contexts
- 权限控制:检查特权容器、主机PID/网络访问、以root用户运行等情况
- 权限能力:识别过度的Linux权限能力(如SYS_ADMIN、NET_RAW)
- 卷挂载:检测危险的主机路径挂载和可写敏感路径
- 资源限制:验证是否存在CPU/内存资源约束
- 安全上下文:检查seccomp配置文件、AppArmor注解、SELinux上下文
Installation
安装
Binary Installation
二进制安装
bash
undefinedbash
undefinedLinux/macOS
Linux/macOS
curl -sSL https://github.com/controlplaneio/kubesec/releases/latest/download/kubesec_linux_amd64.tar.gz |
tar xz -C /usr/local/bin/ kubesec
tar xz -C /usr/local/bin/ kubesec
curl -sSL https://github.com/controlplaneio/kubesec/releases/latest/download/kubesec_linux_amd64.tar.gz |
tar xz -C /usr/local/bin/ kubesec
tar xz -C /usr/local/bin/ kubesec
Verify installation
验证安装
kubesec version
undefinedkubesec version
undefinedDocker Installation
Docker安装
bash
docker pull kubesec/kubesec:v2bash
docker pull kubesec/kubesec:v2Scan a manifest file
扫描资源清单文件
docker run -i kubesec/kubesec:v2 scan /dev/stdin < deployment.yaml
undefineddocker run -i kubesec/kubesec:v2 scan /dev/stdin < deployment.yaml
undefinedkubectl Plugin
kubectl插件
bash
kubectl krew install kubesec-scan
kubectl kubesec-scan pod mypod -n defaultbash
kubectl krew install kubesec-scan
kubectl kubesec-scan pod mypod -n defaultPractical Scanning
实操扫描
Scanning a Single Manifest
扫描单个资源清单
bash
undefinedbash
undefinedScan a deployment manifest
扫描Deployment资源清单
kubesec scan deployment.yaml
kubesec scan deployment.yaml
Scan with JSON output
以JSON格式输出扫描结果
kubesec scan -o json deployment.yaml
kubesec scan -o json deployment.yaml
Scan from stdin
从标准输入扫描
cat pod.yaml | kubesec scan -
undefinedcat pod.yaml | kubesec scan -
undefinedSample Output
示例输出
json
[
{
"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
}
]
}
}
]json
[
{
"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
}
]
}
}
]Scanning Multiple Resources
扫描多个资源
bash
undefinedbash
undefinedScan all YAML files in a directory
扫描目录下所有YAML文件
for file in manifests/*.yaml; do
echo "=== Scanning $file ==="
kubesec scan "$file"
done
for file in manifests/*.yaml; do
echo "=== 扫描 $file ==="
kubesec scan "$file"
done
Scan multi-document YAML
扫描多文档YAML文件
kubesec scan multi-resource.yaml
undefinedkubesec scan multi-resource.yaml
undefinedUsing the HTTP API
使用HTTP API
bash
undefinedbash
undefinedScan via the public API
通过公共API扫描
curl -sSX POST --data-binary @deployment.yaml
https://v2.kubesec.io/scan
https://v2.kubesec.io/scan
curl -sSX POST --data-binary @deployment.yaml
https://v2.kubesec.io/scan
https://v2.kubesec.io/scan
Run a local API server
运行本地API服务器
kubesec http --port 8080 &
kubesec http --port 8080 &
Scan against local server
针对本地服务器扫描
curl -sSX POST --data-binary @deployment.yaml
http://localhost:8080/scan
http://localhost:8080/scan
undefinedcurl -sSX POST --data-binary @deployment.yaml
http://localhost:8080/scan
http://localhost:8080/scan
undefinedCI/CD Integration
CI/CD集成
GitHub Actions
GitHub Actions
yaml
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 $FAILyaml
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 存在严重问题(评分: $SCORE)"
FAIL=1
fi
done
exit $FAILGitLab CI
GitLab CI
yaml
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/yaml
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 评分为 $SCORE"
cat /tmp/result.json | jq '.[0].scoring.critical'
exit 1
fi
done
artifacts:
paths:
- kubesec-results/Admission Webhook
准入Webhook
Deploy Kubesec as a ValidatingWebhookConfiguration to reject insecure manifests at deploy time:
yaml
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"]将Kubesec部署为ValidatingWebhookConfiguration,在部署阶段拒绝不安全的资源清单:
yaml
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"]Security Checks Reference
安全检查参考
Critical Checks (Negative Score)
关键检查(负分)
| Check | Selector | Risk |
|---|---|---|
| Privileged | | Full host access |
| HostPID | | Process namespace escape |
| HostNetwork | | Network namespace escape |
| SYS_ADMIN | | Near-root capability |
| 检查项 | 选择器 | 风险 |
|---|---|---|
| Privileged | | 完全主机访问权限 |
| HostPID | | 进程命名空间逃逸 |
| HostNetwork | | 网络命名空间逃逸 |
| SYS_ADMIN | | 接近root的权限能力 |
Best Practice Checks (Positive Score)
最佳实践检查(正分)
| Check | Points | Description |
|---|---|---|
| ReadOnlyRootFilesystem | +1 | Prevents filesystem writes |
| RunAsNonRoot | +1 | Non-root process execution |
| RunAsUser > 10000 | +1 | High UID reduces collision risk |
| LimitsCPU | +1 | Prevents CPU resource exhaustion |
| LimitsMemory | +1 | Prevents memory resource exhaustion |
| RequestsCPU | +1 | Ensures scheduler resource awareness |
| ServiceAccountName | +3 | Explicit service account |
| AppArmor annotation | +3 | Kernel-level MAC enforcement |
| Seccomp profile | +4 | Syscall filtering |
| 检查项 | 分值 | 描述 |
|---|---|---|
| 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 | 系统调用过滤 |