zhuce 发表于 2017-7-10 06:38:37

网站防刷方案

访问网站所涉及环节浏览器款控制方案CDN 与 反向代理网络设备控制方法服务器上做控制5.1. 操作系统部分提示5.2. WEB 服务器部分通过程序控制访问行为提示总结Mr. Neo Chen (netkiller), 陈景峰(BG7NYT)中国广东省深圳市龙华新区民治街道溪山美地518131+86 13113668890+86 755 29812080netkiller@msn.com版权 © 2011, 2012, 2013 http://netkiller.github.io摘要这是讲述如何防止重复请求你的网站, 包括如,爬虫,数据采集,刷排名,批量注册,批量发帖,利用漏洞获取网站数据等等。简单说就是重复相同的请求首先看看访问流程所设计的每个环节User -> Browse -> CDN/Proxy Cache -> Web Server -> App Server / fastcgi pool -> Cache -> Database大部分网站都是这样的结构:用户,浏览器,CDN或反向代理,Web服务器,应用服务器,缓存,数据库这个访问过程中所涉及的设备PC -> ADSL/Cable/Ethernet -> Route -> ... -> Route -> Firewall -> Load Balance -> Switch -> Server我们看看从那些环节可以截获用户的刷新行为可控制环节CDN / 反向代理,提供一些基本防护功能,过于简单。3/4层设备,防火墙/路由器/交换机,主要还是靠防火墙设备,例如Cisco ASA 系列防火墙,都提供IPS/IDS服务(需要单独采购,设备默认没有)主要是针对IP地址的请求频率做出策略控制,4/7 层负载均衡设备, 一半负载均衡设备都附带此功能。但不是他主要的功能,没有能力购买防火墙设备的中小公司可以使用该功能,7层功能非常强大,但都是通用功能,不一定满足你的个性化需求。浏览器,这是主要是改变浏览器端设置,利用Cookie变化,Javascript等技术,阻止重复请求WEB 服务器,在web上通过扩展模块与相应的配置也能达到一定的效果应用服务器, 主要是通过编写程序在阻止恶意访问。依次从上至下,越能提前在上一层阻止行为越好,否则就在下一层截获。2. 浏览器款控制方案通过 Javascript 防止重复点击提交按钮,通常的做法是将按钮禁用 通过 disabled 属性实现。下面是Jquery例子$("form").submit(function(){$(":submit",this).attr("disabled","disabled");});在上面的例子基础上可以改良,增加计时器,限制一定时间内不可重复提交。通过 Cookie技术控制重复访问动作访问第一个页面 login.example.com/form.ext 的时候设置一个 cookie 变量访问第二个页面 login.example.com/auth.ext 的时候判断上一个页面设置的 cookie 是否有效,如果无效拒绝访问。可以进一步增加难度,例如用户注册分为很多步骤,每一个步骤都会设置一个标记,如果用户行为不是安装顺序访问,直接在最后一个页面提交,明显可以判断是非法行为。这里的方案是针对人工操作,更多的时采用程序实现刷新,采集,爬虫等等。3. CDN 与 反向代理CDN 都提供一些基本的防护功能,主要是针对 IP 地址, URL 做一些限制如果自己做反向代理,控制权更大,可以充分使用操作系统带的包过滤防火墙与代理软件所提供的7层功能由于很多web server 具备代理服务器功能,配置也相差无几,所有在后面web server 会详细介绍。4. 网络设备控制方法每一个网络设备使用方法都不同,这里无法举例,但原理都是相同的。3/4 层网络设备可以按照IP地址与端口号访问情况做具体限制,如单位时间内允许的访问次数,这种对于大量的攻击比较有效7层网络设备功能非常强大,就可以根据HTTP头做规则策略,如限制URL的单位时间访问的IP数量,判断 Cookie 等信息,5. 服务器上做控制这部分分为,操作系统与web服务器两个部分5.1. 操作系统部分操作系统部分,主要是通过linux内核提供的包过滤功能,通常所说的iptablesiptables -A INPUT -p icmp -m limit --limit 3/s -j LOG --log-level INFO --log-prefix "ICMP packet IN: "iptables -N syn-floodiptables -A INPUT -p tcp --syn -j syn-floodiptables -I syn-flood -p tcp -m limit --limit 3/s --limit-burst 6 -j RETURNiptables -A syn-flood -j REJECT限制源IP的访问数量-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -m connlimit --connlimit-above 50 --connlimit-mask 32 -j REJECT --reject-with icmp-port-unreachable-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 --tcp-flags FIN,SYN,RST,ACK SYN -m connlimit --connlimit-above 50 --connlimit-mask 32 -j REJECT --reject-with icmp-port-unreachable关键字,字符串过略iptables -A INPUT -p tcp --dport 80 -m string --algo bm --string "XXDD0S" -j DROP以上所讲都是被动方法,需要系统管理一条一条添加规则。提示基于IP与端口的方法有明显的不足,经常会误将某些正常的IP地址封锁。下面通过脚本实现主动防御,通过提取 access.log 文件定位更精准,同时实现了黑/白名单可以将安全IP放置在白名单中。#!/bin/bash######################################### Homepage: http://netkiller.github.io# Author: neo ########################################PIPE=/tmp/pipepidfile=/tmp/firewall.pidACCCESS_LOG=/tmp/access.logTIMEPOINT='24/May/2012'BLACKLIST=/var/tmp/black.lstWHITELIST=/var/tmp/white.lst########################################if [ -z "$( egrep "CentOS|Redhat" /etc/issue)" ]; thenecho 'Only for Redhat or CentOS'exitfiif [ ! -f ${BLACKLIST} ]; thentouch ${BLACKLIST}fiif [ ! -f ${WHITELIST} ]; thentouch ${WHITELIST}fifor deny in $(grep ${TIMEPOINT} ${ACCCESS_LOG} | awk '{print $1}' | awk -F'.' '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -r -n | head -n 30| awk '{print $2}')doif [ $(grep -c $deny ${WHITELIST}) -ne 0 ]; thenecho 'Allow IP:' $denyiptables -D INPUT -p tcp --dport 443 -s $deny -j DROPiptables -D INPUT -p tcp --dport 80 -s $deny -j DROPcontinuefiif [ $(grep -c $deny ${BLACKLIST}) -eq 0 ] ; thenecho 'Deny IP:' $denyecho $deny >> ${BLACKLIST}iptables -I INPUT -p tcp --dport 443 -s $deny -j DROPiptables -I INPUT -p tcp --dport 80 -s $deny -j DROPfidone相比前面脚本,这个脚本更高级,实现关键字过滤,管道实时处理,这样不回因为日志尺寸变大,影响到脚本的处理性能。#!/bin/bash######################################### Homepage: http://netkiller.github.io# Author: neo ########################################ACCESSLOG=/www/logs/www.example.com/access.$(date +'%Y-%m-%d').logTIMEPOINT='24/May/2012'KEYWORD=send.phpBLACKLIST=/var/tmp/black.lstWHITELIST=/var/tmp/white.lstPIPE=/var/tmp/pipepidfile=/var/tmp/firewall.pidlogfile=/var/tmp/firewall.log########################################if [ -z "$( egrep "CentOS|Redhat" /etc/issue)" ]; thenecho 'Only for Redhat or CentOS'exitfiif [ -z $1 ]; thenecho "$0 clear|fw|collect|process|close"fiif [ "$1" == "clear" ]; thenrm -rf $BLACKLISTrm -rf $PIPEecho "Clear OK!!!"fiif [ "$1" == "close" ]; thenkillall tailkill `cat $pidfile`echo > $pidfilefiif [ ! -e $PIPE ]; thenmkfifo $PIPEfiif [ "$1" == 'fw' ]; theniptables -A OUTPUT -p tcp --dport 2049 -j REJECTiptables -A OUTPUT -p tcp -m multiport --dports 22,21 -j REJECTfor ipaddr in ${WHITELIST}doif [ $(grep -c $ipaddr ${WHITELIST}) -ne 0 ]; theniptables -A INPUT -p tcp --dport 443 -s $ipaddr -j ACCEPTiptables -A INPUT -p tcp --dport 80 -s $ipaddr -j ACCEPTecho 'Allow IP:' $ipaddr >> $logfilefiif [ $(grep -c $ipaddr ${BLACKLIST}) -eq 0 ] ; theniptables -D INPUT -p tcp --dport 443 -s $ipaddr -j DROPiptables -D INPUT -p tcp --dport 80 -s $ipaddr -j DROPecho 'Deny IP:' $ipaddrfidonefiif [ "$1" == "collect" ]; thenkillall tailfor (( ; ; ))dotail -f $ACCESSLOG | grep $KEYWORD | cut -d ' ' -f1 > $PIPEdone &echo $! > $pidfilefiif [ "$1" == "process" ]; thenif [ ! -f $BLACKLIST ]; thentouch $BLACKLISTfiif [ ! -f ${WHITELIST} ]; thentouch ${WHITELIST}fifor (( ; ; ))dowhile read ipaddrdoif [ $(grep -c $ipaddr ${WHITELIST}) -ne 0 ]; thenecho 'Allow IP:' $ipaddr >> $logfilecontinuefigrep $ipaddr ${BLACKLIST}if [ $? -eq 1 ] ; thenecho $ipaddr >> ${BLACKLIST}iptables -I INPUT -p tcp --dport 80 -s $ipaddr -j DROPecho "Deny IP: $ipaddr" >> $logfilefidone < $PIPEdone &echo $! >> $pidfilefi5.2. WEB 服务器部分下面所讲技术,适用于反向代理,负载均衡,web服务器Web 服务器也可以实现前面所说的防火墙等设备3/4层的功能,同时具备七层功能,很多负载均衡设备7层采用web服务器实现,例如 F5 7层的高级功能是由 Apache httpd 来完成(apache 是经过二次开发的), 所以7层的部门我们主要在这里深入讨论如果你有防火墙设备应该首先考虑在防火墙端做控制,如果没有防火墙那麽就考虑在负载均衡设备中做控制,这些设备你都没有,最后考虑在反向代理中处理,最后考虑web服务器。限制IP地址在这里可以做到更细腻的控制,例如实现某个目录的,某URL的IP访问策略。请自行查找手册或参考《Netkiller Web 手札》HTTP 协议头我们要做以下几种限制限制 http_referer, 常说的防盗链。限制 http_user_agent, 主要是防爬虫限制 request_method, 不是所有页面都允许 POST限制 http_cookie, 没有携带正确的 cookie 不允许访问上面7层访问控制还是比较粗糙的,主要是给应用程序减压,更细腻的控制需要通过程序手段,实现更智能判断。 不过同上上面的层层限制,已经足矣改善你的状况,如果还是无效继续往下看。valid_referers none blocked *.example.com example.com;if ($invalid_referer) {#rewrite ^(.*)$http://www.example.com/cn/$1;return 403;}if ($http_user_agent = "") { return 403; }通过程序控制访问行为设计应用防火墙,将所有资源纳入管理范围IP地址,上面已经反复强调怎样封锁IP地址,但都过于粗糙,很多时候是一刀切。在程序中实现禁止IP访问,更灵活我们要做以下几种限制单位时间内访问次数访问时间间隔设置封锁时间设置黑白名单验证码,最常用的,最有效的方法,分为图片扭曲法,问提/答案 法,手机验证码,语音验证码等等方法,形式多重多样http_referer, 虽然上面已经做了 http_referer 限制,但是web 服务器只能做粗糙限制,允许 *.example.com 域进行访问,但我需要更精确的控制。例如:www.example.com (此时 http_referer 为空,或者其他,这不重要) -> login.example.com (http_referer: www.example.com)-> login.example.com/auth.ext (http_referer: login.example.com) -> login.example.com/secussed.ext (http_referer: login.example.com/auth.ext)看明白了吗 http_referer 每次都是上一个页面,我们程序中判断,如果上一个页面不是我们所指定的,或者不再允许列表内,就拒绝访问request_methodwww.example.com (GET) -> login.example.com (GET)-> login.example.com/auth.ext (POST) -> login.example.com/secussed.ext (GET)同理,在不允许的页面POST操作,将立即拒绝http_cookiewww.example.com (cookie 1) -> login.example.com (cookie 2)-> login.example.com/auth.ext (cookie 3) -> login.example.com/secussed.ext (cookie 4)没有按照指定流程访问,cookie 值不会变化,属于异常行为cookie + redis 间隔时间提示上面所有的操作都将计入日志,通过脚本可以将异常访问行文达到一定次数后,放入iptables DROP链中。7. 总结上面提方法单一使用过于简单,需要组合使用,同时经常调整组合方式才能更有效阻止各种良性与恶性网站访问行为。
页: [1]
查看完整版本: 网站防刷方案