Nginx secure_link模块可实现无需后端校验的可控防盗链,通过URL中st(MD5+Base64签名)和e(过期时间戳)参数,由Nginx在边缘自动验证签名与时效性,任一不符即返回403。

直接用 Nginx 的 secure_link 模块生成带签名和过期时间的下载链接,就能实现真正可控的防盗链——不依赖 Referer(可伪造),也不需要后端实时校验,整个过程由 Nginx 在边缘完成。
核心原理:URL 里藏“密码+时效”
每个合法链接形如:/download/app-v2.3.zip?st=abc123&e=1717027200
其中:
-
st 是对
密钥 + 请求路径 + 过期时间戳计算 MD5 后再 Base64 编码的结果 - e 是 Unix 秒级时间戳,代表链接失效时刻
- Nginx 收到请求时自动重算签名、比对时间,任一不符即返回 403
服务端生成安全链接(Python 示例)
签名必须由可信服务端生成,不能暴露密钥。例如用 Python 快速构造:
gen_download_url("/download/report.pdf")
- 使用
secure_link $arg_st,$arg_e提取 URL 中的参数 -
secure_link_md5 "your_secret$uri$arg_e"——$uri包含前导/,必须与签名时完全一致 - 用
$secure_link变量判断结果:"1"表示有效,"0"表示已过期,空字符串表示签名错误 - 验证失败统一返回 403,避免泄露校验逻辑
安全增强建议
生产环境需注意几个易忽略但关键的点:
- 密钥定期轮换,并通过 Nginx 变量或 env 注入,避免硬编码在配置中
- 确保服务器时间准确(NTP 同步),否则时间戳校验会频繁失败
- 不要把
/download/目录直接映射为可列目录,禁用 autoindex - 若配合 CDN 使用,确认 CDN 不会缓存 403 响应,也不应缓存带
st/e参数的 URL(可加 Cache-Control: private)










