很多时候,服务不是被用户流量击垮,而是被大量的对你没有任何贡献的盗链击倒,所以作为一个web站点防盗链是首先要考虑的问题,目前来说,对于各个web服务器,简单的防盗链方法多数是做rewrite,判断referer是否有效,当然高端的伪造referer的情况不在这里讨论。

      在apache下,防盗链的方法有很多,你可以看看apache的日志,有多少是外部直接referer过来的,有可能比内部引用还多,尤其是图片和下载类站点更加明显。在apache下,最简单的防盗链使用类似这个形式:

SetEnvIfNoCase Referer "^http://www.google.com" local_ref=1
SetEnvIfNoCase Referer "^http://google.com" local_ref=1
<filesmatch "\.(txt|doc|mp3|zip|rar|jpg|gif)">
Order Allow,Deny
Allow from env=local_ref

或者在apache下使用RewriteEngine on,然后使用RewriteCond {HTTP_REFERER} 来定义,这些都是防止比较低级的盗链,如果是面对迅雷或者其他的话,这个远远不够,但是不是这里讨论的范围。

    对于nginx而言,本身也有简单的防盗链模块ngx_http_referer_module,配置比较简单,定义文件类型:

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {

      valid_referers none blocked server_names *.163.com 163.com baidu.com;
      if ($invalid_referer) {return 403;}
    expires      30d;
}


具体的可以参考这里:http://wiki.nginx.org//NginxHttpLimitZoneModule,同时还有一个第三的防盗链相关模块,ngx_http_accesskey_module:
location /download {
accesskey             on;
accesskey_hashmethod md5;
accesskey_arg         "key";
accesskey_signature   "mypass$remote_addr";
}


具体的使用方法:http://wiki.nginx.org//NginxHttpAccessKeyModule


    对于带宽限制,apache可以动态编译一些模块进去,mod_evasive20.so和mod_bw.so都是对防止简单的dos和带宽限制而存在的,而对于nginx,可以使用nginx的标准模块ngx_http_limit_zone_module,进行会话的并发连接数控制:
http {
    limit_zone   one $binary_remote_addr 10m;
#
定义一个叫“one”的记录区,总容量为 10M,以变量 $binary_remote_addr 作为会话的判断基准(即一个地址一个会话)


    ...
    server {
        ...
        location /icons_rar/ {
            limit_conn   one 2;
            limit_rate 2k;
        }


# 限制 /icons_rar/ 目录下:

limit_conn 一个会话只能进行两个连接。超过一个,则返回503。

imit_rate 来控制该目录的下载速度为2KB/S

# 如果限制当前server内域名下所有目录下载显示则写 /  如:


    server {
        ...
        location / {
            limit_conn   one 2;
            limit_rate 2k;
        }

之后用迅雷下载文件测试:



这是简单的nginx的方案,更高级的应用应该是在客户端类型或者根据日志分析后,针对具体问题做文章,例如对$http_user_agent的特殊内容进行匹配,然后返回503。

为什么要返回503?如果直接返回403,有可能被下载工具发现,403的状态被认为被禁止了,然后进行调整继续作案。而返回一个503,对服务器来说影响不大,只占用一个nginx的线程而已。

先说到这里,以后再继续补充。

 

web服务器 | 评论(0) | 引用(0) | 阅读(9596)