ghofranehad/k8s-security
GitHub: ghofranehad/k8s-security
这是一个利用 GitOps 构建生产级 Kubernetes 纵深防御体系的项目,集成了从镜像扫描到运行时检测的七层安全策略。
Stars: 0 | Forks: 0
# k8s-security
一个生产级的 Kubernetes 安全加固项目,展示了跨越 7 个安全层面的纵深防御。所有层面均通过 ArgoCD 使用 GitOps 进行部署和管理。旨在本地通过 [Kind](https://kind.sigs.k8s.io/) 运行 —— 无需云账户。
## 架构
```
┌─────────────────────────────────────────────────────────────────┐
│ Developer Workflow │
│ │
│ git push → Layer 1: CI/CD (Trivy) │
│ └── Blocks images with HIGH/CRITICAL CVEs │
│ └── Blocks misconfigured manifests │
└──────────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Layer 2: GitOps (ArgoCD) │
│ └── Single source of truth — this repository │
│ └── Automated sync — cluster matches Git state │
│ └── AppProject scoping — source repo restriction │
└──────────────────────────┬──────────────────────────────────────┘
│ All layers deployed and reconciled by ArgoCD
▼
┌─────────────────────────────────────────────────────────────────┐
│ Layer 0: Infrastructure (Kind + Calico CNI) │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Layer 3: Admission Control (Kyverno) │ │
│ │ └── Mutate: inject secure defaults into every pod │ │
│ │ └── Validate: deny non-compliant workloads │ │
│ │ └── Generate: auto-create NetworkPolicies per ns │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Layer 4: Pod Security Standards (native Kubernetes) │ │
│ │ └── restricted: app namespaces │ │
│ │ └── baseline: infra namespaces │ │
│ │ └── privileged: security tools (Falco) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Layer 5: Network Segmentation (Calico + NetworkPolicy) │ │
│ │ └── Default deny-all generated per namespace │ │
│ │ └── Explicit allow rules per workload │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Layer 6: Runtime Detection (Falco) │ │
│ │ └── Shell spawned in container │ │
│ │ └── Sensitive file read │ │
│ │ └── Unexpected outbound connection │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Layer 7: Secrets Management (Sealed Secrets) │ │
│ │ └── No plaintext secrets in Git │ │
│ │ └── Encrypted at rest, decrypted only in-cluster │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
## 安全覆盖
| Layer | Tool | What it prevents |
|-------|------|-----------------|
| CI/CD | Trivy + GitHub Actions | 易受攻击的镜像和配置错误的清单到达集群 |
| GitOps | ArgoCD | 未授权的更改 —— 集群状态始终与 Git 一致 |
| Admission | Kyverno | Root 容器、特权 Pod、缺少资源限制、可写的 rootfs |
| Pod Security | PSS (native) | 特权容器、主机命名空间访问、不安全的卷类型 |
| Network | Calico + NetworkPolicy | Pod 和命名空间之间的横向移动 |
| Runtime | Falco | 正在进行的攻击 —— shell 生成、凭证访问、数据外泄 |
| Secrets | Sealed Secrets | 明文凭证被提交到 Git |
## 快速开始
### 先决条件
```
kind version # >= 0.20
docker info # Docker must be running
kubectl version --client
helm version # >= 3.0
```
### 1. 创建集群
```
kind create cluster --config kind/cluster-config.yaml
```
### 2. 安装 Calico CNI
```
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/custom-resources.yaml
kubectl wait --timeout=120s --for=condition=Ready pods --all -n calico-system
```
### 3. 安装 ArgoCD
```
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl wait --timeout=120s --for=condition=Ready pods --all -n argocd
```
### 4. 引导 GitOps
```
kubectl apply -f argocd/projects/security-project.yaml
kubectl apply -f argocd/apps/main.yaml
```
ArgoCD 将自动部署本仓库中的所有安全层。访问 UI:
```
kubectl port-forward svc/argocd-server -n argocd 8080:443
# Username: admin
# Password:
kubectl get secret argocd-initial-admin-secret -n argocd \
-o jsonpath='{.data.password}' | base64 -d
```
## 项目结构
```
k8s-security/
├── .github/workflows/ # Layer 1 — Trivy image + manifest scanning
├── kind/ # Layer 0 — Cluster bootstrap (Kind + Calico)
├── argocd/
│ ├── apps/ # Layer 2 — ArgoCD Applications (app-of-apps)
│ └── projects/ # Layer 2 — AppProject (source restriction)
├── kyverno/
│ └── policies/
│ ├── validate/ # Layer 3 — Deny non-compliant workloads
│ ├── mutate/ # Layer 3 — Inject secure defaults
│ └── generate/ # Layer 3 — Auto-create NetworkPolicies
├── pod-security/ # Layer 4 — PSS namespace labels
├── network-policies/ # Layer 5 — Explicit allow rules per workload
├── falco/ # Layer 6 — Runtime detection + custom rules
├── sealed-secrets/ # Layer 7 — Encrypted secrets
├── tests/
│ └── violations/ # Manifests that test policy enforcement
└── docs/
└── adr/ # Architecture Decision Records
```
## 策略详情
### Kyverno — 变更策略
| Policy | Effect |
|--------|--------|
| `add-default-securitycontext` | 向 container 和 initContainer 注入 `runAsNonRoot`、`runAsUser: 1000`、`readOnlyRootFilesystem`、`allowPrivilegeEscalation: false`、`capabilities.drop: ALL`、`seccompProfile: RuntimeDefault` |
| `add-resource-limits` | 向 container 和 initContainer 注入 `cpu: 100m`、`memory: 256Mi` 限制 |
基础设施命名空间(kyverno、argocd、falco、calico-system 等)被排除在外。
### Kyverno — 验证策略
| Policy | Action |
|--------|--------|
| `block-root-containers` | 拒绝 `runAsNonRoot != true` 的 Pod |
| `block-privileged-containers` | 拒绝 `privileged: true` 的 Pod |
| `require-resource-limits` | 拒绝没有 CPU 和内存限制的 Pod |
| `require-readonly-rootfs` | 拒绝 root 文件系统可写的 Pod |
### Falco — 自定义规则
| Rule | Detects |
|------|---------|
| Shell Spawned in Container | 在运行中的容器内执行了 `sh`、`bash`、`zsh` |
| Sensitive File Read | 访问 `/etc/shadow`、`etc/passwd`、`/root/.ssh/*` |
| Unexpected Outbound Connection | 非标准端口上的出站流量 |
## 测试策略执行
```
# 应用违规清单 — 它们运行是因为变更强制了安全默认值
kubectl apply -f tests/violations/
# 要直接测试拒绝行为,请先禁用变更:
kubectl delete mutatingpolicy add-default-securitycontext
kubectl apply -f tests/violations/root-container.yaml
# → Error: pods is forbidden — runAsNonRoot must be true
# 恢复变更:
kubectl apply -f kyverno/policies/mutate/add-default-securitycontext.yaml
```
## 设计决策
| ADR | Decision |
|-----|----------|
| [ADR-001](docs/adr/ADR-001-cluster-setup.md) | Kind + Calico;kubeadm 加固的权衡 |
| [ADR-002](docs/adr/ADR-002-falco-wsl2-kyverno-exclusion.md) | Falco WSL2 限制 + Kyverno 命名空间排除策略 |
| [ADR-003](docs/adr/ADR-003-kyverno-vs-opa.md) | 选择 Kyverno 而非 OPA/Gatekeeper |
| [ADR-004](docs/adr/ADR-004-calico-vs-cilium-flannel.md) | 选择 Calico 而非 Cilium/Flannel |
| [ADR-005](docs/adr/ADR-005-sealed-secrets-vs-eso.md) | 选择 Sealed Secrets 而非 External Secrets Operator |
MITRE ATT&CK 覆盖范围:[docs/MITRE-MAPPING.md](docs/MITRE-MAPPING.md)
威胁模型:[docs/THREAT-MODEL.md](docs/THREAT-MODEL.md)
CIS Benchmark 映射:[docs/CIS-BENCHMARK-MAPPING.md](docs/CIS-BENCHMARK-MAPPING.md)
## 作者
**Ghofrane Haddedi** — DevSecOps 工程师
[GitHub](https://github.com/ghofranehad) · CKA · CKS
标签:APT组织, ArgoCD, DevSecOps, GitHub Advanced Security, GitOps, JSONLines, Kind, Web截图, 上游代理, 子域名字典, 子域名突变, 安全加固, 容器安全, 本地集群, 活动识别, 深度防御, 镜像扫描, 零信任