一、背景与需求
最近通过分析nginx日志,发现有很多站点会到公司站点上采集行情信息。想通过nginx rewrite处理所有的盗链。具体要求如下:
1、对于白名单中的域名允许其调用行情信息;
2、对于白名单中的IP允许其调用行情信息。
说白了上面就是一个逻辑或的语句,只要满足上面的任一条件即可通过。不过,因为nginx rewrite的要求比较严格——不支持if嵌套、or 和and 等操作。所以处理起来比较麻烦。不过最后试来试去,总算工夫不负有心人,成功完成了要求。
调试这个nginx rewrite 正则是我和另外一个同事一块儿处理的,而我们写出来的最终内容虽然不同,但效果确实一样的。在些两个正则都提供一下吧。
二、方法
方法一:
location / { proxy_pass http://127.0.0.1:8080; //后端tomcat valid_referers none blocked *.abc.com *.abc.cc *.xyz.cc *.test.org ; set $ok Y; set $ref N; if ($invalid_referer) { set $ok N; } if ($remote_addr ~* ^123.23.1.11$) { set $ok "${ok}Y"; } } if ($remote_addr ~* ^25.11.33.60$) { set $ok "${ok}Y"; } if ($ok = N) { return 404; } if ($ok = NY) { set $ok Y; } if ($ok = YY) { set $ok YY; set $ref Y; } if ($http_referer = '') { set $ok "${ok}${ref}"; } if ($ok = YYY) { set $ok Y; } if ($ok = YY) { set $ok Y; } if ($ok != Y) { return 404; }
注:
1、上面写到的IP和域名是允许访问的白名单,以免泄露公司信息,在此我随便写的两个IP和几个域名。如有雷同,纯属巧合。
2、上面关于IP的部分,可能过|这个nginx 逻辑或符号写到一块。具体可以参看nginx的正则。下面的例子中也会提到。
方法二:
location ~* .(gif|jpg|png)$ { if ($http_referer ~* (.*?).abc.org|(.*?).test.com) { set $var_tz '1'; } if ($remote_addr ~* ^15.236.33.12$) { set $var_tz '1'; } if ($var_tz !~ '1') { return 403; } }
注:
1、此防盗链同样适合于图片视频音频等文件的处理。所以方法二中我由”location /” 换成了图片的处理。
2、如.abc.org,abc前面的点不能少,当时就因为少了一个点,害我搞了半天才找到原因。
三、分析
上面的两个nginx rewrite规则虽然效果一样,但还是有不小的差别的。方法1为公司写程序的同事所写,逻辑性太强了,看的人头晕。显然这个多条件判断会增加nginx的处理负担。方法2为我自己所写,看上去要清晰一些,不过也有缺点,因为是通过http_referer进行的判断。所以如果采集方通过伪造成符合上面规则的url去连接的话,就可以正常得到信息。