听说你的资源被盗用了,那你知道 Nginx 怎么防盗链吗?

简单有效的防盗链手段
场景如果做过个人站点的同学,可能会遇到别人盗用自己站点资源链接的情况,这就是盗链 。说到盗链就要说一个 HTTP 协议的 头部,referer 头部 。当其他网站通过 URL 引用了你的页面,用户在浏览器上点击 URL 时,HTTP 请求的头部会通过 referer 头部将该网站当前页面的 URL 带上,告诉服务器本次请求是由谁发起的 。
例如,在谷歌中搜索 Nginx 然后点击链接:

听说你的资源被盗用了,那你知道 Nginx 怎么防盗链吗?

文章插图
 
在打开的新页面中查看请求头会发现,请求头中包含了 referer 头部且值是 https://www.google.com/ 。
听说你的资源被盗用了,那你知道 Nginx 怎么防盗链吗?

文章插图
 
像谷歌这种我们是允许的,但是有一些其他的网站想要引用我们自己网站的资源时,就需要做一些管控了,不然岂不是谁都可以拿到链接 。
目的这里目的其实已经很明确了,就是要拒绝非正常的网站访问我们站点的资源 。
思路
  • invalid_referer 变量referer 提供了这个变量,可以用来配置哪些 referer 头部合法,也就是,你允许哪些网站引用你的资源 。
referer 模块要实现上面的目的,referer 模块可得算头一号,一起看下 referer 模块怎么用的 。
  • 默认编译进 Nginx,通过 --without-http_referer_module 禁用
referer 模块有三个指令,下面看一下 。
Syntax: valid_referers none | blocked | server_names | string ...;Default: —Context: server, locationSyntax: referer_hash_bucket_size size;Default: referer_hash_bucket_size 64; Context: server, locationSyntax: referer_hash_max_size size;Default: referer_hash_max_size 2048; Context: server, location
  • valid_referers 指令,配置是否允许 referer 头部以及允许哪些 referer 访问 。
  • referer_hash_bucket_size 表示这些配置的值是放在哈希表中的,指定哈希表的大小 。
  • referer_hash_max_size 则表示哈希表的最大大小是多大 。
这里面最重要的是 valid_referers 指令,需要重点来说明一下 。
valid_referers 指令可以同时携带多个参数,表示多个 referer 头部都生效 。
参数值
  • none允许缺失 referer 头部的请求访问
  • block:允许 referer 头部没有对应的值的请求访问 。例如可能经过了反向代理或者防火墙
  • server_names:若 referer 中站点域名与 server_name 中本机域名某个匹配,则允许该请求访问
  • string:表示域名及 URL 的字符串,对域名可在前缀或者后缀中含有 * 通配符,若 referer 头部的值匹配字符串后,则允许访问
  • 正则表达式:若 referer 头部的值匹配上了正则,就允许访问
invalid_referer 变量
  • 允许访问时变量值为空
  • 不允许访问时变量值为 1
实战下面来看一个配置文件 。
server { server_name referer.ziyang.com;listen 80; error_log logs/myerror.log debug; root html; location /{valid_referers none blocked server_names*.ziyang.com www.ziyang.org.cn/nginx/~.google.;if ($invalid_referer) {return 403;}return 200 'validn'; }}那么对于这个配置文件而言,以下哪些请求会被拒绝呢?
curl -H 'referer: http://www.ziyang.org.cn/ttt' referer.ziyang.com/curl -H 'referer: http://www.ziyang.com/ttt' referer.ziyang.com/curl -H 'referer: ' referer.ziyang.com/curl referer.ziyang.com/curl -H 'referer: http://www.ziyang.com' referer.ziyang.com/curl -H 'referer: http://referer.ziyang.com' referer.ziyang.com/curl -H 'referer: http://image.baidu.com/search/detail' referer.ziyang.com/curl -H 'referer: http://image.google.com/search/detail' referer.ziyang.com/我们需要先来解析一下这个配置文件 。valid_referers 指令配置了哪些值呢?
valid_referers none blocked server_names*.ziyang.com www.ziyang.org.cn/nginx/~.google.;
  • none:表示没有 referer 的可以访问
  • blocked:表示 referer 没有值的可以访问
  • server_names:表示本机 server_name 也就是 referer.ziyang.com 可以访问
  • *.ziyang.com:匹配上了正则的可以访问
  • www.ziyang.org.cn/nginx/:该页面发起的请求可以访问
  • ~.google.:google 前后都是正则匹配
下面就实际看下响应:
# 返回 403,没有匹配到任何规则?~ curl -H 'referer: http://www.ziyang.org.cn/ttt' referer.ziyang.com/<html><head><title>403 Forbidden</title></head><body><center><h1>403 Forbidden</h1></center><hr><center>nginx/1.17.8</center></body></html>?~ curl -H 'referer: http://image.baidu.com/search/detail' referer.ziyang.com/<html><head><title>403 Forbidden</title></head><body><center><h1>403 Forbidden</h1></center><hr><center>nginx/1.17.8</center></body></html># 匹配到了 *.ziyang.com?~ curl -H 'referer: http://www.ziyang.com/ttt' referer.ziyang.com/valid?~ curl -H 'referer: http://www.ziyang.com' referer.ziyang.com/valid# 匹配到了 server name?~ curl -H 'referer: http://referer.ziyang.com' referer.ziyang.com/valid# 匹配到了 blocked?~ curl -H 'referer: ' referer.ziyang.com/valid# 匹配到了 none?~ curl referer.ziyang.com/valid# 匹配到了 ~.google.?~ curl -H 'referer: http://image.google.com/search/detail' referer.ziyang.com/valid


推荐阅读