云原生安全深度理论知识

#安全#云原生架构

云原生安全深度理论知识

学习深度: ⭐⭐⭐⭐ 文档类型: 纯理论知识(无代码实践) 权威参考: CNCF、Falco、HashiCorp Vault、NIST、CIS Benchmarks


目录

  1. 云原生安全基础
  2. 容器安全
  3. Kubernetes安全架构
  4. 网络策略与隔离
  5. Secrets管理
  6. 合规与审计

云原生安全基础

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

零信任四大原则:

  1. 永不信任网络位置:

    • Pod IP动态分配 → 不能依赖IP白名单
    • 解决方案: 基于身份的访问控制 (Service Mesh mTLS)
  2. 微分段 (Micro-Segmentation):

    • 每个微服务独立隔离
    • 解决方案: Network Policy 限制Pod间通信
  3. 持续验证:

    • 每个请求都验证身份
    • 解决方案: Istio/Linkerd 自动注入认证
  4. 最小权限:

    • Pod仅获得必需权限
    • 解决方案: RBAC + Pod Security Standards

容器安全

2.1 容器隔离原理

Linux Namespace (命名空间)

定义: 隔离进程视图,让容器看到独立的系统资源。

7种命名空间:

  1. PID Namespace (进程隔离):

    • 容器内 PID 1 (init)
    • 主机看到真实 PID (如 12345)
    • 容器看不到主机进程
  2. Network Namespace (网络隔离):

    • 独立网卡、IP、路由表
    • 容器间网络隔离
  3. Mount Namespace (文件系统隔离):

    • 独立挂载点
    • 容器看到自己的根文件系统
  4. UTS Namespace (主机名隔离):

    • 独立主机名
    • 容器可设置hostname
  5. IPC Namespace (进程间通信隔离):

    • 隔离共享内存、信号量
    • 防止容器间IPC干扰
  6. User Namespace (用户隔离):

    • 容器内 root ≠ 主机 root
    • UID/GID 映射
  7. Cgroup Namespace (资源视图隔离):

    • 隔离 cgroup 视图

示例: PID Namespace

主机视角:

PID 1: systemd
PID 12345: nginx (容器进程)

容器视角:

PID 1: nginx (以为自己是init)

Cgroups (控制组)

定义: 限制和监控容器资源使用。

资源类型:

  1. CPU:

    • cpu.shares: CPU权重 (默认1024)
    • cpu.cfs_quota_us: CPU配额 (微秒)
    • 示例: 限制容器最多使用50% CPU
  2. Memory:

    • memory.limit_in_bytes: 内存上限
    • memory.oom_control: OOM行为
    • 示例: 限制容器最多512MB内存
  3. Block I/O:

    • blkio.weight: I/O权重
    • blkio.throttle.read_bps_device: 读取速率
    • 示例: 限制磁盘读取10MB/s
  4. 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 镜像扫描

漏洞扫描原理

扫描流程:

  1. 镜像解析:

    • 提取所有层 (layers)
    • 识别包管理器 (apt, yum, apk)
  2. 包清单提取:

    • 列出所有已安装包及版本
    • 示例: nginx 1.18.0, openssl 1.1.1k
  3. 漏洞数据库匹配:

    • 查询 CVE 数据库
    • 匹配包名 + 版本
  4. 风险评分:

    • CVSS 分数 (0-10)
    • 严重性: Critical, High, Medium, Low
  5. 生成报告:

    • 漏洞列表
    • 修复建议

扫描工具对比:

工具数据源语言支持性能推荐指数
Trivy多源多语言⭐⭐⭐⭐⭐
GrypeSyft + CVE多语言⭐⭐⭐⭐
ClairNVD操作系统包⭐⭐⭐
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 签名

流程:

  1. 推送镜像时签名:

    docker push myregistry.com/app:v1.0
    • 生成签名(使用私钥)
    • 存储到 Notary 服务器
  2. 拉取镜像时验证:

    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

告警流程:

  1. 容器内执行 curl malicious.com
  2. Falco 捕获 socket() 系统调用
  3. 匹配规则: 目标IP不在白名单
  4. 触发告警 → Webhook/Slack/SIEM
  5. 可选: 自动响应(杀死容器)

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 支持的认证方式:

  1. X.509 客户端证书:

    • kubectl 使用证书认证
    • 证书 CN (Common Name) = 用户名
    • 证书 O (Organization) = 用户组
  2. Service Account Token:

    • Pod 内应用使用
    • JWT 格式
    • 自动挂载到 /var/run/secrets/kubernetes.io/serviceaccount/token
  3. OIDC (OpenID Connect):

    • 集成企业 IdP (如 Okta, Azure AD)
    • 用户通过 SSO 登录
  4. Webhook Token:

    • 自定义认证服务
    • Kubernetes 调用 webhook 验证 token
  5. 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):

核心概念:

  1. Role (角色):

    • 定义一组权限
    • Namespace 级别

    示例:

    kind: Role
    metadata:
      namespace: default
      name: pod-reader
    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get", "list"]
  2. ClusterRole (集群角色):

    • 集群级别权限
    • 可访问所有 Namespace
  3. RoleBinding (角色绑定):

    • 将 Role 绑定到用户/组

    示例:

    kind: RoleBinding
    metadata:
      name: read-pods
      namespace: default
    subjects:
    - kind: User
      name: alice
    roleRef:
      kind: Role
      name: pod-reader
  4. 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 的局限性

问题:

  1. Base64 编码 ≠ 加密:

    echo -n 'password123' | base64
    # 输出: cGFzc3dvcmQxMjM=
    # 轻易解码
  2. etcd 默认明文存储:

    • Secret 存储在 etcd
    • etcd 未加密 → Secret 明文
  3. 广泛的 RBAC 权限:

    • 有 get/list secrets 权限的用户可读所有 secrets
    • 难以细粒度控制
  4. 日志泄露风险:

    • Secret 可能被打印到日志
    • 容器环境变量可被inspect

改进方案:

  1. etcd 加密:

    • 启用 Encryption at Rest
    • 配置加密提供商 (AES-CBC, KMS)
  2. 外部 Secrets 管理:

    • HashiCorp Vault
    • AWS Secrets Manager
    • Azure Key Vault
  3. Sealed Secrets:

    • 加密 Secret 存储在 Git
    • 集群内控制器解密

网络策略与隔离

4.1 Kubernetes网络模型

默认网络行为

Kubernetes 网络要求:

  1. 所有 Pod 可直接通信 (无 NAT)
  2. 所有节点可与 Pod 通信
  3. 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 工作原理:

  1. 默认拒绝 + 显式允许:

    • 创建 NetworkPolicy → 拒绝所有流量
    • 配置规则 → 允许特定流量
  2. 选择器匹配:

    • podSelector: 选择应用策略的 Pod
    • namespaceSelector: 选择允许的 Namespace
    • ipBlock: 允许的 IP 段
  3. 入站/出站规则:

    • 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

流程:

  1. Pod A 应用发起请求 → 本地 Envoy
  2. Envoy A 使用 Pod A 证书建立 mTLS 连接
  3. Envoy B 验证 Pod A 证书
  4. Envoy B 提取 Service Account (从证书)
  5. 应用授权策略 (是否允许 Pod A 访问 Pod B)
  6. 允许 → 转发请求到 Pod B 应用
  7. 加密响应返回

证书管理:

  • 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:

  1. 初始化 (一次性):

    vault operator init

    → 生成5个密钥碎片 (Shamir Secret Sharing) → 生成 Root Token

  2. Unsealing (每次启动):

    • Vault 启动时处于 Sealed 状态 (加密)
    • 需要3个密钥碎片 Unseal
    • Unsealed 后可处理请求
  3. 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"
  1. 定义角色:

    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"
  2. 应用请求凭证:

    vault read database/creds/readonly

    输出:

    {
      "username": "v-k8s-readonly-abc123def456",
      "password": "A1b2C3d4E5f6...",
      "lease_duration": 3600
    }
  3. Vault 后台操作:

    • a. 连接数据库
    • b. 创建临时用户(TTL: 1小时)
    • c. 授予只读权限
    • d. 返回凭证给应用
  4. 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

流程:

  1. Pod 创建 → Webhook 注入 Vault Agent
  2. Init Container:
    • a. 使用 ServiceAccount Token 认证 Vault
    • b. Vault 验证 ServiceAccount
    • c. 返回 Vault Token
    • d. 拉取 Secret
    • e. 渲染模板 → /vault/secrets/config
  3. App 容器启动:
    • 读取 /vault/secrets/config
    • 获取数据库凭证
  4. Sidecar 持续运行:
    • 监听 Secret 变化
    • 自动更新文件
    • App 可重新读取(无需重启)

5.4 Secrets轮换

自动轮换策略

轮换场景:

  1. 定期轮换:

    • 每30天轮换密码
    • 降低长期暴露风险
  2. 泄露后轮换:

    • 检测到泄露 → 立即轮换
    • 撤销旧凭证
  3. 员工离职轮换:

    • 员工离职 → 轮换所有访问过的 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 响应示例:

  1. Falco 检测到反向 Shell
  2. 触发 Webhook
  3. Kubernetes 删除 Pod
  4. 通知安全团队

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"
    },
    ...
  ]
}

用途:

  1. 漏洞管理:

    • 新 CVE 发布 (如 Log4Shell)
    • 查询 SBOM → 哪些镜像包含 log4j
    • 优先修复
  2. 合规:

    • 审计软件成分
    • 许可证检查
  3. 供应链攻击检测:

    • 对比 SBOM 变化
    • 检测未授权依赖

签名与证明 (Sigstore)

Sigstore 工作流:

  1. 构建镜像:

    docker build -t myimage:v1.0 .
  2. 签名镜像:

    cosign sign myimage:v1.0
    • 使用 OIDC 认证 (GitHub/Google)
    • 生成签名
    • 上传到透明日志 (Rekor)
  3. 生成证明 (Attestation):

    cosign attest --predicate sbom.json myimage:v1.0
    • 将 SBOM 绑定到镜像
  4. 部署时验证:

    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)
  • □ 审计日志
  • □ 定期渗透测试

权威资源索引

官方文档

工具

标准与基准

学习资源


文档版本: v1.0 最后更新: 2025-01-21 适用深度: ⭐⭐⭐⭐ (高级理论知识)