图片分享与防盗链

来源:互联网 发布:红色管弦乐 知乎 编辑:程序博客网 时间:2024/05/18 17:01

最近看有很多图片站都增加了百度图片分享,于是未能免俗也增加了这么个实际上没什么人用的功能。

自己手动测试了下,发现分享的时候会抓取跳转的防盗链图片。

查看了下日志,发现有这么一行内容:

1*.*.*.* - - [16/Dec/2012:09:31:50 +0800] "GET http://xxx.xxx.com/xx.jpg HTTP/1.1" 0 106 "-" "SinaWeiboBot"[]
2*.*.*.* - - [16/Dec/2012:09:31:50 +0800] "GET http://xxx.xxx.com/xx.jpg HTTP/1.1" 0 106 "-" "-"[]
3*.*.*.* - - [16/Dec/2012:09:31:50 +0800] "GET http://xxx.xxx.com/no.png HTTP/1.1" 200 1625 "-" "-"[]
原来新浪微博抓取图片的User-Agent头是SinaWeiboBot,而抓取图片是在后台进行,referer为空值——这点与搜索引擎是类似的。

问题就出在我防盗链白名单里是以引用页HTTP_REFERER来判断来访页面从而实现防盗链的——其实这也是最低级的方法。而众所周知的一旦引用页为空被加入白名单的话,很容易被破掉。

所以我尝试除了referer头之外增加对于User-Agent的判断,于是我在.htaccess里增加了如下内容

01//以下三条规则为判断常规浏览器user_agent头,目的是在常规浏览器访问的时候不被阻挡
02RewriteCond %{HTTP_USER_AGENT} !Mozilla(.*)
03RewriteCond %{HTTP_USER_AGENT} !Googlebot(.*)
04RewriteCond %{HTTP_USER_AGENT} !Opera(.*)
05//百度与谷歌搜索引擎的user_agent头通配符
06RewriteCond %{HTTP_USER_AGENT} !Baiduspider(.*)
07RewriteCond %{HTTP_USER_AGENT} !Baiduspider-image(.*)
08RewriteCond %{HTTP_USER_AGENT} !Googlebot-Image(.*)
09RewriteCond %{HTTP_USER_AGENT} !Sogou(.*)
10//新浪微博抓取图片的user_agent头
11RewriteCond %{HTTP_USER_AGENT} !SinaWeiboBot
12RewriteRule .*\.(gif|jpg|jpeg)$ /images/no.png [R=301,NC,L]

这里要解释下白名单里为什么没有googlebot,因为google蜘蛛的user_agent头中包含有Mozilla字样,符合第一条规则。

经过这样设置以后笔者发现问题的焦点“referer头为空”的问题依旧没有解决。

然后笔者尝试着合并规则,然而实际运行的时候RewriteCond的不同判定内容是不能顺序执行的。

比如前面半段判定RewriteCond %{HTTP_USER_AGENT}来判定访客信息,后面半段判定RewriteCond %{HTTP_REFERER}来判断引用来源,最后合并成一个重定向规则"RewriteRule .*\.(gif|jpg|jpeg)$ /images/no.png [R=301,NC,L]",这样的写法在.htaccess里是不行的,只有分成两条重定向规则才能识别——或者是前前判定不同header头的内容无效。

另一方面是验证请求头条数越多,执行速度越慢,大概一条是1%,超过15条以后就比较明显的感觉要慢上0.1~0.3秒的样子,同时既要兼顾搜索引擎又要兼顾访客的USER_AGENT头判定,个人以为规则写太宽了起不了作用,太细了又容易阻挡正常访客,很是伤神。

目前的问题是防盗链要求不能让空referer头访问正常附件(也就是直接跳转防盗链提示),然而微博抓取图片又是空referer抓取,笔者试图通过合并规则来实现这样要求的想法被否定了,暂时也没有找到其他更好的办法。如果有哪位大神看到这篇文章,烦请指教一二。

 ——————————————————————————————————————————————————

2012年12月18日更新:我突然想到了nginx规则里面可以通过if语句来先判断referer头再判断user_agent头实现我想要的功能。

01location ~* \.(gif|jpg|jpeg|png)$ {
02valid_referers blocked www.xxx.com;
03valid_user_agent SinaWeiboBot Googlebot(.*) Baiduspider(*);
04if($http_referer = ""){
05if($invalid_user_agent) {
06return301;
07}
08}
09else{if($invalid_referer) {
10return403;
11}
12}  
13}

以上代码纯属笔者捏造,大概思路是这么回事,具体能不能运行就不知道了,暂时也没时间测试。

0 0
原创粉丝点击