V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Elizabevil
V2EX  ›  程序员

Nginx+HLS 如何防盜鏈

  •  
  •   Elizabevil · 100 天前 · 1613 次点击
    这是一个创建于 100 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Nginx+HLS 如何防盜鏈

    业务逻辑: user—>服务接口( A 服务器)-->查询 直播 播放链接 http://x.m3u8 ( B 服务器) --》 301 跳转 user—>直连:http://x.m3u8

    ffmpeg 拉取第三方直播 到本地 xxx.m3u8 (默认同时只存 5 个 ts 文件),再使用 nginx 代理本地文件提供对外播放地址

    /usr/bin/ffmpeg http://xxxx -vcodec copy -scodec copy -acodec copy -hls_flags delete_segments -hls_delete_threshold 1 -hls_time 5 xx.m3u8
    
    #EXTM3U
    #EXT-X-VERSION:3
    #EXT-X-TARGETDURATION:5
    #EXT-X-MEDIA-SEQUENCE:3
    #EXTINF:5.000000,
    xx3.ts
    #EXTINF:5.000000,
    xx4.ts
    #EXTINF:5.000000,
    xx5.ts
    #EXTINF:5.000000,
    xx6.ts
    #EXTINF:5.000000,
    xx7.ts
    

    由于是直播链接,每 1min 都会重新写入 m3u8 文件,意味着每 1min 浏览器/播放器都要重新请求.m3u8

    问题:想实现播放鉴权(时间验证),目前在 301 跳转时播放链接上加参数 http://x.m3u8?token=jwtToken

    但后续 浏览器/播放器都要重新请求 时 m3u8 用的时统一个 url 意味着?token=jwtToken 参数不会变化,如果 jwtToken 过期就一直过期 即

    0:xxxx -->http 301-->http://x.m3u8?token=jwtToken1  首次
    1: http://x.m3u8?token=jwtToken1	//正常鉴权播放
    2: http://x.m3u8?token=jwtToken1 //鉴权过期 err
    3: http://x.m3u8?token=jwtToken1 //播放器重试 jwtToken 不会变 err (问题在此处)
    

    大佬们有没有什么好的解决办法/或思路?

    限制:

    • user 必须经 ( A 服务器)服务接口 才能拿到播放地址
    • user 拿到播放地址 需要 30x 播放( B 服务器),而不是走 A 服务器代理(消耗 A 的宽带)
    9 条回复    2024-08-19 09:27:15 +08:00
    Elizabevil
        2
    Elizabevil  
    OP
       99 天前
    最好是在请求阶段鉴权,而不是文件加密
    kaf
        3
    kaf  
       99 天前
    Nginx 里判断$referer 就可以了吧
    supersu
        4
    supersu  
       99 天前 via Android
    nginx 支持 hmac 签名鉴权模块,感觉可以搞一下~
    ysxb1145
        5
    ysxb1145  
       99 天前 via Android   ❤️ 1
    玩 tvheadend 直播源服务器的大佬们为了防止白嫖狗吸血鬼盗链都会加密码,加密码之后获取到的直播链接都会有专属 key ,没有 key 访问就会 401 ,反倒是酒店的直播服务器被盗链很厉害甚至一些小本经营的酒店直接被薅到关闭直播服务器
    amlee
        6
    amlee  
       99 天前
    你的服务接口 A 相当于内嵌了一个认证接口,查询直播播放链接的时候自动认证并下发了一个 jwt token 。

    可以将认证单独拆出来做一个服务接口。
    jwtToken 里面不是可以带上过期时间吗,客户端判断 jwtToken 有效期,然后去认证接口重新认证,拿到新的 jwtToken 不就行了
    esile
        7
    esile  
       99 天前 via Android
    token 最好加 IP 认真阻止盗链狗模拟请求后直接引用
    starofazeroths
        8
    starofazeroths  
       98 天前 via iPhone
    防盜链是一个重要的安全措施,可以保护你的视频内容不被未经授权的网站使用。以下是一些使用 Nginx 和 HLS (HTTP Live Streaming) 实现防盗链的方法:

    1. 使用 Referer 检查

    在 Nginx 配置中添加 referer 检查:

    ```nginx
    location /hls/ {
    valid_referers none blocked server_names *.yourdomain.com yourdomain.com;
    if ($invalid_referer) {
    return 403;
    }
    # 其他 HLS 相关配置
    }
    ```

    这将只允许来自你指定域名的请求。

    2. 使用令牌验证

    生成一个带有过期时间的令牌,并在 URL 中包含这个令牌:

    ```nginx
    location /hls/ {
    secure_link $arg_md5,$arg_expires;
    secure_link_md5 "$secure_link_expires$uri$remote_addr secret";

    if ($secure_link = "") {
    return 403;
    }
    if ($secure_link = "0") {
    return 410;
    }
    # 其他 HLS 相关配置
    }
    ```

    客户端需要在请求 URL 中包含正确的 md5 和 expires 参数。

    3. 使用 Cookie 验证

    在用户登录后设置一个 Cookie ,然后在 Nginx 中验证这个 Cookie:

    ```nginx
    location /hls/ {
    if ($http_cookie !~* "authorized=1") {
    return 403;
    }
    # 其他 HLS 相关配置
    }
    ```

    4. 对 .m3u8 和 .ts 文件进行不同的处理

    ```nginx
    location ~ \.m3u8$ {
    # 对 m3u8 文件进行更严格的验证
    }

    location ~ \.ts$ {
    # 对 ts 文件可以稍微宽松一些
    }
    ```

    5. 使用加密的 HLS

    使用 Apple 的 FairPlay Streaming 或其他 DRM 解决方案来加密你的 HLS 流。

    6. 限制 IP 访问频率

    ```nginx
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    location /hls/ {
    limit_req zone=one burst=5;
    # 其他 HLS 相关配置
    }
    ```

    7. 使用 HTTPS

    确保你的 HLS 流通过 HTTPS 提供,这可以防止中间人攻击。

    8. 定期更换 URL

    对于重要的直播内容,可以考虑定期更换流的 URL 。

    实施这些方法时,需要根据你的具体需求和安全级别来选择合适的组合。同时,要注意平衡安全性和用户体验,过于严格的限制可能会影响正常用户的访问。
    Elizabevil
        9
    Elizabevil  
    OP
       98 天前
    @amlee 意思是讓前端去重新請求,而不是後端來處理
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5611 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 123ms · UTC 08:36 · PVG 16:36 · LAX 00:36 · JFK 03:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.