89·安全高级

镜像安全

kubernetessecurityimagecontainer

镜像安全

学习目标

  1. 理解容器镜像安全的重要性
  2. 掌握镜像扫描和验证方法
  3. 了解镜像安全的最佳实践

核心概念

一句话解释

镜像安全通过扫描、签名和策略控制,确保容器镜像不包含漏洞和恶意代码。

镜像安全威胁

┌─────────────────────────────────────────────────────────────┐
│                    镜像安全威胁                              │
├─────────────────────────────────────────────────────────────┤
│  漏洞风险                                                   │
│  ├── 操作系统漏洞                                           │
│  ├── 应用依赖漏洞                                           │
│  └── 配置错误                                               │
├─────────────────────────────────────────────────────────────┤
│  恶意代码                                                   │
│  ├── 后门程序                                               │
│  ├── 挖矿程序                                               │
│  └── 数据窃取                                               │
├─────────────────────────────────────────────────────────────┤
│  供应链攻击                                                 │
│  ├── 基础镜像被篡改                                         │
│  ├── 依赖包被替换                                           │
│  └── 构建过程被污染                                         │
└─────────────────────────────────────────────────────────────┘

镜像安全层次

┌─────────────────────────────────────────────────────────────┐
│                    镜像安全层次                              │
├─────────────────────────────────────────────────────────────┤
│  构建时安全                                                 │
│  ├── 使用可信基础镜像                                       │
│  ├── 最小化镜像                                             │
│  ├── 多阶段构建                                             │
│  └── 扫描漏洞                                               │
├─────────────────────────────────────────────────────────────┤
│  存储时安全                                                 │
│  ├── 私有镜像仓库                                           │
│  ├── 镜像签名                                               │
│  ├── 访问控制                                               │
│  └── 定期扫描                                               │
├─────────────────────────────────────────────────────────────┤
│  运行时安全                                                 │
│  ├── 镜像验证                                               │
│  ├── 准入控制                                               │
│  ├── 只读根文件系统                                         │
│  └── 非 root 运行                                           │
└─────────────────────────────────────────────────────────────┘

镜像扫描工具

工具说明特点
Trivy开源扫描工具快速、全面
Clair开源扫描工具API 驱动
Anchore企业级扫描策略引擎
Snyk开发者友好IDE 集成
Docker ScoutDocker 官方集成 Docker

Trivy 扫描示例

# 安装 Trivy
brew install trivy  # macOS
# 或
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh

# 扫描镜像
trivy image nginx:latest

# 扫描本地镜像
trivy image my-app:latest

# 扫描指定严重级别
trivy image --severity HIGH,CRITICAL nginx:latest

# 输出 JSON 格式
trivy image --format json --output result.json nginx:latest

# 扫描 Dockerfile
trivy config Dockerfile

镜像签名

# 使用 cosign 签名镜像
# 安装 cosign
go install github.com/sigstore/cosign/v2/cmd/cosign@latest

# 生成密钥对
cosign generate-key-pair

# 签名镜像
cosign sign --key cosign.key my-registry/my-image:tag

# 验证签名
cosign verify --key cosign.pub my-registry/my-image:tag

镜像验证策略

# 使用 Kyverno 验证镜像
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image
spec:
  validationFailureAction: enforce
  background: false
  rules:
    - name: verify-image-signature
      match:
        any:
        - resources:
            kinds:
              - Pod
      verifyImages:
      - imageReferences:
        - "my-registry/*"
        attestors:
        - entries:
          - keys:
              publicKeys: |-
                -----BEGIN PUBLIC KEY-----
                ...
                -----END PUBLIC KEY-----

镜像仓库安全

# 私有镜像仓库认证
apiVersion: v1
kind: Secret
metadata:
  name: registry-credentials
  namespace: default
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: eyJhdXRocyI6eyJteS1yZWdpc3RyeSI6eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiJwQHNzdzByZCJ9fX0=

---
# Pod 使用私有镜像
apiVersion: v1
kind: Pod
metadata:
  name: private-image-pod
spec:
  containers:
  - name: app
    image: my-registry/my-app:latest
  imagePullSecrets:
  - name: registry-credentials

最小化镜像

# 多阶段构建
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o my-app

FROM scratch
COPY --from=builder /app/my-app /my-app
ENTRYPOINT ["/my-app"]

# 使用最小基础镜像
FROM alpine:3.18
RUN apk --no-cache add ca-certificates
COPY my-app /my-app
ENTRYPOINT ["/my-app"]

# 使用 distroless 镜像
FROM gcr.io/distroless/static
COPY my-app /my-app
ENTRYPOINT ["/my-app"]

镜像安全最佳实践

1. 使用可信基础镜像
   - 官方镜像
   - 经过验证的镜像
   - 定期更新基础镜像

2. 最小化镜像
   - 多阶段构建
   - 只包含必要组件
   - 减少攻击面

3. 定期扫描漏洞
   - CI/CD 集成扫描
   - 定期重新扫描
   - 及时修复漏洞

4. 镜像签名和验证
   - 使用 cosign 签名
   - 准入控制验证签名
   - 防止镜像篡改

5. 私有镜像仓库
   - 使用私有仓库
   - 访问控制
   - 定期清理旧镜像

CI/CD 集成

# GitLab CI 镜像扫描
image_scanning:
  stage: test
  image:
    name: aquasec/trivy:latest
    entrypoint: [""]
  script:
    - trivy image --exit-code 1 --severity HIGH,CRITICAL $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  only:
    - main

---
# GitHub Actions 镜像扫描
name: Image Scan
on: [push]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Run Trivy vulnerability scanner
      uses: aquasecurity/trivy-action@master
      with:
        image-ref: 'my-image:latest'
        format: 'table'
        exit-code: '1'
        severity: 'CRITICAL,HIGH'

实践练习

练习 1:扫描镜像漏洞

# 扫描 nginx 镜像
trivy image nginx:latest

# 扫描指定严重级别
trivy image --severity HIGH,CRITICAL nginx:latest

# 扫描本地构建的镜像
docker build -t my-app:latest .
trivy image my-app:latest

练习 2:创建安全的 Dockerfile

# 使用多阶段构建
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
USER node
CMD ["node", "dist/main.js"]

常见误解

1. 官方镜像一定安全

事实:官方镜像也可能包含漏洞
误解:使用官方镜像就安全了
解决:定期扫描所有镜像,包括官方镜像

2. 镜像扫描是一次性工作

事实:漏洞不断被发现,需要持续扫描
误解:构建时扫描一次就够了
解决:定期重新扫描,及时更新镜像

小结

要点说明
镜像安全扫描、签名、验证
扫描工具Trivy、Clair、Anchore
镜像签名cosign、Notary
最佳实践可信基础镜像、最小化、定期扫描
CI/CD 集成构建时扫描、准入控制

练习编辑器

bash
Loading...

继续学习

完成本课后,建议继续学习下一课「审计日志」 以巩固所学知识。