爬虫和反爬虫日益成为每家公司的标配系统。爬虫在情报获取、虚假流量、动态订价、恶意攻击、薅羊毛等方面都能起到很关键的做用,因此每家公司都或多或少的须要开发一些爬虫程序,业界在这方面的成熟的方案也很是多;有矛就有盾,每家公司也相应的须要反爬虫系统来达到数据保护、系统稳定性保障、竞争优点保持的目的。java
然而,一方面防守这事ROI很差体现,另外一方面反爬虫这种系统,相对简单的爬虫来讲难度和复杂度都要高不少,每每须要一整套大数据解决方案才能把事情作好,所以只有少许的公司能够玩转起来。当出现问题的时候,不少公司每每一筹莫展。python
本文将描述一种尽可能简单的反爬虫方案,能够在十几分钟内解决部分简单的爬虫问题,缓解恶意攻击或者是系统超负荷运行的情况;至于复杂的爬虫以及更精准的防护,须要另外讨论。linux
整套方案会尽可能简单易懂,不会涉及到专门的程序开发,同时尽可能利用现有的组件,避免额外组件的引入。内容上主要分为三大部分:nginx
访问数据获取。采集用户的访问数据,用来作爬虫分析的数据源正则表达式
爬虫封禁。当找到爬虫后,想办法去阻断它后续的访问shell
爬虫分析。示例经过简单策略来分析出爬虫apache
数据获取是作好反爬虫系统的关键,常见的几种模式centos
本篇,采用nginx的日志方式,这种只须要经过对常见的nginx最简单的配置就能从远程获取相应的访问日志安全
官方nginx配置:cookie
log_format warden '" "$remote_addr" "$remote_port" "$server_addr" "$server_port" "$request_length" "$content_length" "$body_bytes_sent" "$request_uri" "$host" "$http_user_agent" "$status" "$http_cookie" "$request_method" "$http_referer" "$http_x_forwarded_for" "$request_time" "$sent_http_set_cookie" "$content_type" "$upstream_http_content_type" "$request_body"\n'; access_log syslog:server=127.0.0.1:9514 warden ;
tengine配置(编译时带上--with-syslog)
log_format warden '" "$remote_addr" "$remote_port" "$server_addr" "$server_port" "$request_length" "$content_length" "$body_bytes_sent" "$request_uri" "$host" "$http_user_agent" "$status" "$http_cookie" "$request_method" "$http_referer" "$http_x_forwarded_for" "$request_time" "$sent_http_set_cookie" "$content_type" "$upstream_http_content_type" "$request_body"\n'; access_log syslog:user::127.0.0.1:9514 warden ;
这里面须要注意的是:
因为较老的nginx官方版本不支持syslog,因此tengine在这块功能上作了单独的开发(须要经过编译选项来启用),在不肯定的状况下,请修改配置 文件后先使用(nginx -t)来测试一下,若是不经过,须要从新在configure时加上syslog选项,并编译。
尽可能获取了跟爬虫相关的数据字段,若是有定制的http header,能够自行加上
采用udp方式来发送syslog,能够将访问日志发送给远端分析服务,同时udp的方式保证nginx自己不会受到影响
访问日志拿不到响应的具体内容(nginx有办法搞定,但有代价),没法支持业务相关的防御
反爬虫最后的生效,须要靠合理的封禁模式,这里比较几种模式:
本段将介绍基于iptables的方案,虽然适用范围较小;可是依赖少,能够经过简单配置linux就能达到效果。
安装ipset。ipset扩充了iptables的基本功能,能够提供更加高效的访问控制 # centos 6.5上面安装很是简单 sudo yum install -y ipset
在iptables中创建相应的ipset,来进行访问权限的封禁
# 新增用于封禁的ipset sudo ipset -N --exist warden_blacklist iphash # 增长相应的iptables规则 sudo iptables -A INPUT -m set --set warden_blacklist src -j DROP # 保存iptables sudo service iptables save
获取当前封禁的ip黑名单,并导入到iptables里面去
sudo ipset --exist destroy warden_blacklist_tmp; sudo ipset -N warden_blacklist_tmp iphash; echo "1.1.1.1,2.2.2.2" | tr , "\n" | xargs -n 1 -I {} sudo ipset -A warden_blacklist_tmp {} ; sudo ipset swap warden_blacklist_tmp warden_blacklist
这里为了尽量的提高效率,做了如下事情:
创建临时ipset,方便作操做
将当前封禁黑名单中的ip提取出来,加入到此ipset(示例中用了最简单的echo来展现,实际可相应调整)
将ipset经过原子操做与iptables正在使用的ipset做交换,以最小的代价将最新的黑名单生效
要能精确的分析爬虫,须要强大的数据分析平台和规则引擎,来分析这个IP/设备/用户分别在短期区间/长时间范围里的行为特征和轨迹,这里涉及到了很是复杂的数据系统开发,本文将经过简单的shell脚本描述比较简单的规则
nc -ul 9514 | head -100000 | awk -F '" "' '{print $2}' | sort | uniq -c | sort -nr | awk '$1>=5000 {print $2}'
这里面:
udp服务监听nginx发过来的syslog消息,并取10000条,找到其中每条访问记录的ip
经过sort 和uniq来获取每一个ip出现的次数,并进行降序排列
再经过awk找到其中超过阈值的ip,这就获得了咱们所须要的结果。
nc -ul 9514 | head -100000 | awk -F '" "' '$10 ~ /java|feedly|universalfeedparser|apachebench|microsoft url control|python-urllib|httpclient/ {print $2}' | uniq
这里面:
经过awk的正则来过滤出问题agent,并将相应ip输出
关于agent的正则表达式列出了部分,能够根据实际状况去调整和积累
固然,这里只是列举了简单的例子,有不少的不足之处
因为只采用了shell,规则比较简单,能够经过扩展awk或者其余语言的方式来实现更复杂的规则
统计的窗口是每100000条,这种统计窗口比较粗糙,好的统计方式须要在每条实时数据收到是对过去的一小段时间(例如5分钟)从新作统计计算
不够实时,没法实时的应对攻击行为;生产环境中,须要毫秒级的响应来应对高级爬虫
.......
全部模块组合起来,作一个完整的例子。假设:
负载均衡192.168.1.1,使用了官方nginx,并配置了syslog发往192.168.1.2
192.168.1.2启动nc server,每隔一段时间进行分析,找出问题ip,并吐给192.168.1.1
192.168.1.1经过iptables进行阻拦,数据来源于192.168.1.2的分析机器
除了nginx配置和iptables基本配置,前几段的配置略做改动:
### nginx conf@192.168.1.1 log_format warden '" "$remote_addr" "$remote_port" "$server_addr" "$server_port" "$request_length" "$content_length" "$body_bytes_sent" "$request_uri" "$host" "$http_user_agent" "$status" "$http_cookie" "$request_method" "$http_referer" "$http_x_forwarded_for" "$request_time" "$sent_http_set_cookie" "$content_type" "$upstream_http_content_type" "$request_body"\n'; access_log syslog:server=192.168.1.2:9514 warden ; ### 分析@192.168.1.2, 增长告终果会吐,同时每隔60分钟跑一次,把数据返回给192.168.1.1 while true ; do nc -ul 9514 | head -100000 | awk -F '" "' '{print $2}' | sort | uniq -c | sort -nr | awk '$1>=5000 {print $2}' | tr '\n' ',' | awk '{print $0}' | socat - UDP:192.168.1.1:9515 ; sleep 3600 ; done ### 阻断@192.168.1.1 #基础配置 sudo ipset -N --exist warden_blacklist iphash sudo iptables -A INPUT -m set --set warden_blacklist src -j DROP sudo service iptables save #动态接收并更新iptables while true ; do sudo ipset --exist destroy warden_blacklist_tmp; sudo ipset -N warden_blacklist_tmp iphash; socat UDP-LISTEN:9515 - | tr , "\n" | xargs -n 1 -I {} sudo ipset -A warden_blacklist_tmp {} ;sudo ipset swap warden_blacklist_tmp warden_blacklist ; sudo ipset list ; done
以上只是简单示例,实际中仍是建议换成shell脚本
本文列出一种简单的反爬虫方案,因为过于简单,能够当作概念示例或者是救急方案,若是须要进一步深化,须要在如下方面去增强:
强化数据源,能够经过流量得到全量数据。目前爬虫等网络攻击逐渐转向业务密切相关的部分,往钱的方向靠近,因此须要更多的业务数据去支撑,而不只仅是访问日志
更灵活的阻断,须要有多种阻断手段和略复杂的阻断逻辑
除却ip,还须要考察用户、设备指纹等多种追踪方式,应对移动环境和ipv6环境下,“IP”这一信息的力不从心
强化规则引擎和模型,须要考察更多用户行为的特征,仅仅从频率等手段只等应对傻爬虫,同时会形成误杀率更高
创建数据存储、溯源、统计体系,方便分析人员去分析数据并创建新的模型和规则。反爬虫是一件持续性行为,须要良好的平台来支撑。
能够根据实际须要去作好反爬虫系统的集成。好比nginx数据-->反爬系统-->nginx阻断;F5数据-->反爬系统-->F5阻断
岂安科技联合创始人,首席产品技术官曾担任PayPal资深高级工程师,在可信计算,计算机风控等领域有深刻的理论研究和成果;并在防欺诈和风险监控行业有多年且深厚的工做经历,擅长分布式系统和实时大数据计算。他参与岂安科技全部产品线的架构和设计,带领团队在数据挖掘、多媒体分析、跨数据中心分布式系统、高性能实时大数据计算、海量数据采集等领域进行前沿研究和产品化,帮助客户更好的解决内部的安全和风控问题。