OpenResty(nginx扩展)实现防cc攻击

防cc攻击,推荐使用HttpGuard

 

本文介绍使用openresty来实现防cc攻击的功能。openresty官网http://openresty.org/cn/index.html。下面是防cc攻击的流程图。
根据流程图,我们知道防cc攻击主要包括两部分,一是限制请求速度,二是给用户发送js跳转代码进行验证请求是否合法。
Nginx

一、安装依赖

centos:

  1. yum install readline-devel pcre-devel openssl-devel

ubuntu:

  1. apt-get install libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl

二、luajit安装

  1. cd /tmp/
  2. git clone http://luajit.org/git/luajit-2.0.git
  3. cd luajit-2.0/
  4. make && make install
  5. ln -sf luajit-2.0.0-beta10 /usr/local/bin/luajit
  6. ln -sf /usr/local/lib/libluajit-5.1.so.2 /usr/lib/

三、openresty安装

  1. cd /tmp
  2. wget http://agentzh.org/misc/nginx/ngx_openresty-1.2.4.13.tar.gz
  3. tar xzf ngx_openresty-1.2.4.13.tar.gz
  4. cd ngx_openresty-1.2.4.13/
  5. ./configure –prefix=/usr/local/openresty –with-luajit
  6. make && make install

四、nginx配置

nginx.conf:

  1. http{
  2. [……]
  3. lua_shared_dict limit 10m;
  4. lua_shared_dict jsjump 10m;
  5.  
  6. <pre><code>server {
  7.     #lua_code_cache off;
  8.     listen       80;
  9.     server_name  devops.webres.wang;
  10.  
  11.     location / {
  12.         default_type  text/html;
  13.         content_by_lua_file "/usr/local/openresty/nginx/conf/lua";
  14.     }
  15.     location @cc {
  16.         internal;
  17.         root   html;
  18.         index  index.html index.htm;
  19.     }
  20. }
  21. </code></pre>
  22.  
  23. }

/usr/local/openresty/nginx/conf/lua文件:

  1. local ip = ngx.var.binary_remote_addr
  2. local limit = ngx.shared.limit
  3. local req,_=limit:get(ip)
  4. if req then
  5.         if req > 20 then
  6.                 ngx.exit(503)
  7.         else
  8.                 limit:incr(ip,1)
  9.         end
  10. else
  11.         limit:set(ip,1,10)
  12. end
  13.  
  14. local jsjump = ngx.shared.jsjump
  15. local uri = ngx.var.request_uri
  16. local jspara,flags=jsjump:get(ip)
  17. local args = ngx.req.get_uri_args()
  18. if jspara then
  19.     if flags then
  20.         ngx.exec("@cc")
  21.     else
  22.                 local p_jskey=”
  23.                 if args["jskey"] and type(args["jskey"])==’table’ then
  24.                          p_jskey=args["jskey"][table.getn(args["jskey"])]
  25.                 else
  26.                          p_jskey=args["jskey"]
  27.                 end
  28.         if p_jskey and p_jskey==tostring(jspara) then
  29.                         jsjump:set(ip,jspara,3600,1)
  30.                         ngx.exec("@cc")
  31.         else
  32.                         local url=”
  33.                         if ngx.var.args then
  34.                                 url=ngx.var.scheme.."://"..ngx.var.host..uri.."&amp;jskey="..jspara
  35.                         else
  36.                                 url=ngx.var.scheme.."://"..ngx.var.host..uri.."?jskey="..jspara
  37.                         end
  38.                         local jscode="<script>window.location.href=’"..url.."’;</script>"
  39.                         ngx.say(jscode)
  40.         end
  41.     end
  42. else
  43.     math.randomseed( os.time() );
  44.     local random=math.random(100000,999999)
  45.     jsjump:set(ip,random,60)
  46.     local url=”
  47.     if ngx.var.args then
  48.         url=ngx.var.scheme.."://"..ngx.var.host..uri.."&amp;jskey="..random
  49.     else
  50.         url=ngx.var.scheme.."://"..ngx.var.host..uri.."?jskey="..random
  51.     end
  52.     local jscode="<script>window.location.href=’"..url.."’;</script>"
  53.     ngx.say(jscode)
  54. end

lua代码部分解释:
1、1-12行是限速功能实现,第5和第10行表示10秒钟内容最多只能请求20次。
2、14-48行是验证部分,24行中的3600表示验证通过后,白名单时间为3600秒,即1小时。

update: 2013.5.26
1、修复JS无限跳转bug
2、增加随机种子

virtualbox host-only网络设置

  • 1、打开virtualbox,设置虚拟机的网络连接方式为host-only。
  • 2、在宿主机器的网卡上,如本地连接,右键属性,切换到共享,勾选允许共享网络,这样虚拟机才能可能连接互联网,这时VirtualBox Host-Only Network虚拟网卡ip会设置为192.168.137.1。
  • 3、开启虚拟机,设置虚拟机的网络的ip为192.168.137.x,子掩码255.255.255.0,网关192.168.137.1。
  • 经过以上三步的设置,宿主机可以连接虚拟机,虚拟机也可以上网了。

    防止端口扫描shell脚本

    网上有现在的防端口工具,如psad、portsentry,但觉得配置有点麻烦,且服务器不想再装一个额外的软件。所以自己就写了个shell脚本实现这个功能。基本思路是:使用iptables的recent模块记录下在60秒钟内扫描超过10个端口的IP,并结合inotify-tools工具实时监控iptables的日志,一旦iptables日志文件有写入新的ip记录,则使用iptables封锁源ip,起到了防止端口扫描的功能。 继续阅读防止端口扫描shell脚本

    远程密令临时开启ssh端口

    linux服务器,我们一般是通过ssh通道远程管理,这就需要我们开启ssh端口,如22。但开启端口有被暴力破解的风险,你会说可以设置复杂的密码或使用证书避免。就算破解不了密码,但openssh也可能会有漏洞,你会说可以更改ssh端口,但还是有可能被扫描出来。还有一种选择,我们可以只允许指定IP访问ssh,通过vpn登录管理服务器,但局限很明显,万一紧急情况vpn登录不上去了怎么办。下面给出一种个人觉得比较满意的解决方案,即使用iptables的recent模块,通过密令临时开启ssh端口。当然,密令需要保管好,防止外泄。
    1、iptables规则设定

    1. #指定78字节的icmp数据包(包含IP头部20字节,ICMP头部8字节)通过被加入sshopen列表。
    2. iptables -A INPUT -p icmp –icmp-type 8 -m length –length 78 -m recent –set –name sshopen –rsource -j ACCEPT
    3. #检查sshopen列表是否存在你的来源IP,如果存在,即从第一次使用密令开始15秒钟内开启ssh端口22,超过15秒端口自动关闭,不再允许新连接,已连接的不会断开。
    4. iptables -A INPUT -p tcp –dport 22 –syn -m recent –rcheck –seconds 15 –name sshopen –rsource -j ACCEPT

    2、临时开启ssh端口密令

    1. linux下:ping -s 50 host
    2. windows下:ping -l 50 host

    3、我目前使用的iptables规则

    1. -A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
    2. -A INPUT -p tcp -m tcp –dport 80 -j ACCEPT
    3. -A INPUT -p tcp -m tcp –dport 443 -j ACCEPT
    4. -A INPUT -p tcp -m tcp –dport 123 -j ACCEPT
    5. -A INPUT -p icmp -m icmp –icmp-type 8 -m length –length 50 -m recent –set –name sshopen –rsource -j ACCEPT
    6. -A INPUT -p tcp -m tcp –dport 22 –syn -m recent –rcheck –seconds 15 –name sshopen –rsource -j ACCEPT
    7. -A INPUT -i lo -j ACCEPT
    8. -A INPUT -p icmp -m icmp –icmp-type 8 -j ACCEPT
    9. -A INPUT -p icmp -m icmp –icmp-type 11 -j ACCEPT
    10. -A OUTPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
    11. -A OUTPUT -o lo -j ACCEPT
    12. -A OUTPUT -p tcp -m tcp –dport 80 -j ACCEPT
    13. -A OUTPUT -p tcp -m tcp –dport 443  -j ACCEPT
    14. -A OUTPUT -p icmp -m icmp –icmp-type 8 -j ACCEPT
    15. -A OUTPUT -p icmp -m icmp –icmp-type 11 -j ACCEPT

    参考:http://blog.onovps.com/archives/iptables-recent.html

    tar增量备份

    现在我们来展示一个使用tar工具来增量备份的例子。

    一、增量备份

    1、新建backup目录,里面新建file1,file2,file3文件

    1. mkdir backup/
    2. touch backup/{file1,file2,file3}

    2、进行完整备份

    1. tar -g tarinfo -czf backup-full.tar.gz backup/

    3、新增文件到backup

    1. touch backup/file4

    4、进行增量备份

    1. tar -g tarinfo -czf backup-incre1.tar.gz backup/

    5、查看增量备份文件

    1. tar -ztf backup-incre1.tar.gz

    二、进行还原

    1、删除backup目录

    1. rm -rf backup/

    2、执行还原操作

    1. tar xzf backup-full.tar.gz
    2. tar xzf backup-incre1.tar.gz

    现在已经完成tar的还原操作。其它tar的增量备份只需要指定-g参数,tarinfo文件则是用来记录备份的一些信息。