网站防刷方案

本文涉及的产品
网络型负载均衡 NLB,每月750个小时 15LCU
云防火墙,500元 1000GB
应用型负载均衡 ALB,每月750个小时 15LCU
简介: 目录[-]网站防刷方案网站重复请求解决方案Mr. Neo Chen (netkiller), 陈景峰(BG7NYT)1. 访问网站所涉及环节2. 浏览器款控制方案3. CDN 与 反向代理4. 网络设备控制方法5. 服务器上做控制5.1. 操作系统部分提示5.2. WEB 服务器部分6. 通过程序控制访问行为提示7. 总结网站防刷方案 摘要 这是讲述如何防止重复请求你的网站, 包括如,爬虫,数据采集,刷排名,批量注册,批量发帖,利用漏洞获取网站数据等等。

网站防刷方案

摘要

这是讲述如何防止重复请求你的网站, 包括如,爬虫,数据采集,刷排名,批量注册,批量发帖,利用漏洞获取网站数据等等。

1. 访问网站所涉及环节

简单说就是重复相同的请求

首先看看访问流程所设计的每个环节

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

我们看看从那些环节可以截获用户的刷新行为

可控制环节

  1. CDN / 反向代理,提供一些基本防护功能,过于简单。

  2. 3/4层设备,防火墙/路由器/交换机,主要还是靠防火墙设备,例如Cisco ASA 系列防火墙,都提供IPS/IDS服务(需要单独采购,设备默认没有)主要是针对IP地址的请求频率做出策略控制,

  3. 4/7 层负载均衡设备, 一半负载均衡设备都附带此功能。但不是他主要的功能,没有能力购买防火墙设备的中小公司可以使用该功能,7层功能非常强大,但都是通用功能,不一定满足你的个性化需求。

  4. 浏览器,这是主要是改变浏览器端设置,利用Cookie变化,Javascript等技术,阻止重复请求

  5. WEB 服务器,在web上通过扩展模块与相应的配置也能达到一定的效果

  6. 应用服务器, 主要是通过编写程序在阻止恶意访问。

依次从上至下,越能提前在上一层阻止行为越好,否则就在下一层截获。

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内核提供的包过滤功能,通常所说的iptables

iptables -A INPUT -p icmp -m limit --limit 3/s -j LOG --log-level INFO --log-prefix "ICMP packet IN: "

iptables -N syn-flood
iptables -A INPUT -p tcp --syn -j syn-flood
iptables -I syn-flood -p tcp -m limit --limit 3/s --limit-burst 6 -j RETURN
iptables -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/pipe
pidfile=/tmp/firewall.pid

ACCCESS_LOG=/tmp/access.log
TIMEPOINT='24/May/2012'
BLACKLIST=/var/tmp/black.lst
WHITELIST=/var/tmp/white.lst
########################################

if [ -z "$( egrep "CentOS|Redhat" /etc/issue)" ]; then
	echo 'Only for Redhat or CentOS'
	exit
fi

if [ ! -f ${BLACKLIST} ]; then
    touch ${BLACKLIST}
fi

if [ ! -f ${WHITELIST} ]; then
    touch ${WHITELIST}
fi

for 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}')
do

    if [ $(grep -c $deny ${WHITELIST}) -ne 0 ]; then
        echo 'Allow IP:' $deny
	iptables -D INPUT -p tcp --dport 443 -s $deny -j DROP
	iptables -D INPUT -p tcp --dport 80 -s $deny -j DROP
	continue
    fi

    if [ $(grep -c $deny ${BLACKLIST}) -eq 0 ] ; then

	echo 'Deny IP:' $deny
        echo $deny >> ${BLACKLIST}
        iptables -I INPUT -p tcp --dport 443 -s $deny -j DROP
        iptables -I INPUT -p tcp --dport 80 -s $deny -j DROP
    fi
done

相比前面脚本,这个脚本更高级,实现关键字过滤,管道实时处理,这样不回因为日志尺寸变大,影响到脚本的处理性能。

#!/bin/bash
########################################
# Homepage: http://netkiller.github.io
# Author: neo 
########################################
ACCESSLOG=/www/logs/www.example.com/access.$(date +'%Y-%m-%d').log
TIMEPOINT='24/May/2012'
KEYWORD=send.php
BLACKLIST=/var/tmp/black.lst
WHITELIST=/var/tmp/white.lst
PIPE=/var/tmp/pipe
pidfile=/var/tmp/firewall.pid
logfile=/var/tmp/firewall.log
########################################
if [ -z "$( egrep "CentOS|Redhat" /etc/issue)" ]; then
	echo 'Only for Redhat or CentOS'
	exit
fi

if [ -z $1 ]; then
    echo "$0 clear|fw|collect|process|close"
fi

if [ "$1" == "clear" ]; then
    rm -rf $BLACKLIST
    rm -rf $PIPE
    echo "Clear OK!!!"
fi

if [ "$1" == "close" ]; then
	killall tail
    kill `cat $pidfile`
    echo > $pidfile
fi

if [ ! -e $PIPE ]; then
    mkfifo $PIPE
fi

if [ "$1" == 'fw' ]; then
    iptables -A OUTPUT -p tcp --dport 2049 -j REJECT
    iptables -A OUTPUT -p tcp -m multiport --dports 22,21 -j REJECT

	for ipaddr in ${WHITELIST}
	do
		if [ $(grep -c $ipaddr ${WHITELIST}) -ne 0 ]; then
			iptables -A INPUT -p tcp --dport 443 -s $ipaddr -j ACCEPT
			iptables -A INPUT -p tcp --dport 80 -s $ipaddr -j ACCEPT
			echo 'Allow IP:' $ipaddr >> $logfile
		fi
		if [ $(grep -c $ipaddr ${BLACKLIST}) -eq 0 ] ; then
			iptables -D INPUT -p tcp --dport 443 -s $ipaddr -j DROP
			iptables -D INPUT -p tcp --dport 80 -s $ipaddr -j DROP
			echo 'Deny IP:' $ipaddr

		fi
	done

fi

if [ "$1" == "collect" ]; then
    killall tail
    for (( ; ; ))
    do
        tail -f $ACCESSLOG | grep $KEYWORD | cut -d ' ' -f1 > $PIPE
    done &
    echo $! > $pidfile
fi

if [ "$1" == "process" ]; then

	if [ ! -f $BLACKLIST ]; then
		touch $BLACKLIST
	fi

	if [ ! -f ${WHITELIST} ]; then
		touch ${WHITELIST}
	fi

	for (( ; ; ))
	do
		while read ipaddr
		do
			if [ $(grep -c $ipaddr ${WHITELIST}) -ne 0 ]; then
				echo 'Allow IP:' $ipaddr >> $logfile
				continue
			fi

			grep $ipaddr ${BLACKLIST}
			if [ $? -eq 1 ] ; then
				echo $ipaddr >> ${BLACKLIST}
				iptables -I INPUT -p tcp --dport 80 -s $ipaddr -j DROP
				echo "Deny IP: $ipaddr" >> $logfile
			fi
		done < $PIPE
	done &
	echo $! >> $pidfile
fi

5.2. WEB 服务器部分

下面所讲技术,适用于反向代理,负载均衡,web服务器

Web 服务器也可以实现前面所说的防火墙等设备3/4层的功能,同时具备七层功能,很多负载均衡设备7层采用web服务器实现,例如 F5 7层的高级功能是由 Apache httpd 来完成(apache 是经过二次开发的), 所以7层的部门我们主要在这里深入讨论

如果你有防火墙设备应该首先考虑在防火墙端做控制,如果没有防火墙那麽就考虑在负载均衡设备中做控制,这些设备你都没有,最后考虑在反向代理中处理,最后考虑web服务器。

限制IP地址在这里可以做到更细腻的控制,例如实现某个目录的,某URL的IP访问策略。请自行查找手册或参考《Netkiller Web 手札》

HTTP 协议头

我们要做以下几种限制

  1. 限制 http_referer, 常说的防盗链。

  2. 限制 http_user_agent, 主要是防爬虫

  3. 限制 request_method, 不是所有页面都允许 POST

  4. 限制 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; 
}

6. 通过程序控制访问行为

设计应用防火墙,将所有资源纳入管理范围

IP地址,上面已经反复强调怎样封锁IP地址,但都过于粗糙,很多时候是一刀切。在程序中实现禁止IP访问,更灵活

我们要做以下几种限制

  1. 单位时间内访问次数

  2. 访问时间间隔设置

  3. 封锁时间设置

  4. 黑白名单

验证码,最常用的,最有效的方法,分为图片扭曲法,问提/答案 法,手机验证码,语音验证码等等方法,形式多重多样

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_method

www.example.com (GET) -> login.example.com (GET)-> login.example.com/auth.ext (POST) -> login.example.com/secussed.ext (GET)

同理,在不允许的页面POST操作,将立即拒绝

http_cookie

www.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. 总结

上面提方法单一使用过于简单,需要组合使用,同时经常调整组合方式才能更有效阻止各种良性与恶性网站访问行为。

相关实践学习
Serverless极速搭建Hexo博客
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
目录
相关文章
|
5月前
JeecgBoot 短信验证码接口,如何实现防刷机制?
短信接口防刷,主要通过两个方面来实现:一个是短信接口加签和时间戳;另外针对短信接口,增加防刷 check 机制
89 1
|
1月前
|
数据采集 运维 JavaScript
淘宝反爬虫机制的主要手段有哪些?
淘宝的反爬虫机制包括用户身份识别与验证、请求特征分析、页面内容保护、浏览器指纹识别和蜜罐技术。通过User-Agent识别、Cookie验证、账号异常检测、请求频率限制、动态页面生成、验证码机制等手段,有效防止爬虫非法抓取数据。
|
2月前
|
存储 安全 区块链
搭建代购系统时如何保证商品信息的真实性和可靠性
搭建代购系统时,确保商品信息真实可靠至关重要。需严格筛选供应商,建立长期合作关系并签订详细合同;规范信息采集流程,多渠道验证信息并设专人审核;采用防伪技术和区块链技术提升信息透明度;建立用户评价体系,开通举报渠道;遵守相关法律法规,定期进行合规审查。
|
5月前
|
安全 算法 测试技术
淘宝API接口测试中的安全性保障
在电商领域,淘宝API连接商家与消费者,安全性至关重要。本文探讨了确保API接口测试安全的方法与最佳实践:接口签名确保请求完整性;Token方案防抓包和数据爬取;使用Postman和Katalon Studio提高测试效率。此外,还强调了使用授权认证、数据加密、参数验证及限制请求频率等安全配置的重要性。最后,提醒测试者注意账户授权、数据格式、遵循安全规范及保持工具更新。这些措施共同保障了API的安全性和稳定性。
|
4月前
|
缓存 自然语言处理 监控
关于代购系统的全面解析
全球化推动了跨境购物需求的增长,代购系统因此兴起。本文全面剖析代购系统的发展前景、使用流程、注意事项、优势特点、用户反馈及常见问题解决策略。系统预计将持续进化,通过技术创新提供多语言、多货币支持,优化物流服务,从而改善用户体验。用户需注册登录、提交需求、确认报价并支付,期间应注意数据合法性与安全性等问题。系统优点包括安全可靠的交易环境、多语言支持、强大的商品与支付功能等。用户普遍对其稳定性、客户服务及操作简便性给予好评,但也提出优化建议。面对诸如商品信息异常、支付问题等挑战,适时采取措施可有效解决。随着技术进步和服务升级,代购系统将为用户提供更优质的跨境购物体验。
|
7月前
|
存储 弹性计算 关系型数据库
100W用户、8000W流量在线贺卡应用架构如何优化?
100W用户、8000W流量在线贺卡应用架构如何优化?
|
消息中间件 安全 JavaScript
优雅的接口防刷处理方案! 上
优雅的接口防刷处理方案! 上
|
安全 NoSQL Redis
优雅的接口防刷处理方案! 下
优雅的接口防刷处理方案! 下
|
NoSQL 安全 Java
优雅的接口防刷处理方案 下
优雅的接口防刷处理方案 下