前言:
之前在整理nginx资料的时候, 里面谈到过防盗链的配置. 当时觉得有些新鲜(还是自己孤陋寡闻了), 毕竟很少接触这个概念或者说是名词. 大致的意思时, 防止他人的网站引用你的图片, 进而消耗你网络带宽资源的一种措施.
本文将讲述防盗链的原理, nginx如何配置防盗链, 以及如何反防盗链的一些思路. 笔者这是简单谈谈, 权当抛砖引玉.
科普:
他人网站未经你的允许, 引用你网站的资源链接(图片/文档). 不仅消耗你服务器的网络带宽, 甚至侵害你的利益, 间接盗取你的网站流量, 所以危害很大.
微信公众号, 新浪博客等图片, 都开启防盗链功能. 比如在他人站点引用了他们的图片, 则图片的展示效果如下所示:
防盗链的原理:
在http协议中, 一般的浏览器访问页面, 除了浏览器地址栏直接输入, 其他链接点击/资源引用, 都会在后续的http请求头中附带Referer字段, 它表征了来自哪个具体的源网页链接.
依据上述的事实, 很多服务器会根据Referer字段来简单判断源链接是否是自己的, 还是他人的可疑盗链链接.
• 举个简单例子:
比如网站A(域名:www.a.com), 其下页面内容引用网站B(域名:www.b.com)的图片资源.
当用户通过访问A页面(引用B的图片), 浏览器会自动发起图片请求(注入Referer: www.b.com/xxx Http头信息). 则网站B服务器就收到图片请求, 服务器可以依据Referer字段, 发现该源链接为www.a.com, 而不是自身的www.b.com, 因此可判断为盗链, 最后拒绝访问.
微信公众号貌似就是基于此来防盗图的.
nginx配置防盗链:
nginx是借用ngx_http_referer_module来阻挡来源非法的域名请求的, 其配置规则如下:
valid_referers none | blocked | server_names | string ...;
none: 表示referer字段为空
blocked: 表示不以http://或者https://开头的源链接
server_names: 当前location配置的server域名
具体的一个案例配置如下所示:
location ~* .(gif|jpg|png|bmp)$ { valid_referers none blocked *.your-website.com server_names ~.google. ~.baidu.; if ($invalid_referer) { return 403; #rewrite ^/ http://www.your-website.com/xxx/403.jpg; } } location = /xxx/403.jpg { // 防止循环重定向 }
注: 很多合法请求可能没有设置referer, 本着宁可放过一千, 不可错杀一个的博爱精神, 还是应该放开限制, 不过也留下了做手脚的空间.
具体参考文章: nginx图片防盗链(referer指令).
反防盗链思路:
再知道了防盗链的原理后, 反防盗链的思路基本上也清晰很多.
一种简单易行的方法就是, 就是修改http请求中的referer字段. 然而浏览器很正直, 它不会帮我们欺骗. 因此这条路暂时搁置一下.
回到最初, 既然绕不过, 那就只能抓取原始图片, 正真成为盗图者了(不再盗链接, 直接复制图).
• 同步图片资源
同步下载图片资源于自己的服务器中, 再替换自己的图片链接. 这样也是无奈之举, 等于投降了^_^.
图片资源的存储也有两种方式, 一种存于本地, 另一种则存于云存储服务中.
可参见之前写的博客文章: springmvc学习笔记--支持文件上传.
• 代理模式
把自己的服务器当做代理服务器, 图片请求先经过自己服务器, 修改referer头, 再中转到真正的服务器地址,进行流复制.
注: 基于字节流进行传输, 代理服务器做了修改referer, 欺骗后一级服务器.
原本的链接:
<img src="http://www.b.com/xxx/yyy.jpg" />
皆改为如下的格式: http://www.a.com/zzz?source_url=${source_url}
<img src="http://www.a.com/zzz?source_url="http://www.b.com/xxx/yyy.jpg" />
这样他人服务器的防盗链限制就被绕过了, 同时本地服务器又不需要去存储这些资源文件.
这种代理模式, 对图片等小资源友好, 对特大资源(超过10M)并不推荐如此做.
总结:
互联网的攻与防很多, 魔高一尺, 道高一丈, 希望这世界变得美好.
公众号&游戏站点:
个人微信公众号: 木目的H5游戏世界
个人游戏作品集站点(尚在建设中...): www.mmxfgame.com, 也可直接ip访问: http://120.26.221.54/.