Nginx 配置防盗链功能
2013-05-19 by dongnan
开始之前
什么是referer请求头?
referer
请求头包含当前请求页面的来源地址,即表示当前页面是通过这个来源页面里的链接进入的。
服务端一般使用referer
请求头识别访问来源
,可能会以此进行统计分析、日志记录以及缓存优化等。
利用referer防止盗链?
假设当一个 HTTP
请求头的 referer
字段中包含一些不正确(期望)的值。那么可以使用 nginx 的 ngx_http_referer_module
模块,禁止这个请求访问站点。
也就是常说的 nginx 防盗链,不过需要注意的是,referer 请求头是可以伪造的,因此这个模块并不能 100%
的阻止这类请求。
防盗链功能主要由模块中的 valid_referers
指令与 $invalid_referer
变量配合使用,例如下面的配置,允许符合以下规则的请求访问站点。
- 没有
referer
,直接在浏览器打开这个URI。 - 带有
referer
,但是被修改过值不是以http(s)://
开头的字符串。 - 带有
referer
, 值是以http(s)://
开头的字符串,并且匹配valid_referers
列表中的值。
操作步骤
nginx
配置文件:
cat /etc/nginx/conf.d/default.conf
server {
#..其它配置项目省略
# 上传图片目录
location ^~ /attachments {
alias /data/uploads/;
expires 180d;
valid_referers none blocked
*.demo.com demo.com
~\.demo\.;
if ($invalid_referer) {
return 403;
}
}
}
重启nginx服务:
nginx -t && nginx reload
验证
- 请求1,没有带
referer
信息,相当于直接在浏览器打开这个URI,匹配参数None
。 - 请求2,虽然有带
referer
信息,但值不是以http(s)://
开头的字符串,匹配参数blocked
。 - 请求3,带有正确主机名
referer
信息,匹配参数server_names
,这也是浏览器中正常请求。 - 请求4,带有域外的主机名
referer
信息,"表示这个请求是从百度页面里的链接进入的",按照规则$invalid_referer
变量被设置为1
,最终服务器返回403
状态码,完成防盗链。
valid_referers
语法: valid_referers none|blocked|server_names string ...;
默认值: no
使用字段: server, location
功能: 此指令在 referer头的基础上为 $invalid_referer 变量赋值,可以实现简单的防盗链功能。
如果 valid_referers列表中没有匹配Referer请求头,$invalid_referer将被设置为1,否则为0(或空值)。
参数:
none
,请求头中不存在Referer
字段(空值,如直接在浏览器打开图片URI
)。blocked
,请求头中存在Referer
字段,但值不是"http(s)://
开头的字符串(被代理服务器修改删除)。server_names
,Referer字段包含服务器名称。arbitrary string
,定义服务器名称和可选URI
前缀,服务器名称的开头或结尾可以有一个*
。regular expression
,使用正则匹配,第一个符号为~
。
示例:
valid_referers none blocked server_names
*.example.com example.* www.example.org/galleries/
~\.google\.;
if ($invalid_referer) {
return 403;
}
小结
最后来总结下文章中的知识点:
referer
请求头,用于识别访问来源。referer
请求头可以伪造,不能做为唯一的判断条件。- 借助
ngx_http_referer_module
模块,实现简单的nginx
防盗链。
参考
- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Referer
- http://nginx.org/en/docs/http/ngx_http_referer_module.html