十分鐘解決爬蟲問題!超輕量級反爬蟲方案

bigsec

爬蟲和反爬蟲日益成爲每家公司的標配系統。爬蟲在情報獲取、虛假流量、動態訂價、惡意攻擊、薅羊毛等方面都能起到很關鍵的做用,因此每家公司都或多或少的須要開發一些爬蟲程序,業界在這方面的成熟的方案也很是多;有矛就有盾,每家公司也相應的須要反爬蟲系統來達到數據保護、系統穩定性保障、競爭優點保持的目的。java

然而,一方面防守這事ROI很差體現,另外一方面反爬蟲這種系統,相對簡單的爬蟲來講難度和複雜度都要高不少,每每須要一整套大數據解決方案才能把事情作好,所以只有少許的公司能夠玩轉起來。當出現問題的時候,不少公司每每一籌莫展。python

本文將描述一種儘可能簡單的反爬蟲方案,能夠在十幾分鍾內解決部分簡單的爬蟲問題,緩解惡意攻擊或者是系統超負荷運行的情況;至於複雜的爬蟲以及更精準的防護,須要另外討論。linux

整套方案會盡可能簡單易懂,不會涉及到專門的程序開發,同時儘可能利用現有的組件,避免額外組件的引入。內容上主要分爲三大部分:nginx

  1. 訪問數據獲取。採集用戶的訪問數據,用來作爬蟲分析的數據源正則表達式

  2. 爬蟲封禁。當找到爬蟲後,想辦法去阻斷它後續的訪問shell

  3. 爬蟲分析。示例經過簡單策略來分析出爬蟲apache

簡單的數據獲取

數據獲取是作好反爬蟲系統的關鍵,常見的幾種模式centos

bigsec

本篇,採用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有辦法搞定,但有代價),沒法支持業務相關的防禦

簡單的爬蟲封禁

反爬蟲最後的生效,須要靠合理的封禁模式,這裏比較幾種模式:
 
bigsec

本段將介紹基於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腳本描述比較簡單的規則

例子1,封禁最近100000條中訪問量超過5000的ip

nc -ul 9514 | head -100000 | awk -F '" "' '{print $2}' | sort | uniq -c | sort -nr | awk '$1>=5000 {print $2}'

這裏面:

  1. udp服務監聽nginx發過來的syslog消息,並取10000條,找到其中每條訪問記錄的ip

  2. 經過sort 和uniq來獲取每一個ip出現的次數,並進行降序排列

  3. 再經過awk找到其中超過閾值的ip,這就獲得了咱們所須要的結果。

例子2,封禁最近100000條中user agent明顯是程序的ip

nc -ul 9514 | head -100000 | awk -F '" "' '$10 ~ /java|feedly|universalfeedparser|apachebench|microsoft url control|python-urllib|httpclient/ {print $2}' | uniq

這裏面:

  1. 經過awk的正則來過濾出問題agent,並將相應ip輸出

  2. 關於agent的正則表達式列出了部分,能夠根據實際狀況去調整和積累

 

固然,這裏只是列舉了簡單的例子,有不少的不足之處

  1. 因爲只採用了shell,規則比較簡單,能夠經過擴展awk或者其餘語言的方式來實現更復雜的規則

  2. 統計的窗口是每100000條,這種統計窗口比較粗糙,好的統計方式須要在每條實時數據收到是對過去的一小段時間(例如5分鐘)從新作統計計算

  3. 不夠實時,沒法實時的應對攻擊行爲;生產環境中,須要毫秒級的響應來應對高級爬蟲

  4. .......

拼起來

全部模塊組合起來,作一個完整的例子。假設:

  1. 負載均衡192.168.1.1,使用了官方nginx,並配置了syslog發往192.168.1.2

  2. 192.168.1.2啓動nc server,每隔一段時間進行分析,找出問題ip,並吐給192.168.1.1

  3. 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腳本
 

總結

本文列出一種簡單的反爬蟲方案,因爲過於簡單,能夠當作概念示例或者是救急方案,若是須要進一步深化,須要在如下方面去增強:

  1. 強化數據源,能夠經過流量得到全量數據。目前爬蟲等網絡攻擊逐漸轉向業務密切相關的部分,往錢的方向靠近,因此須要更多的業務數據去支撐,而不只僅是訪問日誌

  2. 更靈活的阻斷,須要有多種阻斷手段和略複雜的阻斷邏輯

  3. 除卻ip,還須要考察用戶、設備指紋等多種追蹤方式,應對移動環境和ipv6環境下,「IP」這一信息的力不從心

  4. 強化規則引擎和模型,須要考察更多用戶行爲的特徵,僅僅從頻率等手段只等應對傻爬蟲,同時會形成誤殺率更高

  5. 創建數據存儲、溯源、統計體系,方便分析人員去分析數據並創建新的模型和規則。反爬蟲是一件持續性行爲,須要良好的平臺來支撐。

  6. 能夠根據實際須要去作好反爬蟲系統的集成。好比nginx數據-->反爬系統-->nginx阻斷;F5數據-->反爬系統-->F5阻斷

反爬蟲
文章來源:http://bigsec.com/

做者介紹

豈安科技聯合創始人,首席產品技術官曾擔任PayPal資深高級工程師,在可信計算,計算機風控等領域有深刻的理論研究和成果;並在防欺詐和風險監控行業有多年且深厚的工做經歷,擅長分佈式系統和實時大數據計算。他參與豈安科技全部產品線的架構和設計,帶領團隊在數據挖掘、多媒體分析、跨數據中心分佈式系統、高性能實時大數據計算、海量數據採集等領域進行前沿研究和產品化,幫助客戶更好的解決內部的安全和風控問題。

相關文章
相關標籤/搜索