云原生安全深度理论知识
云原生安全深度理论知识
学习深度: ⭐⭐⭐⭐ 文档类型: 纯理论知识(无代码实践) 权威参考: CNCF、Falco、HashiCorp Vault、NIST、CIS Benchmarks
目录
云原生安全基础
1.1 云原生安全挑战
传统安全 vs 云原生安全
graph TB
subgraph Traditional["传统应用安全模型"]
direction TB
Firewall["网络边界(防火墙)"]
subgraph AppServer["应用服务器(长期运行)"]
Feature1["• 静态IP"]
Feature2["• 可预测端口"]
Feature3["• 手动配置"]
end
Firewall --> AppServer
end
subgraph TraditionalFeatures["传统模型特点"]
T1["边界清晰"]
T2["资源静态"]
T3["部署频率低"]
end
subgraph CloudNative["云原生挑战"]
direction TB
Mesh["微服务网格"]
subgraph Pods["Pod集群"]
Pod1["Pod1"]
Pod2["Pod2"]
Pod3["Pod3"]
Pod4["Pod4"]
end
Dynamic["动态IP、动态端口、自动扩缩容"]
Mesh --> Pods
Pods --> Dynamic
end
subgraph Challenges["新挑战"]
C1["❌ 边界消失(东西向流量占80%+)"]
C2["❌ 资源动态(Pod生命周期秒级)"]
C3["❌ 部署频繁(每天数百次)"]
C4["❌ 攻击面扩大(容器、编排器、镜像仓库)"]
C5["❌ 复杂性爆炸(微服务+依赖)"]
end
Traditional -.对比.-> CloudNative
style Traditional fill:#e1f5ff
style CloudNative fill:#fff3e0
style Challenges fill:#ffebee
style TraditionalFeatures fill:#e8f5e9
1.2 云原生安全的4C模型
CNCF 安全层次模型:
graph TB
subgraph Layer1["Cloud (云基础设施)"]
direction TB
Cloud1["物理安全"]
Cloud2["网络安全"]
Cloud3["IAM (身份访问管理)"]
end
subgraph Layer2["Cluster (集群)"]
direction TB
Cluster1["Kubernetes RBAC"]
Cluster2["网络策略"]
Cluster3["Pod安全策略"]
end
subgraph Layer3["Container (容器)"]
direction TB
Container1["镜像扫描"]
Container2["运行时保护"]
Container3["资源限制"]
end
subgraph Layer4["Code (代码)"]
direction TB
Code1["依赖扫描"]
Code2["SAST/DAST"]
Code3["Secrets检测"]
end
subgraph LayerRelation["层次关系"]
R1["每层依赖下层安全"]
R2["攻击可在任何层发生"]
R3["深度防御 (Defense in Depth)"]
end
Layer1 --> Layer2
Layer2 --> Layer3
Layer3 --> Layer4
style Layer1 fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style Layer2 fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
style Layer3 fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style Layer4 fill:#fce4ec,stroke:#c2185b,stroke-width:2px
style LayerRelation fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
1.3 零信任架构在云原生中的应用
sequenceDiagram
participant SA as Service A<br/>(mTLS证书: A)
participant SB as Service B<br/>(验证证书A, 检查权限)
Note over SA,SB: 零信任原则应用
SA->>SB: 1. TLS握手
SB->>SA: 2. 请求客户端证书
SA->>SB: 3. 提供证书A
SB->>SB: 4. 验证证书A
SB->>SB: 5. 提取Service Account
SB->>SB: 6. RBAC授权检查
SB->>SB: 7. Network Policy过滤
alt 验证成功
SB-->>SA: 允许访问
else 验证失败
SB-->>SA: 拒绝访问
end
Note over SA,SB: 每个请求多层验证:<br/>1. mTLS双向认证<br/>2. 提取Service Account<br/>3. RBAC授权检查<br/>4. Network Policy过滤
style SA fill:#e3f2fd,stroke:#1976d2
style SB fill:#e8f5e9,stroke:#388e3c
零信任四大原则:
-
永不信任网络位置:
- Pod IP动态分配 → 不能依赖IP白名单
- 解决方案: 基于身份的访问控制 (Service Mesh mTLS)
-
微分段 (Micro-Segmentation):
- 每个微服务独立隔离
- 解决方案: Network Policy 限制Pod间通信
-
持续验证:
- 每个请求都验证身份
- 解决方案: Istio/Linkerd 自动注入认证
-
最小权限:
- Pod仅获得必需权限
- 解决方案: RBAC + Pod Security Standards
容器安全
2.1 容器隔离原理
Linux Namespace (命名空间)
定义: 隔离进程视图,让容器看到独立的系统资源。
7种命名空间:
-
PID Namespace (进程隔离):
- 容器内 PID 1 (init)
- 主机看到真实 PID (如 12345)
- 容器看不到主机进程
-
Network Namespace (网络隔离):
- 独立网卡、IP、路由表
- 容器间网络隔离
-
Mount Namespace (文件系统隔离):
- 独立挂载点
- 容器看到自己的根文件系统
-
UTS Namespace (主机名隔离):
- 独立主机名
- 容器可设置hostname
-
IPC Namespace (进程间通信隔离):
- 隔离共享内存、信号量
- 防止容器间IPC干扰
-
User Namespace (用户隔离):
- 容器内 root ≠ 主机 root
- UID/GID 映射
-
Cgroup Namespace (资源视图隔离):
- 隔离 cgroup 视图
示例: PID Namespace
主机视角:
PID 1: systemd
PID 12345: nginx (容器进程)
容器视角:
PID 1: nginx (以为自己是init)
Cgroups (控制组)
定义: 限制和监控容器资源使用。
资源类型:
-
CPU:
- cpu.shares: CPU权重 (默认1024)
- cpu.cfs_quota_us: CPU配额 (微秒)
- 示例: 限制容器最多使用50% CPU
-
Memory:
- memory.limit_in_bytes: 内存上限
- memory.oom_control: OOM行为
- 示例: 限制容器最多512MB内存
-
Block I/O:
- blkio.weight: I/O权重
- blkio.throttle.read_bps_device: 读取速率
- 示例: 限制磁盘读取10MB/s
-
Network (通过 tc):
- 带宽限制
- 示例: 限制容器100Mbps网速
资源爆炸的后果:
- CPU饱和 → 其他容器卡顿
- 内存溢出 → OOM Killer杀进程
- 磁盘I/O满 → 系统不响应
Cgroups防护:
- 硬限制 (limit): 超过即拒绝
- 软限制 (request): 保证最小资源
2.2 容器镜像安全
镜像构建安全
安全层次:
Dockerfile 安全最佳实践:
❌ 不安全:
FROM ubuntu:latest
RUN apt-get update && apt-get install -y nginx
COPY app /app
USER root
ENV SECRET_KEY=hardcoded_secret
问题:
- latest 标签不确定(无法重现)
- root 用户运行(权限过高)
- 硬编码 secret
✅ 安全:
FROM ubuntu:22.04@sha256:abc123... # 固定版本+digest
RUN apt-get update && apt-get install -y nginx=1.18.0 \
&& rm -rf /var/lib/apt/lists/* # 清理缓存减小镜像
RUN useradd -m -u 1000 appuser # 创建非特权用户
USER appuser # 非root运行
ENV SECRET_KEY=/run/secrets/key # 引用外部secret
改进:
- 固定版本(可重现)
- 非特权用户
- 不包含 secrets
- 最小化镜像(多阶段构建)
多阶段构建 (Multi-stage Build):
目的: 减小最终镜像大小,去除构建工具
示例:
# 阶段1: 构建
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# 阶段2: 运行
FROM alpine:3.18 # 最小基础镜像
COPY --from=builder /app/myapp /
USER 1000
CMD ["/myapp"]
对比:
- 传统: golang:1.21 镜像 (800MB)
- 多阶段: alpine + 二进制 (20MB)
- 减小 97.5%
安全好处:
- 攻击面小(无编译器、调试工具)
- 漏洞少
- 扫描快
2.3 镜像扫描
漏洞扫描原理
扫描流程:
-
镜像解析:
- 提取所有层 (layers)
- 识别包管理器 (apt, yum, apk)
-
包清单提取:
- 列出所有已安装包及版本
- 示例: nginx 1.18.0, openssl 1.1.1k
-
漏洞数据库匹配:
- 查询 CVE 数据库
- 匹配包名 + 版本
-
风险评分:
- CVSS 分数 (0-10)
- 严重性: Critical, High, Medium, Low
-
生成报告:
- 漏洞列表
- 修复建议
扫描工具对比:
| 工具 | 数据源 | 语言支持 | 性能 | 推荐指数 |
|---|---|---|---|---|
| Trivy | 多源 | 多语言 | 快 | ⭐⭐⭐⭐⭐ |
| Grype | Syft + CVE | 多语言 | 快 | ⭐⭐⭐⭐ |
| Clair | NVD | 操作系统包 | 中 | ⭐⭐⭐ |
| Snyk | 私有DB | 多语言 | 快 | ⭐⭐⭐⭐ (商业) |
Trivy 示例输出:
nginx:1.18.0 (ubuntu 20.04)
├─ CVE-2021-23017 (CRITICAL, CVSS 9.8)
│ • 受影响包: nginx < 1.20.1
│ • 修复: 升级到 nginx:1.20.1
├─ CVE-2020-12345 (HIGH, CVSS 7.5)
│ • 受影响包: openssl < 1.1.1l
│ • 修复: 更新基础镜像
└─ 总计: 2 Critical, 5 High, 12 Medium
镜像签名与验证
问题: 如何确保镜像未被篡改?
方案1: Docker Content Trust (DCT)
原理: Notary 签名
流程:
-
推送镜像时签名:
docker push myregistry.com/app:v1.0- 生成签名(使用私钥)
- 存储到 Notary 服务器
-
拉取镜像时验证:
docker pull myregistry.com/app:v1.0- 下载签名
- 验证签名(使用公钥)
- 签名有效 → 拉取镜像
- 签名无效 → 拒绝
好处:
- 防止中间人攻击
- 确保镜像来源可信
方案2: Sigstore Cosign
特点:
- 无需维护密钥服务器
- 支持 Keyless 签名 (OIDC)
- 透明日志 (Rekor)
签名验证:
cosign verify myregistry.com/app:v1.0
- 查询透明日志
- 验证签名
- 检查证书链
2.4 容器运行时安全
运行时威胁检测 (Falco)
Falco 原理: 基于系统调用监控异常行为。
graph TB
subgraph ContainerProc["容器进程"]
Nginx["nginx"]
App["app"]
end
subgraph Kernel["Linux Kernel (系统调用)"]
Syscalls["系统调用接口"]
end
subgraph SyscallCapture["系统调用捕获"]
eBPF["eBPF 探针"]
KernelModule["内核模块"]
end
subgraph FalcoEngine["Falco 引擎"]
RuleEngine["规则引擎"]
end
ContainerProc --> Kernel
Kernel --> SyscallCapture
SyscallCapture --> FalcoEngine
style ContainerProc fill:#fce4ec,stroke:#c2185b,stroke-width:2px
style Kernel fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style SyscallCapture fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
style FalcoEngine fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
检测示例:
规则1: 检测容器内执行Shell
- rule: Container Shell Spawned
condition: >
container and
proc.name in (bash, sh, zsh)
output: >
Shell spawned in container
(user=%user.name container=%container.name)
priority: WARNING
规则2: 检测容器内写入系统目录
- rule: Write Below Etc
condition: >
container and
fd.name startswith /etc and
evt.type = write
output: >
File written to /etc in container
priority: ERROR
规则3: 检测异常网络连接
- rule: Unexpected Outbound Connection
condition: >
container and
fd.type = ipv4 and
fd.sip not in (allowed_ips)
output: >
Unexpected outbound connection
(dest=%fd.rip port=%fd.rport)
priority: CRITICAL
告警流程:
- 容器内执行
curl malicious.com - Falco 捕获 socket() 系统调用
- 匹配规则: 目标IP不在白名单
- 触发告警 → Webhook/Slack/SIEM
- 可选: 自动响应(杀死容器)
2.5 容器逃逸防护
常见逃逸技术
1. 特权容器逃逸
攻击方式:
docker run --privileged -v /:/host ubuntu
→ 挂载主机根目录 → chroot /host → 逃逸到主机
防护措施:
- 禁止
privileged: true - 限制 capabilities (CAP_SYS_ADMIN)
- 使用 Pod Security Standards
2. 内核漏洞利用
攻击方式: 利用脏牛 (Dirty COW) 等内核漏洞 → 提权 → 逃逸
防护措施:
- 及时更新内核
- 使用安全容器 (gVisor, Kata Containers)
3. Docker Socket 暴露
攻击方式:
docker run -v /var/run/docker.sock:/var/run/docker.sock
→ 容器内控制 Docker → 创建特权容器 → 逃逸
防护措施:
- 绝不挂载 docker.sock 到不可信容器
- 使用只读挂载
4. HostPath 挂载
攻击方式:
volumes:
- hostPath:
path: /
type: Directory
→ 读写主机文件系统
防护措施:
- Pod Security Policy 限制 hostPath
- 仅允许特定路径 (如 /var/log)
安全容器技术
graph TB
subgraph Traditional["传统容器 (Docker/containerd)"]
direction TB
subgraph Containers["容器层"]
C1["容器1"]
C2["容器2"]
C3["容器3"]
end
SharedKernel["共享主机内核"]
Containers --> SharedKernel
end
subgraph TraditionalRisk["风险"]
Risk["内核漏洞影响所有容器"]
end
subgraph gVisor["安全容器 (gVisor)"]
direction TB
Application["应用"]
Sentry["Sentry (用户空间内核)<br/>• 系统调用拦截<br/>• 沙箱隔离"]
Application --> Sentry
MinimalKernel["Linux Kernel (最小接触)"]
Sentry --> MinimalKernel
end
subgraph gVisorBenefits["gVisor 好处"]
GB1["✓ 攻击面减小 (只有少量系统调用到达内核)"]
GB2["✓ 逃逸困难"]
end
subgraph Kata["安全容器 (Kata Containers)"]
direction TB
KataContainers["容器1 & 容器2"]
LightweightVM["轻量级虚拟机 (VM)"]
GuestKernel["Guest Kernel"]
Hypervisor["Hypervisor (KVM/Firecracker)"]
HostKernel["Host Kernel"]
KataContainers --> LightweightVM
LightweightVM --> GuestKernel
GuestKernel --> Hypervisor
Hypervisor --> HostKernel
end
subgraph KataBenefits["Kata 好处"]
KB1["✓ 硬件级隔离 (VM边界)"]
KB2["✓ 性能接近容器 (轻量级VM)"]
end
subgraph Performance["性能对比"]
P1["Docker: 启动 <1s, 开销 ~2%"]
P2["gVisor: 启动 ~2s, 开销 ~20%"]
P3["Kata: 启动 ~3s, 开销 ~10%"]
end
style Traditional fill:#ffebee,stroke:#c62828,stroke-width:2px
style TraditionalRisk fill:#ffcdd2,stroke:#e53935,stroke-width:1px
style gVisor fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
style gVisorBenefits fill:#c8e6c9,stroke:#66bb6a,stroke-width:1px
style Kata fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style KataBenefits fill:#bbdefb,stroke:#42a5f5,stroke-width:1px
style Performance fill:#fff3e0,stroke:#f57c00,stroke-width:2px
Kubernetes安全架构
3.1 Kubernetes认证与授权
认证 (Authentication)
Kubernetes 支持的认证方式:
-
X.509 客户端证书:
- kubectl 使用证书认证
- 证书 CN (Common Name) = 用户名
- 证书 O (Organization) = 用户组
-
Service Account Token:
- Pod 内应用使用
- JWT 格式
- 自动挂载到 /var/run/secrets/kubernetes.io/serviceaccount/token
-
OIDC (OpenID Connect):
- 集成企业 IdP (如 Okta, Azure AD)
- 用户通过 SSO 登录
-
Webhook Token:
- 自定义认证服务
- Kubernetes 调用 webhook 验证 token
-
Static Token File (不推荐):
- 静态密码文件
- 安全性差
flowchart TD
User["用户/Pod"] --> APIServer["API Server"]
APIServer --> Auth["1. 认证 (Authentication)"]
subgraph AuthProcess["认证过程"]
Auth --> Extract["提取证书/Token"]
Extract --> Verify["验证签名"]
Verify --> Identify["确定用户身份"]
end
Identify --> Result["用户: alice<br/>组: developers"]
style Auth fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style AuthProcess fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
style Result fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
授权 (Authorization)
RBAC (Role-Based Access Control):
核心概念:
-
Role (角色):
- 定义一组权限
- Namespace 级别
示例:
kind: Role metadata: namespace: default name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list"] -
ClusterRole (集群角色):
- 集群级别权限
- 可访问所有 Namespace
-
RoleBinding (角色绑定):
- 将 Role 绑定到用户/组
示例:
kind: RoleBinding metadata: name: read-pods namespace: default subjects: - kind: User name: alice roleRef: kind: Role name: pod-reader -
ClusterRoleBinding (集群角色绑定):
- 将 ClusterRole 绑定到用户/组
- 全局生效
flowchart TD
User["用户: alice"] --> Request["请求: GET /api/v1/namespaces/default/pods"]
Request --> Authz["2. 授权 (Authorization)"]
subgraph AuthzProcess["授权过程"]
Authz --> FindBindings["查找 alice 的 Bindings"]
FindBindings --> CheckRole["检查 Role 权限"]
CheckRole --> MatchAPI["匹配 apiGroups/resources"]
MatchAPI --> CheckVerbs["检查 verbs"]
end
CheckVerbs --> Decision["允许/拒绝"]
style Authz fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style AuthzProcess fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
style Decision fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
常见 verbs:
- get: 读取单个资源
- list: 列出资源
- watch: 监听资源变化
- create: 创建
- update: 更新
- patch: 部分更新
- delete: 删除
#### 准入控制 (Admission Control)
**准入控制器链**:
认证 → 授权 → 准入控制 → 持久化
**准入控制器职责**:
- 变更请求 (Mutating)
- 验证请求 (Validating)
- 拒绝不合规请求
**内置准入控制器**:
1. **NamespaceLifecycle**:
- 防止在被删除的 Namespace 创建资源
2. **LimitRanger**:
- 强制执行资源限制 (CPU/内存)
3. **ResourceQuota**:
- 强制执行配额(总资源上限)
4. **PodSecurityPolicy (已废弃 → Pod Security Standards)**:
- 强制 Pod 安全策略
5. **ServiceAccount**:
- 自动注入 ServiceAccount Token
6. **NodeRestriction**:
- 限制 kubelet 只能修改自己节点的资源
**动态准入控制**:
**Mutating Webhook**:
请求 → API Server → Webhook (修改请求) → 继续处理
示例: Istio Sidecar 注入
- 用户创建 Pod
- Webhook 拦截请求
- 自动添加 Envoy Sidecar 容器
- 返回修改后的 Pod
**Validating Webhook**:
请求 → API Server → Webhook (验证) → 允许/拒绝
示例: OPA Gatekeeper
- 用户创建 Pod
- Webhook 检查策略:
- 镜像必须来自可信仓库
- 不能使用 latest 标签
- 必须设置资源限制
- 不符合 → 拒绝
---
### 3.2 Pod安全标准 (Pod Security Standards)
#### 三个安全级别
**PSS 级别(从宽松到严格)**:
**1. Privileged (特权)**:
- 无限制
- 允许特权容器
- 允许 hostPath
- 适用: 系统组件
**2. Baseline (基线)**:
- 最小限制集
- 禁止:
- 特权容器
- hostPath (除特定路径)
- hostNetwork/hostPID
- 不安全的 capabilities
- 适用: 大多数应用
**3. Restricted (限制)**:
- 最严格
- 禁止:
- Baseline 所有禁止项
- root 用户运行
- 特权提升
- 所有 capabilities (除 NET_BIND_SERVICE)
- 强制:
- 非root用户
- 只读根文件系统
- runAsNonRoot: true
- 适用: 高安全需求
**实施方式**:
**方式1: Namespace 标签**
```yaml
apiVersion: v1
kind: Namespace
metadata:
name: my-app
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
方式2: 准入控制器
- 集群级别配置
- 不同 Namespace 不同策略
示例: Restricted Pod
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsNonRoot: true # 必须
runAsUser: 1000 # 非root UID
fsGroup: 2000
seccompProfile:
type: RuntimeDefault # 必须
containers:
- name: app
image: nginx:1.21
securityContext:
allowPrivilegeEscalation: false # 必须
readOnlyRootFilesystem: true # 推荐
capabilities:
drop:
- ALL # 必须
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
3.3 Secrets安全
Kubernetes Secrets 的局限性
问题:
-
Base64 编码 ≠ 加密:
echo -n 'password123' | base64 # 输出: cGFzc3dvcmQxMjM= # 轻易解码 -
etcd 默认明文存储:
- Secret 存储在 etcd
- etcd 未加密 → Secret 明文
-
广泛的 RBAC 权限:
- 有 get/list secrets 权限的用户可读所有 secrets
- 难以细粒度控制
-
日志泄露风险:
- Secret 可能被打印到日志
- 容器环境变量可被inspect
改进方案:
-
etcd 加密:
- 启用 Encryption at Rest
- 配置加密提供商 (AES-CBC, KMS)
-
外部 Secrets 管理:
- HashiCorp Vault
- AWS Secrets Manager
- Azure Key Vault
-
Sealed Secrets:
- 加密 Secret 存储在 Git
- 集群内控制器解密
网络策略与隔离
4.1 Kubernetes网络模型
默认网络行为
Kubernetes 网络要求:
- 所有 Pod 可直接通信 (无 NAT)
- 所有节点可与 Pod 通信
- Pod 看到的自己IP = 其他 Pod 看到的IP
默认行为:
- 所有 Pod 互通 (Flat Network)
- 无网络隔离
风险: 攻击者攻陷一个 Pod → 可访问所有其他 Pod
graph LR
Pod1["Pod1<br/>(Web)"] -->|✓| Pod2["Pod2<br/>(API)"]
Pod2 -->|✓| Pod3["Pod3<br/>(DB)"]
Pod1 -.->|不应该但可以| Pod3
Note["问题: Web Pod 可直接访问 DB Pod (不应该)"]
style Pod1 fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style Pod2 fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style Pod3 fill:#ffebee,stroke:#c62828,stroke-width:2px
style Note fill:#fff9c4,stroke:#f57f17,stroke-width:2px
4.2 Network Policy 原理
网络策略模型
Network Policy 工作原理:
-
默认拒绝 + 显式允许:
- 创建 NetworkPolicy → 拒绝所有流量
- 配置规则 → 允许特定流量
-
选择器匹配:
- podSelector: 选择应用策略的 Pod
- namespaceSelector: 选择允许的 Namespace
- ipBlock: 允许的 IP 段
-
入站/出站规则:
- ingress: 入站流量规则
- egress: 出站流量规则
示例: 三层应用隔离
graph LR
subgraph NS["Namespace: production"]
Web["Web<br/>Pod"] --> API["API<br/>Pod"]
API --> DB["DB<br/>Pod"]
end
External["外部<br/>0.0.0.0/0"] -->|允许:80| Web
Web -->|✓ 允许:8080| API
Web -.->|✗ 拒绝| DB
API -->|✓ 允许:5432| DB
External -.->|✗ 拒绝| API
style Web fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style API fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style DB fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
style External fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
style NS fill:#fafafa,stroke:#424242,stroke-width:2px
策略1: Web Pod 只接受外部流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-ingress
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 0.0.0.0/0 # 允许所有外部IP
ports:
- protocol: TCP
port: 80
策略2: API Pod 只接受 Web Pod 流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-ingress
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: web # 仅允许来自 Web Pod
ports:
- protocol: TCP
port: 8080
策略3: DB Pod 只接受 API Pod 流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-ingress
spec:
podSelector:
matchLabels:
app: db
policyTypes:
- Ingress
- Egress # 同时限制出站
ingress:
- from:
- podSelector:
matchLabels:
app: api # 仅允许来自 API Pod
ports:
- protocol: TCP
port: 5432
egress:
- to:
- podSelector:
matchLabels:
app: api
- to: # 允许 DNS 查询
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53
效果:
- Web → API ✓
- Web → DB ✗ (被拒绝)
- API → DB ✓
- 外部 → API ✗ (被拒绝)
---
### 4.3 Service Mesh 安全
#### mTLS (双向TLS) 原理
**传统 TLS vs mTLS**:
```mermaid
sequenceDiagram
participant C as 客户端
participant S as 服务器
Note over C,S: 传统 TLS (单向)
C->>S: 验证服务器证书
S-->>C: 加密通信
Note over C,S: mTLS (双向)
C->>S: 出示客户端证书
S->>C: 验证客户端证书
C<<->>S: 双向加密通信
style C fill:#e3f2fd,stroke:#1976d2
style S fill:#e8f5e9,stroke:#388e3c
Istio mTLS 实现:
graph TB
subgraph PodA["Pod A (Envoy Sidecar)"]
AppA["App容器"] --> EnvoyA["Envoy"]
end
subgraph PodB["Pod B (Envoy Sidecar)"]
EnvoyB["Envoy"] --> AppB["App容器"]
end
EnvoyA -->|mTLS| EnvoyB
style PodA fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style PodB fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
style EnvoyA fill:#fff3e0,stroke:#f57c00
style EnvoyB fill:#fff3e0,stroke:#f57c00
流程:
- Pod A 应用发起请求 → 本地 Envoy
- Envoy A 使用 Pod A 证书建立 mTLS 连接
- Envoy B 验证 Pod A 证书
- Envoy B 提取 Service Account (从证书)
- 应用授权策略 (是否允许 Pod A 访问 Pod B)
- 允许 → 转发请求到 Pod B 应用
- 加密响应返回
证书管理:
- Istio CA 签发短期证书 (默认24小时)
- Envoy 自动轮换证书
- 基于 SPIFFE 标准
#### 授权策略 (Authorization Policy)
**Istio 细粒度访问控制**:
**示例: 只允许 frontend 访问 backend 的 /api 路径**
```yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: backend-authz
namespace: default
spec:
selector:
matchLabels:
app: backend
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/frontend"]
to:
- operation:
methods: ["GET", "POST"]
paths: ["/api/*"]
when:
- key: request.headers[x-user-role]
values: ["admin", "user"]
规则解读:
- 目标: backend 服务
- 允许来源: frontend Service Account
- 允许方法: GET, POST
- 允许路径: /api/*
- 条件: HTTP 头包含 x-user-role
默认拒绝策略:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
namespace: default
spec:
{} # 空规则 = 拒绝所有
→ 然后逐个添加 ALLOW 规则 → 零信任原则
Secrets管理
5.1 HashiCorp Vault 架构
Vault 核心概念
Vault 架构:
graph TB
subgraph VaultServer["Vault Server"]
direction TB
Storage["Storage Backend<br/>• etcd/Consul<br/>• 加密存储所有 Secrets"]
Engines["Secrets Engines<br/>• KV (键值对)<br/>• Database (动态凭证)<br/>• AWS/Azure (云凭证)<br/>• PKI (证书)"]
Auth["Auth Methods<br/>• Kubernetes (ServiceAccount)<br/>• OIDC/LDAP<br/>• AppRole"]
Policies["Policies (ACL)<br/>path 'secret/data/db' {<br/> capabilities = ['read']<br/>}"]
Storage --> Engines
Engines --> Auth
Auth --> Policies
end
style VaultServer fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style Storage fill:#fff3e0,stroke:#f57c00
style Engines fill:#e8f5e9,stroke:#388e3c
style Auth fill:#f3e5f5,stroke:#7b1fa2
style Policies fill:#fce4ec,stroke:#c2185b
初始化与 Unsealing:
-
初始化 (一次性):
vault operator init→ 生成5个密钥碎片 (Shamir Secret Sharing) → 生成 Root Token
-
Unsealing (每次启动):
- Vault 启动时处于 Sealed 状态 (加密)
- 需要3个密钥碎片 Unseal
- Unsealed 后可处理请求
-
Sealed 状态:
- 所有数据加密
- 无法访问
- 防止内存转储攻击
安全机制:
- 数据加密: AES-256-GCM
- 传输加密: TLS
- 审计日志: 所有操作记录
---
### 5.2 动态Secrets
#### 原理
**静态 Secrets vs 动态 Secrets**:
**静态**:
- 固定密码(如: db_password = "abc123")
- 长期有效
- 泄露风险高
- 难以轮换
**动态**:
- 临时凭证(有效期: 1小时)
- 使用后销毁
- 泄露影响小
- 自动轮换
**Vault 动态数据库凭证流程**:
1. **配置数据库连接**:
```bash
vault write database/config/my-postgres \
plugin_name=postgresql-database-plugin \
connection_url="postgresql://{{username}}:{{password}}@postgres:5432/mydb" \
allowed_roles="readonly" \
username="vault-admin" \
password="admin-password"
-
定义角色:
vault write database/roles/readonly \ db_name=my-postgres \ creation_statements="CREATE USER '{{name}}' WITH PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \ GRANT SELECT ON ALL TABLES IN SCHEMA public TO '{{name}}';" \ default_ttl="1h" \ max_ttl="24h" -
应用请求凭证:
vault read database/creds/readonly输出:
{ "username": "v-k8s-readonly-abc123def456", "password": "A1b2C3d4E5f6...", "lease_duration": 3600 } -
Vault 后台操作:
- a. 连接数据库
- b. 创建临时用户(TTL: 1小时)
- c. 授予只读权限
- d. 返回凭证给应用
-
1小时后:
- Vault 自动连接数据库
- 删除临时用户
- 凭证失效
好处:
- 最小权限窗口
- 自动清理
- 审计追踪(哪个应用何时使用了哪个凭证)
5.3 Kubernetes集成 (Vault Agent Injector)
Sidecar注入模式
架构:
graph TB
subgraph Pod["Pod"]
direction TB
InitContainer["Init Container: Vault Agent<br/>• 认证到 Vault (ServiceAccount)<br/>• 拉取 Secrets<br/>• 写入共享卷"]
Sidecar["Sidecar: Vault Agent<br/>• 定期刷新 Secrets<br/>• 自动更新文件"]
AppContainer["App Container<br/>• 读取文件中的 Secrets<br/>• 无需 Vault 客户端"]
Volume["共享卷<br/>/vault/secrets/config"]
InitContainer --> Volume
Sidecar --> Volume
Volume --> AppContainer
end
style Pod fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style InitContainer fill:#fff3e0,stroke:#f57c00
style Sidecar fill:#e8f5e9,stroke:#388e3c
style AppContainer fill:#f3e5f5,stroke:#7b1fa2
style Volume fill:#fce4ec,stroke:#c2185b
Deployment 配置:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "myapp"
vault.hashicorp.com/agent-inject-secret-config: "secret/data/db"
vault.hashicorp.com/agent-inject-template-config: |
{{- with secret "secret/data/db" -}}
{
"username": "{{ .Data.data.username }}",
"password": "{{ .Data.data.password }}"
}
{{- end }}
spec:
serviceAccountName: myapp
containers:
- name: app
image: myapp:v1.0
volumeMounts:
- name: vault-secrets
mountPath: /vault/secrets
流程:
- Pod 创建 → Webhook 注入 Vault Agent
- Init Container:
- a. 使用 ServiceAccount Token 认证 Vault
- b. Vault 验证 ServiceAccount
- c. 返回 Vault Token
- d. 拉取 Secret
- e. 渲染模板 → /vault/secrets/config
- App 容器启动:
- 读取 /vault/secrets/config
- 获取数据库凭证
- Sidecar 持续运行:
- 监听 Secret 变化
- 自动更新文件
- App 可重新读取(无需重启)
5.4 Secrets轮换
自动轮换策略
轮换场景:
-
定期轮换:
- 每30天轮换密码
- 降低长期暴露风险
-
泄露后轮换:
- 检测到泄露 → 立即轮换
- 撤销旧凭证
-
员工离职轮换:
- 员工离职 → 轮换所有访问过的 Secrets
实现方案:
方案1: Vault 自动轮换(数据库凭证)
- Vault 管理凭证生命周期
- 自动创建、销毁临时凭证
方案2: External Secrets Operator
原理: 同步外部 Secrets 到 Kubernetes
graph LR
Vault["Vault/AWS<br/>Secrets Mgr"] -->|同步| ESO["External<br/>Secrets Op"]
ESO --> K8sSecret["K8s Secret"]
K8sSecret --> Pod["Pod 使用"]
style Vault fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style ESO fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style K8sSecret fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
style Pod fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
ExternalSecret 配置:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-secret
spec:
refreshInterval: 1h ← 每小时同步
secretStoreRef:
name: vault-backend
target:
name: db-credentials ← K8s Secret 名称
data:
- secretKey: password
remoteRef:
key: secret/data/db
property: password
好处:
- Secret 变化自动同步
- 应用无需重启 (取决于如何使用 Secret)
方案3: 重启 Pod
- Secret 更新 → 触发 Pod 滚动更新
- 简单但有停机时间
方案4: 应用层热重载
- 应用监听 Secret 文件变化
- 自动重新加载配置
- 无停机
---
## 合规与审计
### 6.1 合规框架
#### CIS Kubernetes Benchmark
**CIS (Center for Internet Security) Kubernetes 基准**:
**5个章节**:
1. **Control Plane (控制平面)**:
- API Server 安全配置
- etcd 加密
- Controller Manager 安全
2. **Worker Nodes (工作节点)**:
- kubelet 安全配置
- 文件权限
- 内核参数
3. **Policies (策略)**:
- RBAC
- Pod Security Standards
- Network Policy
4. **Managed Services (托管服务)**:
- EKS/GKE/AKS 特定配置
5. **Managed Services Addons**:
- 日志
- 监控
**评分示例**:
[PASS] 1.2.1 Ensure that the —anonymous-auth argument is set to false [FAIL] 1.2.5 Ensure that the —kubelet-certificate-authority argument is set [WARN] 1.2.10 Ensure that the admission control plugin EventRateLimit is set
**扫描工具**:
- kube-bench (Aqua Security)
- Polaris
- kubeaudit
**修复流程**:
1. 运行 kube-bench
2. 导出报告
3. 修复失败项
4. 重新扫描
5. 持续监控
---
### 6.2 审计日志
#### Kubernetes审计策略
**审计级别**:
1. **None**: 不记录
2. **Metadata**: 记录请求元数据 (用户、时间、资源)
3. **Request**: Metadata + 请求体
4. **RequestResponse**: Request + 响应体
**审计策略示例**:
```yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# 记录 Secret 访问
- level: RequestResponse
resources:
- group: ""
resources: ["secrets"]
omitStages:
- RequestReceived
# 记录 Pod 删除
- level: Request
verbs: ["delete"]
resources:
- group: ""
resources: ["pods"]
# 忽略只读请求
- level: None
verbs: ["get", "list", "watch"]
审计日志格式:
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "Metadata",
"auditID": "abc-123",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/default/secrets/db-password",
"verb": "get",
"user": {
"username": "alice",
"groups": ["developers"]
},
"sourceIPs": ["10.0.0.5"],
"responseStatus": {
"code": 200
}
}
分析:
- 谁 (alice)
- 何时 (timestamp)
- 做了什么 (get secret)
- 结果 (200 OK)
审计日志用途:
- 安全事件调查
- 合规审计
- 异常检测
6.3 策略即代码 (Policy as Code)
OPA Gatekeeper
原理: Open Policy Agent (OPA) + Kubernetes Admission Webhook
graph TB
APIServer["Kubernetes API Server"]
APIServer -->|Webhook| Gatekeeper
subgraph Gatekeeper["OPA Gatekeeper"]
PolicyEngine["Policy Engine<br/>• Rego 语言编写策略<br/>• 评估请求"]
end
style APIServer fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style Gatekeeper fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
style PolicyEngine fill:#fff3e0,stroke:#f57c00
策略示例: 强制镜像仓库
ConstraintTemplate:
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: allowedrepos
spec:
crd:
spec:
names:
kind: AllowedRepos
validation:
openAPIV3Schema:
properties:
repos:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package allowedrepos
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not startswith(container.image, input.parameters.repos[_])
msg := sprintf("Image '%v' not from allowed repos", [container.image])
}
Constraint:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: AllowedRepos
metadata:
name: prod-repo-only
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaces: ["production"]
parameters:
repos:
- "myregistry.com/"
- "docker.io/library/"
效果:
- 创建 Pod with image: nginx:latest → 拒绝 (不在允许的仓库)
- 创建 Pod with image: myregistry.com/nginx:1.21 → 允许
常见策略:
- 强制资源限制
- 禁止 latest 标签
- 强制 readOnlyRootFilesystem
- 禁止特权容器
- 强制标签 (owner, team)
优势:
- ✓ 代码化 (Git 管理)
- ✓ 可测试
- ✓ 审计追踪
- ✓ 统一管理
6.4 运行时威胁检测
Falco规则深度
Falco 规则结构:
- rule: Shell Execution in Container
desc: Detect shell spawned in a container
condition: >
container and
proc.name in (shell_binaries) and
not proc.pname in (allowed_processes)
output: >
Shell spawned in container
(user=%user.name container=%container.name
parent=%proc.pname cmdline=%proc.cmdline)
priority: WARNING
tags: [shell, mitre_execution]
条件字段:
- container: 过滤容器内进程
- proc.name: 进程名
- proc.pname: 父进程名
- fd.*: 文件描述符 (网络/文件)
- user.name: 用户名
复杂规则示例: 检测加密货币挖矿
- rule: Cryptocurrency Mining
condition: >
spawned_process and
(proc.cmdline contains "xmrig" or
proc.cmdline contains "minerd" or
proc.cmdline contains "cpuminer" or
(proc.name = "python" and proc.cmdline contains "stratum"))
output: >
Potential crypto mining activity
(cmdline=%proc.cmdline)
priority: CRITICAL
规则: 检测反向Shell
- rule: Reverse Shell
condition: >
spawned_process and
(proc.name in (bash, sh, zsh) and
(proc.cmdline contains "/dev/tcp" or
proc.cmdline contains "nc" or
proc.cmdline contains "socat"))
output: >
Potential reverse shell
(cmdline=%proc.cmdline)
priority: CRITICAL
Falco + Falcosidekick:
graph TD
Falco["Falco"] -->|检测威胁| Falcosidekick["Falcosidekick"]
Falcosidekick -->|路由告警| Slack["Slack (通知)"]
Falcosidekick --> Webhook["Webhook (自动响应)"]
Falcosidekick --> SIEM["SIEM (日志)"]
style Falco fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style Falcosidekick fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style Slack fill:#e8f5e9,stroke:#388e3c
style Webhook fill:#fce4ec,stroke:#c2185b
style SIEM fill:#f3e5f5,stroke:#7b1fa2
Webhook 响应示例:
- Falco 检测到反向 Shell
- 触发 Webhook
- Kubernetes 删除 Pod
- 通知安全团队
6.5 供应链安全
SBOM (软件物料清单)
定义: Software Bill of Materials
目的: 列出软件中所有组件和依赖
格式:
- SPDX (Software Package Data Exchange)
- CycloneDX
生成 SBOM:
使用 Syft:
syft packages myimage:v1.0 -o spdx-json > sbom.json
输出:
{
"name": "myimage",
"version": "v1.0",
"packages": [
{
"name": "nginx",
"version": "1.21.0",
"supplier": "Organization: nginx"
},
{
"name": "openssl",
"version": "1.1.1k",
"supplier": "Organization: OpenSSL"
},
...
]
}
用途:
-
漏洞管理:
- 新 CVE 发布 (如 Log4Shell)
- 查询 SBOM → 哪些镜像包含 log4j
- 优先修复
-
合规:
- 审计软件成分
- 许可证检查
-
供应链攻击检测:
- 对比 SBOM 变化
- 检测未授权依赖
签名与证明 (Sigstore)
Sigstore 工作流:
-
构建镜像:
docker build -t myimage:v1.0 . -
签名镜像:
cosign sign myimage:v1.0- 使用 OIDC 认证 (GitHub/Google)
- 生成签名
- 上传到透明日志 (Rekor)
-
生成证明 (Attestation):
cosign attest --predicate sbom.json myimage:v1.0- 将 SBOM 绑定到镜像
-
部署时验证:
cosign verify myimage:v1.0- 检查签名
- 验证证书链
- 查询透明日志
Admission Controller 集成:
- Kyverno / OPA Gatekeeper
- 拒绝未签名镜像
policy:
rules:
- name: verify-signature
match:
resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "myregistry.com/*"
attestors:
- entries:
- keyless:
issuer: "https://accounts.google.com"
subject: "user@company.com"
云原生安全最佳实践
安全检查清单
✅ 容器安全:
- □ 使用最小化基础镜像 (alpine, distroless)
- □ 多阶段构建
- □ 非 root 用户运行
- □ 只读根文件系统
- □ 镜像扫描 (Trivy/Grype)
- □ 镜像签名 (Cosign)
✅ Kubernetes 安全:
- □ RBAC 启用
- □ 最小权限原则
- □ Pod Security Standards (Restricted)
- □ Network Policy 隔离
- □ Secrets 加密 (etcd)
- □ 审计日志启用
✅ 网络安全:
- □ Service Mesh (mTLS)
- □ 入口 TLS 终止
- □ 网络策略 (默认拒绝)
- □ Egress 控制
✅ Secrets 管理:
- □ 外部 Secrets 管理器 (Vault)
- □ 动态凭证
- □ 自动轮换
- □ 不在代码中硬编码
✅ 运行时安全:
- □ Falco 威胁检测
- □ 只读文件系统
- □ AppArmor/SELinux
- □ Seccomp 过滤
✅ 供应链安全:
- □ SBOM 生成
- □ 签名验证
- □ 依赖扫描
- □ 可信镜像仓库
✅ 合规:
- □ CIS Benchmark 扫描
- □ Policy as Code (OPA)
- □ 审计日志
- □ 定期渗透测试
权威资源索引
官方文档
-
CNCF 云原生安全白皮书 https://www.cncf.io/reports/cloud-native-security-whitepaper/
-
Kubernetes 安全文档 https://kubernetes.io/docs/concepts/security/
-
HashiCorp Vault 文档 https://developer.hashicorp.com/vault/docs
工具
-
Falco (运行时安全) https://falco.org/docs/
-
OPA Gatekeeper (策略) https://open-policy-agent.github.io/gatekeeper/
-
Trivy (镜像扫描) https://aquasecurity.github.io/trivy/
-
Cosign (签名) https://docs.sigstore.dev/cosign/overview/
标准与基准
-
CIS Kubernetes Benchmark https://www.cisecurity.org/benchmark/kubernetes
-
NIST SP 800-190 (容器安全) https://csrc.nist.gov/publications/detail/sp/800-190/final
-
MITRE ATT&CK for Containers https://attack.mitre.org/matrices/enterprise/containers/
学习资源
-
Kubernetes Security Specialist (CKS) 认证 https://www.cncf.io/certification/cks/
-
《Kubernetes Security》- Liz Rice & Michael Hausenblas
-
CNCF Security TAG https://github.com/cncf/tag-security
文档版本: v1.0 最后更新: 2025-01-21 适用深度: ⭐⭐⭐⭐ (高级理论知识)