如何保护Nginx RTMP搭建的HLS链接仅在自有网站可用?
Nginx HLS防盗链实现方案
针对你遇到的HLS链接被盗用的问题,提供两种可行的解决方法,从易到难覆盖不同需求:
一、基于Referer域名校验(快速实现)
这种方法通过检查请求的Referer请求头,只允许来自自有域名的请求访问HLS资源,直接打开链接或其他网站嵌入的请求会被拒绝。
配置步骤:
找到Nginx配置中处理HLS资源的location块(通常是/hls),添加防盗链规则:
location /hls { # 保留你原有的HLS配置,比如MIME类型、文件根目录等 types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } # 仅允许自有域名的请求 valid_referers blocked *.yourdomain.com yourdomain.com; if ($invalid_referer) { return 403; } }
- 把
*.yourdomain.com和yourdomain.com替换成你实际的自有域名,泛域名*可以覆盖所有子域名。 blocked用来处理Referer被浏览器屏蔽的情况(部分隐私模式下浏览器会隐藏Referer),如果你希望这种情况也被拒绝,可以去掉blocked。
修改完成后,重启Nginx生效:
sudo systemctl restart nginx
二、基于签名的URL验证(高安全防伪造)
由于Referer头可以被伪造,这种方法通过生成带签名和过期时间的URL,只有签名有效且未过期的请求才会被Nginx允许,彻底杜绝盗用。
前提条件:
确保你的Nginx安装了ngx_http_secure_link_module模块,执行以下命令检查:
nginx -V
如果输出中包含--with-http_secure_link_module则可以直接使用;如果没有,需要重新编译Nginx并添加该编译参数。
配置步骤:
- 修改Nginx的HLS location块:
location /hls { # 保留原有的HLS配置 types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } # 签名验证规则 secure_link $arg_md5,$arg_expires; secure_link_md5 "your_secret_key$uri$arg_expires"; # 签名无效时返回403 if ($secure_link = "") { return 403; } # 链接过期时返回410 if ($secure_link = "0") { return 410; } }
把your_secret_key替换成你自己的随机密钥(不要泄露给他人)。
- 生成带签名的URL
你需要在自有网站的后端(比如Python、PHP)生成带签名的HLS链接,示例Python脚本:
import hashlib import time # 和Nginx配置中的密钥保持一致 SECRET_KEY = "your_secret_key" # 要访问的HLS资源路径 STREAM_URI = "/hls/stream/index.m3u8" # 设置链接有效期(这里是1小时,单位:秒) EXPIRES = int(time.time()) + 3600 # 计算MD5签名 sign_str = f"{SECRET_KEY}{STREAM_URI}{EXPIRES}".encode() md5_sign = hashlib.md5(sign_str).hexdigest() # 生成最终的带签名URL signed_url = f"https://mydomain{STREAM_URI}?md5={md5_sign}&expires={EXPIRES}" print(signed_url)
自有网站的视频播放器需要使用这个生成的带签名URL,而不是原始的无签名链接。
- 重启Nginx生效:
sudo systemctl restart nginx
注意事项
- 第一种方法适合快速解决问题,成本低但存在被绕过的可能;第二种方法安全性更高,适合对内容保护要求高的场景。
- 如果你使用CDN,需要确保CDN也支持对应的防盗链规则(Referer校验或签名验证),否则CDN层会直接返回资源,导致Nginx的规则失效。
内容的提问来源于stack exchange,提问作者SHERLOV
相关产品推荐
相关产品推荐

