Rekor 透明日志完整教程 / 10 - 最佳实践
第 10 章:最佳实践
本章总结了在企业环境中使用 Rekor 和 Sigstore 进行供应链安全防护的最佳实践,涵盖签名策略、监控、合规和企业级部署等方面。
10.1 供应链安全策略
10.1.1 SLSA 安全等级
SLSA(Supply-chain Levels for Software Artifacts)定义了供应链安全的四个等级:
| 等级 | 要求 | Rekor 的作用 |
|---|
| SLSA 1 | 构建过程有文档记录 | 提供签名记录 |
| SLSA 2 | 使用版本控制和构建服务 | CI/CD 集成 |
| SLSA 3 | 构建平台有防篡改保证 | 透明日志审计 |
| SLSA 4 | 双人审核 + 可重复构建 | 多重签名 + 验证 |
10.1.2 安全等级提升路线图
当前状态 目标状态
┌──────────┐ ┌──────────┐
│ 无签名 │ ───────────► │ SLSA 3+ │
│ 无审计 │ │ 完整审计 │
└──────────┘ └──────────┘
阶段 1 (1-2 月):
├─ 引入 cosign 签名
├─ 集成 Rekor 日志
└─ 基本 CI/CD 签名
阶段 2 (3-4 月):
├─ 强制签名验证
├─ SBOM 生成和签名
└─ 基本监控
阶段 3 (5-6 月):
├─ 私有 Rekor 实例
├─ 完整审计流程
└─ 合规报告
阶段 4 (7+ 月):
├─ SLSA 3/4 认证
├─ 多重签名策略
└─ 持续改进
10.1.3 签名策略矩阵
| 构件类型 | 签名方式 | 验证策略 | Rekor 记录 |
|---|
| 容器镜像(开发) | 无密钥签名 | 基本身份验证 | ✅ 必须 |
| 容器镜像(生产) | KMS 签名 | 严格身份 + Rekor 验证 | ✅ 必须 |
| 二进制文件 | cosign sign-blob | 公钥验证 | ✅ 推荐 |
| SBOM | cosign attest | 关联验证 | ✅ 推荐 |
| 源码标签 | Git 签名 | GPG/SSH 验证 | ⚠️ 可选 |
| 配置文件 | cosign sign-blob | 公钥验证 | ✅ 推荐 |
10.2 签名策略最佳实践
10.2.1 选择签名方式
┌─────────────────────────────────────────────────────────────────┐
│ 签名方式选择决策树 │
│ │
│ 是否在 CI/CD 中签名? │
│ ├─ 是 ──► 是否使用 GitHub Actions / GitLab CI? │
│ │ ├─ 是 ──► 使用无密钥签名 (Keyless) │
│ │ └─ 否 ──► 使用 KMS 签名 │
│ │ │
│ └─ 否 ──► 是否需要长期有效签名? │
│ ├─ 是 ──► 使用 KMS 签名 │
│ └─ 否 ──► 使用本地密钥签名 │
└─────────────────────────────────────────────────────────────────┘
10.2.2 无密钥签名最佳实践
# ✅ 推荐:使用精确的身份匹配
cosign verify \
--certificate-identity="https://github.com/myorg/myrepo/.github/workflows/build.yml@refs/heads/main" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
ghcr.io/myorg/myimage:v1.0.0
# ❌ 避免:使用过于宽泛的匹配
cosign verify \
--certificate-identity-regexp=".*" \
--certificate-oidc-issuer-regexp=".*" \
ghcr.io/myorg/myimage:v1.0.0
10.2.3 多重签名策略
对于关键系统,建议实施多重签名策略:
# 需要至少两个签名者
apiVersion: policy.sigstore.dev/v1beta1
kind: ClusterImagePolicy
metadata:
name: require-multi-signatures
spec:
images:
- glob: "ghcr.io/myorg/critical-app/**"
authorities:
# 安全团队签名
- key:
data: |
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...security-team...
-----END PUBLIC KEY-----
# 发布经理签名
- key:
data: |
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...release-manager...
-----END PUBLIC KEY-----
10.2.4 密钥管理建议
| 场景 | 推荐方案 | 安全级别 |
|---|
| 个人开发 | 本地密钥 + 密码 | ⭐⭐ |
| 团队开发 | 共享 KMS 密钥 | ⭐⭐⭐ |
| CI/CD | 无密钥签名 | ⭐⭐⭐⭐ |
| 生产发布 | 云 KMS + HSM | ⭐⭐⭐⭐⭐ |
| 关键系统 | 多重 KMS + 审批 | ⭐⭐⭐⭐⭐ |
10.3 Rekor 使用最佳实践
10.3.1 条目查询策略
# ✅ 推荐:使用 digest 查询,而非 tag
cosign verify \
--key cosign.pub \
ghcr.io/myorg/myimage@sha256:abc123...
# ❌ 避免:使用 mutable tag 查询
cosign verify \
--key cosign.pub \
ghcr.io/myorg/myimage:latest
10.3.2 包含证明验证
# ✅ 推荐:始终验证包含证明
cosign verify \
--certificate-identity=[email protected] \
--certificate-oidc-issuer=https://accounts.google.com \
--check-claims=true \
--verify-inclusion=true \
ghcr.io/myorg/myimage:v1.0.0
# ✅ 推荐:验证集成时间
rekor-cli get --log-index=12345678 --format=json | jq '{
integratedTime: (.integratedTime | todate),
bodyKind: .body.kind
}'
10.3.3 批量操作优化
# ✅ 推荐:缓存 Rekor 查询结果
REKOR_CACHE_DIR="$HOME/.cache/rekor"
mkdir -p "$REKOR_CACHE_DIR"
rekor-cli get --log-index=12345678 --format=json > "$REKOR_CACHE_DIR/entry-12345678.json"
# ✅ 推荐:并行验证多个构件
parallel cosign verify --key cosign.pub {} ::: \
ghcr.io/myorg/app1:v1.0.0 \
ghcr.io/myorg/app2:v1.0.0 \
ghcr.io/myorg/app3:v1.0.0
10.3.4 公共实例使用礼仪
| 实践 | 说明 |
|---|
| 实现退避重试 | 遇到 429 错误时指数退避 |
| 缓存查询结果 | 减少重复查询 |
| 批量查询 | 使用搜索 API 而非逐个查询 |
| 使用私有实例 | 大量操作时部署私有实例 |
#!/bin/bash
# 带退避重试的查询脚本
rekor_get_with_retry() {
local max_retries=5
local retry=0
local delay=1
while [ $retry -lt $max_retries ]; do
if result=$(rekor-cli get --log-index="$1" --format=json 2>/dev/null); then
echo "$result"
return 0
fi
# 检查是否为速率限制错误
if echo "$result" | grep -q "429"; then
echo "速率限制,等待 ${delay} 秒后重试..." >&2
sleep $delay
delay=$((delay * 2))
((retry++))
else
return 1
fi
done
echo "超过最大重试次数" >&2
return 1
}
10.4 监控最佳实践
10.4.1 监控指标分类
| 类别 | 指标 | 警告阈值 |
|---|
| 可用性 | API 成功率 | < 99.9% |
| 性能 | API 响应时间 (P99) | > 1s |
| 容量 | 日志树大小增长 | 持续不增长 |
| 资源 | CPU/内存使用率 | > 80% |
| 存储 | 磁盘使用率 | > 85% |
| 数据库 | 连接数/查询延迟 | 连接数 > 150 |
10.4.2 Prometheus 告警规则
# prometheus/alerts/rekor.yml
groups:
- name: rekor
rules:
- alert: RekorServerDown
expr: up{job="rekor-server"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Rekor Server 不可用"
description: "Rekor Server 已停止响应超过 1 分钟"
- alert: RekorHighLatency
expr: histogram_quantile(0.99, rate(rekor_http_request_duration_seconds_bucket[5m])) > 1
for: 5m
labels:
severity: warning
annotations:
summary: "Rekor API 延迟过高"
description: "P99 延迟超过 1 秒"
- alert: RekorTreeNotGrowing
expr: delta(trillian_sequencer_tree_size[1h]) == 0
for: 6h
labels:
severity: warning
annotations:
summary: "日志树大小未增长"
description: "过去 6 小时日志树大小未增加,可能存在写入问题"
- alert: MySQLConnectionsHigh
expr: mysql_global_status_threads_connected > 150
for: 5m
labels:
severity: warning
annotations:
summary: "MySQL 连接数过高"
description: "MySQL 当前连接数超过 150"
- alert: DiskSpaceLow
expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) < 0.15
for: 5m
labels:
severity: critical
annotations:
summary: "磁盘空间不足"
description: "可用磁盘空间低于 15%"
10.4.3 审计日志
#!/bin/bash
# 定期审计脚本 (每周运行)
AUDIT_DIR="/var/audit/rekor/$(date +%Y%m%d)"
mkdir -p "$AUDIT_DIR"
# 记录日志状态
rekor-cli loginfo > "$AUDIT_DIR/loginfo.txt"
# 验证最近的条目
for i in $(seq 0 99); do
INDEX=$((TREE_SIZE - i))
rekor-cli verify --log-index=$INDEX > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "✅ Index $INDEX" >> "$AUDIT_DIR/verification.txt"
else
echo "❌ Index $INDEX" >> "$AUDIT_DIR/verification.txt"
echo "验证失败: Index $INDEX" | mail -s "Rekor 审计告警" [email protected]
fi
done
# 生成审计报告
cat > "$AUDIT_DIR/report.md" << EOF
# Rekor 周审计报告
- 审计时间: $(date -u '+%Y-%m-%d %H:%M:%S UTC')
- 树大小: $(rekor-cli loginfo | grep 'tree size')
- 根哈希: $(rekor-cli loginfo | grep 'root hash')
- 验证结果: $(grep -c '✅' "$AUDIT_DIR/verification.txt") 通过, $(grep -c '❌' "$AUDIT_DIR/verification.txt") 失败
EOF
10.5 合规性实践
10.5.1 常见合规框架与 Rekor
| 合规框架 | 相关要求 | Rekor 的作用 |
|---|
| SOC 2 | 变更管理、访问控制 | 提供不可篡改的变更审计 |
| PCI DSS | 软件完整性验证 | 构件签名和验证 |
| HIPAA | 审计日志 | 软件部署审计追踪 |
| FedRAMP | 供应链安全 | SLSA 合规 |
| GDPR | 数据处理透明性 | 审计和证明能力 |
| NIST 800-218 | 安全软件开发 | SSDF 合规 |
10.5.2 审计证据生成
#!/bin/bash
# generate-compliance-report.sh
# 生成合规审计报告
REPORT_DIR="./compliance-reports/$(date +%Y%m%d)"
mkdir -p "$REPORT_DIR"
echo "=== 生成供应链安全合规报告 ==="
# 1. 签名覆盖率
echo ">>> 计算签名覆盖率..."
TOTAL_IMAGES=$(curl -s https://ghcr.io/v2/myorg/myapp/tags/list | jq '.tags | length')
SIGNED_IMAGES=0
for tag in $(curl -s https://ghcr.io/v2/myorg/myapp/tags/list | jq -r '.tags[]'); do
if cosign verify \
--certificate-identity-regexp=".*" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
ghcr.io/myorg/myapp:$tag > /dev/null 2>&1; then
((SIGNED_IMAGES++))
fi
done
SIGNATURE_COVERAGE=$((SIGNED_IMAGES * 100 / TOTAL_IMAGES))
# 2. Rekor 记录完整性
echo ">>> 验证 Rekor 记录..."
REKOR_ENTRIES=$(rekor-cli search --sha256=$(cosign triangulate ghcr.io/myorg/myapp:v1.0.0 | xargs sha256sum | awk '{print $1}') 2>/dev/null | wc -l)
# 3. 生成报告
cat > "$REPORT_DIR/compliance-report.md" << EOF
# 供应链安全合规报告
## 基本信息
- 报告日期: $(date -u '+%Y-%m-%d')
- 覆盖范围: ghcr.io/myorg/myapp
## 关键指标
- 总镜像数: $TOTAL_IMAGES
- 已签名镜像: $SIGNED_IMAGES
- 签名覆盖率: ${SIGNATURE_COVERAGE}%
- Rekor 记录数: $REKOR_ENTRIES
## 合规状态
- SLSA 等级: $([ $SIGNATURE_COVERAGE -eq 100 ] && echo "Level 3+" || echo "Level 2")
- 签名验证: $([ $SIGNATURE_COVERAGE -ge 95 ] && echo "✅ 合规" || echo "⚠️ 需要改进")
- 透明日志: $([ $REKOR_ENTRIES -gt 0 ] && echo "✅ 合规" || echo "⚠️ 未配置")
## 建议
$([ $SIGNATURE_COVERAGE -lt 100 ] && echo "- 提高签名覆盖率到 100%")
$([ $REKOR_ENTRIES -eq 0 ] && echo "- 启用 Rekor 透明日志记录")
EOF
echo "=== 报告生成完成: $REPORT_DIR/compliance-report.md ==="
10.5.3 合规检查清单
| 检查项 | 状态 | 说明 |
|---|
| 所有容器镜像已签名 | ✅/❌ | 签名覆盖率 100% |
| 签名记录在 Rekor 中 | ✅/❌ | 包含证明验证通过 |
| 使用无密钥或 KMS 签名 | ✅/❌ | 无长期密钥暴露风险 |
| CI/CD 流水线已集成签名 | ✅/❌ | 自动化签名 |
| 部署前验证签名 | ✅/❌ | 准入控制器配置 |
| SBOM 已生成并签名 | ✅/❌ | 供应链透明 |
| 监控告警已配置 | ✅/❌ | Prometheus + Alertmanager |
| 审计报告定期生成 | ✅/❌ | 每周/每月 |
| 密钥管理策略已实施 | ✅/❌ | KMS + 轮换策略 |
| 应急响应计划已制定 | ✅/❌ | 密钥泄露响应流程 |
10.6 企业部署最佳实践
10.6.1 企业级架构
┌────────────────────────────────────────────────────────────────────────┐
│ 企业级 Rekor 部署架构 │
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 开发/CI 环境 │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │GitHub │ │GitLab │ │Jenkins │ │Azure │ │ │
│ │ │Actions │ │CI │ │ │ │DevOps │ │ │
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │
│ │ │ │ │ │ │ │
│ │ └──────────────┼──────────────┼──────────────┘ │ │
│ │ │ │ │ │
│ │ ┌──────▼──────────────▼──────┐ │ │
│ │ │ cosign 签名 │ │ │
│ │ │ (无密钥 / KMS / 混合) │ │ │
│ │ └──────────────┬──────────────┘ │ │
│ └──────────────────────────────┼──────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Rekor 集群 │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────────┐ │ │
│ │ │ 负载均衡器 (HAProxy) │ │ │
│ │ └────────────────────────┬─────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌──────────────────┼──────────────────┐ │ │
│ │ │ │ │ │ │
│ │ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │ │
│ │ │Rekor-1 │ │Rekor-2 │ │Rekor-3 │ │ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │
│ │ └──────────────────┼──────────────────┘ │ │
│ │ │ │ │
│ │ ┌──────▼──────┐ │ │
│ │ │ Trillian │ │ │
│ │ │ Cluster │ │ │
│ │ └──────┬──────┘ │ │
│ │ │ │ │
│ │ ┌──────▼──────┐ │ │
│ │ │ MySQL HA │ │ │
│ │ │ Cluster │ │ │
│ │ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 监控层 │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │Prometheus│ │ Grafana │ │Alert- │ │ ELK/ │ │ │
│ │ │ │ │ │ │manager │ │ Loki │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 部署/验证层 │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │K8s │ │ArgoCD │ │Policy │ │ │
│ │ │Cluster │ │ │ │Controller│ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────┘
10.6.2 环境分离
| 环境 | Rekor 实例 | 签名策略 | 验证策略 |
|---|
| 开发 | 公共实例 | 可选 | 不强制 |
| 测试 | 公共实例 | 必须 | 基本验证 |
| 预生产 | 私有实例 | 必须 | 严格验证 |
| 生产 | 私有实例 | 必须 + 多重签名 | 完整验证 + 审批 |
10.6.3 灾难恢复计划
| 场景 | 恢复策略 | RTO | RPO |
|---|
| 数据库故障 | 主从切换 | 5 分钟 | 0(同步复制) |
| Rekor 实例故障 | 负载均衡切换 | 1 分钟 | 0 |
| 数据中心故障 | 跨区域备份恢复 | 4 小时 | 1 小时 |
| 密钥泄露 | 密钥轮换 + 重新签名 | 24 小时 | — |
10.6.4 密钥泄露应急响应
#!/bin/bash
# emergency-response.sh
# 密钥泄露应急响应脚本
set -euo pipefail
echo "=== 密钥泄露应急响应 ==="
# 1. 立即撤销泄露的密钥
echo ">>> 步骤 1: 撤销泄露的密钥"
# 如果使用 KMS:禁用密钥版本
# 如果使用本地密钥:从所有系统中删除
# 2. 确定影响范围
echo ">>> 步骤 2: 确定影响范围"
echo "搜索使用泄露密钥签名的所有条目..."
COMPROMISED_KEY="cosign-compromised.pub"
AFFECTED_ENTRIES=$(rekor-cli search --public-key="$COMPROMISED_KEY" 2>/dev/null | grep -oE '[0-9]+' || echo "")
echo "受影响的 Rekor 条目数: $(echo "$AFFECTED_ENTRIES" | wc -l)"
# 3. 记录到 Rekor(标记为撤销)
echo ">>> 步骤 3: 记录撤销信息"
# 创建撤销记录...
# 4. 生成新的密钥对
echo ">>> 步骤 4: 生成新密钥"
cosign generate-key-pair
# 5. 重新签名所有受影响的构件
echo ">>> 步骤 5: 重新签名"
# 根据具体情况重新签名...
# 6. 通知相关人员
echo ">>> 步骤 6: 通知"
echo "请通知以下人员:"
echo "- 安全团队"
echo "- 运维团队"
echo "- 受影响的下游用户"
echo "=== 应急响应完成 ==="
10.7 性能优化
10.7.1 性能基准
| 指标 | 公共实例 | 优化后的私有实例 |
|---|
| 写入延迟 | 100-500ms | 20-100ms |
| 读取延迟 | 50-200ms | 5-50ms |
| 写入吞吐 | ~100 TPS | ~1000 TPS |
| 读取吞吐 | ~1000 QPS | ~10000 QPS |
10.7.2 优化建议
| 组件 | 优化策略 |
|---|
| Rekor Server | 增加实例数、启用 Redis 缓存 |
| Trillian | 优化 Sequencer 批量大小 |
| MySQL | 增加缓冲池、优化索引、SSD 存储 |
| 网络 | CDN 缓存静态响应、减少跨区域调用 |
| 客户端 | 缓存验证结果、批量查询 |
10.8 安全加固检查清单
10.8.1 基础设施安全
| 检查项 | 状态 | 说明 |
|---|
| TLS 1.2+ 启用 | ✅/❌ | 所有 API 端点 |
| 内网隔离 | ✅/❌ | Trillian/MySQL 不暴露公网 |
| 防火墙配置 | ✅/❌ | 仅开放必要端口 |
| 定期更新 | ✅/❌ | 镜像和依赖更新 |
| 漏洞扫描 | ✅/❌ | 定期扫描容器镜像 |
10.8.2 访问控制
| 检查项 | 状态 | 说明 |
|---|
| API 认证 | ✅/❌ | 内部 API 需要认证 |
| RBAC 配置 | ✅/❌ | 最小权限原则 |
| 审计日志 | ✅/❌ | 所有访问记录 |
| 密钥轮换 | ✅/❌ | 定期轮换策略 |
10.9 常见陷阱与解决方案
| 陷阱 | 表现 | 解决方案 |
|---|
| Tag 不可信赖 | latest 被覆盖 | 使用 digest 签名和验证 |
| 证书过期误解 | 验证失败 | 理解 integratedTime 的含义 |
| 公共实例速率限制 | 429 错误 | 部署私有实例或实现退避重试 |
| 密钥硬编码 | 安全风险 | 使用 KMS 或无密钥签名 |
| 忽略包含证明 | 安全漏洞 | 始终验证包含证明 |
| 单一签名 | 高风险系统 | 多重签名策略 |
10.10 本章总结
关键要点
| 领域 | 核心实践 |
|---|
| 签名策略 | 使用无密钥签名 + KMS 混合策略 |
| 验证策略 | 验证签名 + 身份 + Rekor 包含证明 |
| CI/CD 集成 | GitHub Actions / GitLab CI 自动化 |
| 监控 | Prometheus + Grafana + 告警 |
| 合规 | 定期审计报告 + SLSA 等级提升 |
| 企业部署 | 私有实例 + 高可用 + 灾难恢复 |
行动项清单
立即行动 (Week 1-2)
短期行动 (Month 1-3)
中期行动 (Month 3-6)
长期行动 (Month 6+)
扩展阅读
🎉 恭喜! 你已经完成了 Rekor 透明日志的全部 10 章教程。从第 1 章的概念理解到第 10 章的企业级最佳实践,你现在应该具备了在生产环境中使用 Rekor 保护软件供应链的知识和技能。
如有任何问题,欢迎参考 Sigstore 社区 获取帮助。