secure_link 是 Nginx 内置防盗链模块,通过时间戳、URI 和密钥拼接后 MD5 签名校验实现 URL 访问控制;需在配置中启用 secure_link 指令并严格匹配签名逻辑,支持 IP 绑定与过期验证。

secure_link 模块是什么
secure_link 是 Nginx 官方提供的一个内置模块(从 1.1.12 和 1.0.9 版本起默认编译进核心),用于实现基于时间戳和密钥的 URL 签名验证,本质是服务端对请求链接做 MD5 校验,防止资源被未授权盗用。它不依赖外部库,无需额外安装,但需要在配置中显式启用并正确设置参数。
签名生成逻辑与关键参数
secure_link 使用三段式结构:路径 + 过期时间戳 + 密钥拼接后取 MD5 前 32 位(或前 16 字节 Base64 编码),最终嵌入 URL 查询参数。典型格式为:
/video/sample.mp4?md5=ABC123&expires=1717027200
其中:
-
md5:对
expires+URI+secret_key(如"1717027200/video/sample.mp4/my_secret")进行 MD5 计算,取前 16 字节转为 base64(URL 安全编码),再去除=并替换+为-、/为_ - expires:Unix 时间戳,单位秒,超过则拒绝访问
- secret_key:服务端配置的密钥,必须严格保密,不同业务可配不同 key 实现隔离
Nginx 配置要点与防盗链实战
在 server 或 location 块中启用校验:
location /video/ {
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires$uri$remote_addr my_secret";
<pre class="brush:php;toolbar:false;">if ($secure_link = "") {
return 403;
}
if ($secure_link = "0") {
return 410;
}
# 合法请求继续处理
alias /data/videos/;}
说明:
-
secure_link $arg_md5,$arg_expires:从 URL 中提取md5和expires参数 -
secure_link_md5 "...”:构造服务端签名原文,注意顺序必须与客户端完全一致;加入$remote_addr可绑定 IP,增强安全性(需同步在客户端生成时加入) -
$secure_link变量值为""表示参数缺失或格式错误;为"0"表示签名不匹配或已过期 - 推荐搭配
alias而非root,避免路径拼接风险
常见问题与加固建议
实际部署中容易踩坑:
- 时间不同步:Nginx 服务器与生成签名的服务时间差超过 expires 容忍范围,导致频繁 410;建议统一 NTP 同步
- URI 不一致:客户端请求的 URI(含 query string)必须与签名时使用的 URI 完全相同;签名时不要带
?md5=...,否则校验失败 - 密钥泄露:密钥硬编码在配置里不安全,生产环境建议通过变量间接引入(如 env + map 模块动态加载)
- IP 绑定失效:若用户走代理或 CDN,
$remote_addr变成 CDN IP,此时应改用$http_x_forwarded_for并确保可信来源 - 可配合
add_header X-Secure-Link-Status $secure_link;方便调试,但上线后关闭


















