一、背景与需求

最近通过分析nginx日志,发现有很多站点会到公司站点上采集行情信息。想通过nginx rewrite处理所有的盗链。具体要求如下:

1、对于白名单中的域名允许其调用行情信息;
2、对于白名单中的IP允许其调用行情信息。

说白了上面就是一个逻辑或的语句,只要满足上面的任一条件即可通过。不过,因为nginx rewrite的要求比较严格——不支持if嵌套、or 和and 等操作。所以处理起来比较麻烦。不过最后试来试去,总算工夫不负有心人,成功完成了要求。

调试这个nginx rewrite 正则是我和另外一个同事一块儿处理的,而我们写出来的最终内容虽然不同,但效果确实一样的。在些两个正则都提供一下吧。

二、方法

方法一:

 1location / {
 2proxy_pass http://127.0.0.1:8080;   //后端tomcat
 3valid_referers none blocked  *.abc.com *.abc.cc *.xyz.cc *.test.org ;
 4set $ok Y;
 5set $ref N;
 6if ($invalid_referer) {
 7        set $ok N;
 8}
 9if ($remote_addr ~* ^123.23.1.11$) {
10        set $ok "${ok}Y";
11}
12}
13if ($remote_addr ~* ^25.11.33.60$) {
14        set $ok "${ok}Y";
15}
16if ($ok = N) {
17        return 404;
18}
19if ($ok = NY) {
20        set $ok Y;
21}
22if ($ok = YY) {
23        set $ok YY;
24        set $ref Y;
25}
26if ($http_referer = '') {
27        set $ok "${ok}${ref}";
28}
29if ($ok = YYY) {
30        set $ok Y;
31}
32if ($ok = YY) {
33        set $ok Y;
34}
35if ($ok != Y) {
36        return 404;
37}

注:1、上面写到的IP和域名是允许访问的白名单,以免泄露公司信息,在此我随便写的两个IP和几个域名。如有雷同,纯属巧合。2、上面关于IP的部分,可能过|这个nginx 逻辑或符号写到一块。具体可以参看nginx的正则。下面的例子中也会提到。

方法二:

 1location ~* .(gif|jpg|png)$ {
 2    if ($http_referer ~* (.*?).abc.org|(.*?).test.com) {
 3        set $var_tz '1';
 4    }
 5    if ($remote_addr ~* ^15.236.33.12$)
 6    {
 7        set $var_tz '1';
 8    }
 9    if ($var_tz !~ '1')
10    {
11        return 403;
12    }
13}

注:1、此防盗链同样适合于图片视频音频等文件的处理。所以方法二中我由”location /” 换成了图片的处理。2、如.abc.org,abc前面的点不能少,当时就因为少了一个点,害我搞了半天才找到原因。

三、分析

上面的两个nginx rewrite规则虽然效果一样,但还是有不小的差别的。方法1为公司写程序的同事所写,逻辑性太强了,看的人头晕。显然这个多条件判断会增加nginx的处理负担。方法2为我自己所写,看上去要清晰一些,不过也有缺点,因为是通过http_referer进行的判断。所以如果采集方通过伪造成符合上面规则的url去连接的话,就可以正常得到信息。