美文网首页dibo
Nginx的防盗链技能

Nginx的防盗链技能

作者: OOM_Killer | 来源:发表于2019-08-03 17:34 被阅读0次

防盗链是什么意思呢?举个简单的例子,我买了某个视频的版权,还花了大价钱买了CDN,但是其他人直接链接指向我的这个视频,那我这视频直接出现在别人网站的页面上,那我岂不巨亏。
网站资源被盗链简单来说就是别人不是从你的网站通过下载资源,被盗链的几种可能情况:
1、在人气非常旺的网站、论坛、社区的网页里直接引用了你网站上的图片,或者直接在其他网页(使用flash或媒体播放插件)里嵌入了你网站上的mp3。
2、在人气非常旺的网站、论坛、社区里提供了你的资源的下载地址。
3、你网站的资源可能被一些下载软件列入了“资源候选名单”,当其他人用下载工具下载相同的文件时,下载软件会自动找上门并且从你的服务器下载。

简单有效的防盗链措施 referer 模块

  • 原理:
    某网站通过url引用了你的页面,当用户在浏览器上点击了url时,http请求的头部会通过referer头部,将该网站的当前url带上,告诉服务器本次请求是从哪里发起的。
    通过referer模块,用invalid_referer 变量根据配置判断referer头部是否合法。
    http://nginx.org/en/docs/http/ngx_http_referer_module.html
  • valid_referer 指令
    参数:
  • none 允许确实referer头部的请求访问
  • block 允许referer头部没有对应的值的请求访问
  • server_names 若referer中的域名与server_name 中的本机某个域名匹配则允许访问。(或可以指定表达式)
valid_referers none blocked server_names
               *.example.com example.* www.example.org/galleries/
               ~\.google\.;

if ($invalid_referer) {
    return 403;
}
$ curl -H"Host:referer.wjx.cn" -H"referer: http://referer.wjx.com" 127.0.0.1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
 Sorry for the inconvenience.<br/>
Please report this message and include the following information to us.<br/>
Thank you very much!</p>

可以看到referer 模块生效了,因为referer头带的 referer.wjx.com 并没有在配置中匹配到。
但是这种是比较low的,对防御大部分浏览器还行,但是防御自定义客户端伪造头部就没法了。

secure_link 防盗链

secure_link 是nginx官方提供的防盗链工具,但是默认没有编译进nginx中,需要添加参数 -with-http_secure_link_module
http://nginx.org/en/docs/http/ngx_http_secure_link_module.html

  • 原理
    由服务器(nginx)生成加密后的安全链接 URL,返回给客户端,客户端使用安全的url访问nginx,由nginx的secure_link 变量去验证是否验证通过。

    • 哈希算法不可逆。
    • 客户端只能拿到执行过hash的url。
    • 仅生成URL的服务器,验证URL是否安全的nginx可以保存hash前的原始字符串。
    • 原始字符串由以下部分组成。
      • 资源位置
      • 用户信息(如IP)
      • 时间戳(是安全URL及时过期)
      • 密钥,仅服务器拥有
  • secure_link 变量值
    1、为空则验证不通过。2、为0则URL过期。3、为1则验证通过。

  • secure_link_expire 时间戳

命令生成安全连接

  • 原始请求
    • /test.txt?md5=md5生成值&expire=时间戳(如2147483647)
  • 生成md5
    • echo -n '时间戳URL客户端IP密钥'|openssl md5 -binary |openssl base64|tr +/- |rd -d =

Nginx 配置

location /s/ {
    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;
    }

    ...
}
实验
  1. 复杂的配置 (uri ip 时间戳)
server {
   listen 80;
   server_name securelink.wjx.cn;
   default_type text/plain;
   location / {
      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;
      }

      return 200 '$secure_link:$secure_link_expires\n';
   }     
 }
$ echo -n '2147483647/test127.0.0.1 secret' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =
sKLl-v-vXj9Pnk8rJ-1QYQ
$ curl 'securelink.wjx.cn/test?md5=sKLl-v-vXj9Pnk8rJ-1QYQ&expires=2147483647'
1:2147483647

  1. 仅对 URI 进行哈希的简单方法
  • 将请求URL分为三个部分, /prefix/hash/link
  • hash 生成方法
  • 用secure_link_secret secret 配置密钥。

原始请求:

  • link

生成的安全请求

  • /prefix/md5/link

生成md5

  • echo -n 'linksecret'|openssl md5 -hex
server {
   listen 80;
   server_name securelink.wjx.cn;
   default_type text/plain;

   location /p/ {
      secure_link_secret mysecret2;

      if ($secure_link = "") {
         return 403;
      }

      rewrite ^ /secure/$secure_link;
   }

   location /secure/ {
      return 200 'ok !!! \n';
      internal;
   }
}
$ echo -n 'linkmysecret2' | openssl md5 -hex
(stdin)= 79828d1d5383001c6e008ee02058df44

$ curl 'http://securelink.wjx.cn/p/79828d1d5383001c6e008ee02058df44/link'
ok !!! /secure/link 

参考: https://www.cnblogs.com/wangyongsong/p/8204698.html

相关文章

网友评论

    本文标题:Nginx的防盗链技能

    本文链接:https://www.haomeiwen.com/subject/cwvjdctx.html