checklist

OSS + ESA + 服务端上线前检查单

架构目标:

reader.fcana.com -> ESA -> 书店 UI
reader-data.fcana.com -> ESA -> JSON / OPDS / 下载授权
reader-file.fcana.com -> ESA -> 私有 OSS

说明:P0 为上线硬门槛;P1 为强烈建议;P2 为上线后优化项。

0. 测试样本

准备一个带空格和中文的测试对象,用来发现路径编码问题:

bookshelf-prod/books/preflight/a b-中文.epub

记录:

  • Bucket:________________
  • Region:cn-beijing
  • Prefix:bookshelf-prod
  • 文件域名:reader-file.fcana.com
  • 数据域名:reader-data.fcana.com

A. OSS

编号级别检查项检测方法预期结果结果
A01P0Bucket 地域OSS 控制台华北2(北京)
A02P0Bucket 权限OSS 控制台私有,未开启公共读
A03P0公共访问阻断OSS ACL/Policy无匿名读取权限
A04P0Object Key控制台搜索测试对象完整 Key 含 bookshelf-prod/
A05P0裸 OSS 直链curl.exe -I403,不能是 200
A06P0RAM 写入权限RAM Policy仅目标 Bucket/Prefix;无管理权限
A07P0服务端上传上传测试文件OSS 中存在且大小一致
A08P1Content-Type查看对象 MetadataEPUB 为 application/epub+zip
A09P1对象不可变查看 Key 规则更新后使用新 hash/版本路径
A10P1删除保护查看清理逻辑不使用全桶 sync --delete

Windows CMD:

curl.exe -I "https://BUCKET.oss-cn-beijing.aliyuncs.com/bookshelf-prod/books/preflight/a%20b-%E4%B8%AD%E6%96%87.epub"

通过:403 Forbidden。返回 200 时立即停止上线。


B. 服务端配置

编号级别检查项检测方法预期结果结果
B01P0Endpoint查看 Storage Profile北京公网或可用内网 Endpoint
B02P0Bucket查看配置只填 Bucket 名
B03P0Region查看配置cn-beijing
B04P0Prefix查看配置bookshelf-prod,无首尾 /
B05P0CDN Base URL查看配置https://reader-file.fcana.com
B06P0下载模式查看配置阿里云 ESA HMAC CDN
B07P0HMAC Secret查看状态,不打印明文与 ESA 使用同一密钥
B08P0Secret 安全搜 Git/日志/前端无明文 Secret、AK、SK
B09P0签名协议检查代码exp + sig,HMAC-SHA256,小写 hex
B10P0时间戳查看真实 URLUnix 秒,不是毫秒
B11P0路径一致比较三处路径OSS Key、CDN path、签名 path 完全一致
B12P0特殊字符生成测试 URL%2520 或双重编码
B13P0无 OSS 原生签名检查 LocationOSSAccessKeyId/x-oss-signature
B14P0下载授权带账号请求302/307reader-file
B15P0授权端点不缓存查看响应头Cache-Control: private, no-store
B16P0未登录访问不带凭据请求401/403,无 Location
B17P0越权访问无权限账号请求403/404,无 Location
B18P1TTL比较 exp-now建议约 300 秒
B19P1幂等入库同 key 重复提交只产生一个正式书目
B20P1健康检查请求 /readyz200
curl.exe -u "USERNAME:PASSWORD" -D - -o NUL "https://reader-data.fcana.com/download/BOOK_ID"

通过响应:

302
Location: https://reader-file.fcana.com/bookshelf-prod/...?exp=...&sig=...
Cache-Control: private, no-store

C. ESA DNS 与私有 OSS 回源

编号级别检查项检测方法预期结果结果
C01P0DNS 记录ESA 控制台reader-file 已开启代理
C02P0CNAMEnslookup指向 ESA,不是 VPS IP
C03P0HTTPScurl.exe -I证书有效且域名匹配
C04P0源站类型ESA 控制台OSS,私有访问-同账号
C05P0BucketESA 控制台与服务端上传 Bucket 相同
C06P0回源授权ESA 控制台自动授权成功,只读回源
C07P0不经 Nginx查看 Nginx/流量文件请求不进入 VPS
C08P1静态网站冲突OSS 控制台未启用静态网站托管
nslookup reader-file.fcana.com

D. ESA HMAC 旁路函数

编号级别检查项检测方法预期结果结果
D01P0函数已发布函数和 Pages有生产版本
D02P0旁路模式路由配置Bypass 已开启
D03P0路由范围查看路由只匹配 bookshelf-prod/books/*covers/*
D04P0算法一致比对代码HMAC-SHA256、UTF-8 Secret、64 位 hex
D05P0签名原文固定向量验证encoded_path + exp
D06P0无签名直接请求403
D07P0错误签名sig 一位403
D08P0过期签名使用旧 URL403
D09P0过远未来 exp手工构造403
D10P0合法签名服务端生成 URL200206
D11P0中文/空格路径测试对象合法 URL 成功,篡改编码失败
D12P1方法限制POST/PUT/DELETE403/405
D13P1函数指标指标页面无持续脚本错误或 CPU 超限
curl.exe -I "https://reader-file.fcana.com/bookshelf-prod/books/preflight/a%20b-%E4%B8%AD%E6%96%87.epub"

必须返回 403


E. ESA 缓存

编号级别检查项检测方法预期结果结果
E01P0文件缓存规则查看规则只匹配文件域名的 books/covers
E02P0Cache Key 忽略 exp查看规则exp 不参与 Cache Key
E03P0Cache Key 忽略 sig查看规则sig 不参与 Cache Key
E04P0无全局参数冲突查看全局设置未开启冲突的全站忽略 query
E05P0首次请求合法 URL AMISS 或首次回源
E06P0第二次请求同路径合法 URL BHIT 或 Age 增加
E07P0HIT 后仍验签错误签名访问已缓存对象403
E08P0错误响应不长缓存先错后对合法请求不持续命中旧 403/404
E09P1TTL查看规则不可变 hash 路径可长缓存
E10P1刷新流程刷新测试对象能正确清除对应缓存

最关键的三步:

合法 URL A -> MISS
合法 URL B(同路径、不同 exp/sig)-> HIT
错误签名 URL -> 403

错误签名得到 200 时立即停止上线。


F. Range 与大文件

编号级别检查项检测方法预期结果结果
F01P0Range请求 0-1023206 Partial Content
F02P0Content-Range看响应头bytes 0-1023/总大小
F03P0Accept-Ranges看响应头bytes
F04P0文件大小HEAD/完整下载与 OSS 对象一致
F05P1Content-Type看响应头类型正确
F06P1文件名实际下载中文名可用,至少有 ASCII fallback
F07P1断点续传中断后续传不从头重新下载
F08P0不经 VPS观察网卡VPS 无文件主体流量
curl.exe -H "Range: bytes=0-1023" -D - -o range-test.bin "完整合法签名URL"

G. CORS(前端使用 fetch/Blob 时升为 P0)

编号级别检查项检测方法预期结果结果
G01P1Allow-Origin带 Origin 请求https://reader.fcana.com
G02P1Expose-Headers看响应暴露 Length、Range、Disposition 等
G03P1Credentials看响应不依赖 Cookie 时不启用
G04P1OPTIONS预检请求200/204 或确认业务不触发预检
G05P1浏览器实测UI 点击下载无 CORS 报错
curl.exe -I -H "Origin: https://reader.fcana.com" "完整合法签名URL"

H. 旧 ESA 规则迁移

编号级别检查项检测方法预期结果结果
H01P0新下载端点绕过缓存请求两次每次重新鉴权/签发
H02P0JSON/API 动态查看规则/api/* 不共享缓存
H03P0OPDS 权限两账号请求内容按权限隔离
H04P0旧规则不抢先检查顺序和 Host新旧规则互不覆盖
H05P0旧 Authorization Cache Key查看匹配范围不作用于 reader-file
H06P1旧链路可回滚保留配置观察期内可切回
H07P1协议接口无 JS ChallengeKoodo/KOReader 实测返回 XML/302,不返回 HTML
H08P1管理 API 未全放行查看 WAF仍有正常安全防护
H09P2清理旧规则稳定后执行删除旧下载缓存和 Koodo 白名单

I. 端到端

编号级别检查项检测方法预期结果结果
I01P0上书上传测试 EPUB任务成功、对象进入 OSS
I02P0JSON请求 catalog书目和下载入口正确
I03P0OPDS客户端/curlacquisition 指向新授权端点
I04P0UI浏览器封面、分类、下载正常
I05P0跳转链点击下载reader-data -> 302 -> reader-file
I06P0完整性比较 hash/打开 EPUB文件完整可读
I07P0权限隔离无权限账号UI/JSON/OPDS/下载均不可越权
I08P0隐藏/删除隐藏书目后重试新请求立即不可见;旧 URL 到期失效
I09P1客户端兼容Koodo/KOReader能下载、识别文件名和格式
I10P1移动端手机浏览器能下载或打开系统分享
I11P1监控下载大文件ESA/OSS 有流量,VPS 无主体流量

J. Go / No-Go

以下任意一项出现,立即 No-Go:

  • ☐ OSS 裸直链返回 200
  • reader-file 无签名返回 200
  • ☐ 错误签名在缓存 HIT 后返回 200
  • ☐ OSS Key、CDN path、签名 path 不一致
  • ☐ 空格或中文路径发生双重编码
  • ☐ 服务端生成 OSS 原生预签名参数
  • ☐ 下载授权 302 被共享缓存
  • ☐ 无权限用户取得 Location
  • ☐ Range 不返回 206
  • ☐ 文件主体流量仍经过 VPS
  • ☐ Secret、AK、SK 出现在 Git、前端或日志
  • ☐ 新 ESA 规则被旧规则覆盖

允许上线的条件:

  • ☐ 所有 P0 通过
  • ☐ P1 失败项均有风险说明和处理日期
  • ☐ 已备份数据库、服务端配置和 ESA 规则
  • ☐ 已完成一份真实 EPUB 的完整端到端下载
  • ☐ 已完成“缓存 HIT 后错误签名仍 403”测试
  • ☐ 已记录回滚操作

K. 推荐上线顺序

1. 备份旧配置
2. 上传测试对象
3. 验证 OSS 裸直链 403
4. 接入 reader-file 私有 OSS
5. 发布 HMAC 旁路函数
6. 验证无签名/错误/过期均 403
7. Cache Key 忽略 exp 和 sig
8. 验证 MISS -> HIT -> 错误签名仍 403
9. 验证 Range 206
10. 服务端启用新 Storage Profile
11. 上传真实测试刊物
12. 验证 JSON、OPDS、UI、302 和完整下载
13. 小范围切换
14. 观察至少 24 小时
15. 再清理旧 Koodo ESA 规则

L. 回滚

1. 暂停新上书
2. 下载入口切回旧端点
3. 恢复旧 Storage Profile
4. 保留 OSS 新对象,不批量删除
5. 禁用 reader-file 函数路由
6. 恢复旧 ESA 规则
7. 排查 prefix、编码、HMAC、Cache Key 和规则优先级

回滚时不要公开 Bucket,也不要为了临时可用而关闭 HMAC 后让文件域名裸奔。