我们在日常维护的web服务中经常会有防盗链的需求,毕竟谁家的流量都是花钱买来的。免费被别的网站盗用肯定是不爽的。这时候Nginx的referer模块就可以解决一些简单有效的防盗链问题。

场景:当其他网站通过爬虫或其他方式获得了我们的url,并放到了他的页面中。当用户在他们的网站点击这个URL的时候,浏览器会做一件事,会在这个http请求中添加一个http头部:referer,再通过referer头部,将他们网站的当前url带上,以告知服务器(我们的服务器)本次请求是由哪个页面发起的。
目的:把我们不希望的一些请求拒绝掉(防盗链)。
思路主要是在referer模块中提供了一个新的变量(invalid_referer),这个变量可以根据配置判断referer头部是否合法。然后根据结果来修改
referer模块默认是编译进Nginx的。
相关指令:
Syntax: valid_referers none | blocked | server_names | string ...;
Default: —
Context: server, location
Syntax: referer_hash_bucket_size size;
Default: referer_hash_bucket_size 64;
Context: server, location
Syntax: referer_hash_max_size size;
Default: referer_hash_max_size 2048;
Context: server, location
可以看到valid_referers 指令只能出现在server, location上下文中,不能出现在http下。它的可选值有:none | blocked | server_names | string
而这些值为了加速访问也放到了hash表中。
然后就有了referer_hash_bucket_size 和 referer_hash_max_size来控制hash表的大小。
我们再来看下valid_referers指令:

他可以同时携带多个参数,表示多个referer头部都生效。允许这些请求继续访问。
none: 如果没有referer头的请求也允许访问。
block:允许有referer头部,但referer没有值的请求访问。这可能是因为经过了反向代理的问题。
server_names: 如果referer的域名和我们server_name中的域名匹配。
使用referer模块可以做一些简单的防盗链,因为请求头中的referer可以被修改掉。但是对于大部分的盗链网站都是有效的。