Secure-Link-Md5 不是 Nginx 官方模块,仅存在于部分第三方定制版;标准 Nginx 仅支持原生 secure_link 指令(硬编码 MD5 算法),其签名公式为 md5($secret + $uri + $arg_e),需严格对齐客户端计算逻辑。

Secure-Link-Md5 不是 Nginx 官方模块,它只存在于某些第三方定制版(如某些 OpenResty 衍生包或旧版 nginx-plus 早期实验分支),标准 Nginx(包括 mainline 和 stable)完全不支持 secure_link_md5 指令。 试图在 vanilla Nginx 中配置它只会触发 unknown directive "secure_link_md5" 错误,且无替代内置方案。
为什么你找不到 secure_link_md5?
标准 Nginx 的访问控制依赖两个原生命令:secure_link 和 secure_link_md5 —— 但后者从未被合并进主线。Nginx 官方只实现了基于 HMAC-SHA1 的 secure_link(配合 secure_link_secret 或更现代的 secure_link_md5 的替代逻辑其实并不存在)。很多中文文档把 secure_link 的 MD5 签名示例误标为 secure_link_md5,造成持续混淆。
常见错误现象包括:
- 配置中写了
secure_link_md5 $arg_st $arg_e;,reload 时直接报错 - 查不到官方文档页,只有零星 GitHub issue 或过时博客引用
- OpenResty 用户误以为自带,实则需手动编译
ngx_http_secure_link_module的扩展变体
用标准 secure_link 实现等效指纹验证
真正可用的是 secure_link 指令,它默认使用 MD5(注意:不是可选配置,是硬编码算法),但签名构造方式与常见“MD5(secret+uri+expires)”模式一致。关键在于客户端生成签名时必须严格对齐 Nginx 解析逻辑。
实操要点:
- Nginx 配置中必须用
secure_link $arg_st,$arg_e;(逗号分隔,顺序不能颠倒) -
$arg_st是签名字符串,$arg_e是过期时间戳(秒级 Unix time) - 服务端计算签名公式为:
md5($secret + $uri + $arg_e),其中$uri是解码后的规范化路径(不含 query string,且已 decode) - 若资源路径含中文或特殊字符,客户端必须先
decodeURIComponent再拼接,否则签名不匹配 - 示例链接:
/video/abc.mp4?st=xxx&e=1717027200,Nginx 内部会取/video/abc.mp4参与计算
OpenResty 用户:别依赖“内置 secure_link_md5”
即使你用的是 OpenResty,其默认构建也不含增强版 secure link 模块。部分发行版(如某些 Debian/Ubuntu 的 nginx-extras)可能打包了第三方 patch,但行为不统一:
- 检查是否存在:
nginx -V 2>&1 | grep -o 'secure_link',仅出现secure_link表示只有原生支持 - 若真需要 SHA256、自定义 salt、或 URI 参数白名单等能力,应改用
lua-resty-session+resty.sha256手写鉴权逻辑 - 用 Lua 实现的好处:签名算法可控、可集成 JWT、可查数据库做动态权限,且调试信息明确(比如打印出实际参与计算的字符串)
- 性能影响有限:一次 SHA256 计算耗时通常
最容易被忽略的一点:Nginx 的 secure_link 对 $uri 的处理是“解码后比对”,而大多数前端 URL 构造函数(如 encodeURIComponent)默认对斜杠 / 也编码,导致客户端算的签名和 Nginx 内部算的不一致 —— 这个细节几乎每次部署都会卡人半小时以上。











