關於防刷票的一些問題
刷票行為,一直以來都是個難題,無法從根本上防止。
但是我們可以盡量減少刷票的傷害,比如:通過人為增加的邏輯限制。
基於 PHP,下面介紹防刷票的一些技巧:
1、使用CURL進行資訊偽造
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://localhost/2.php");curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-FORWARDED-FOR:8.8.8.8', 'CLIENT-IP:8.8.8.8'));curl_setopt($ch, CURLOPT_REFERER, "http://localhost/ ");curl_setopt($ch, CURLOPT_HEADER, 1);curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; MSIE 6.0; Windows NT 5.0)");$out = curl_exec($ch); curl_close($ch);
2、驗證碼:採用非常複雜的驗證碼
確切的說驗證碼的出現不是針對於人,而是針對於機器。通過複雜度和識別難易度的控制來阻攔掉一部分刷票機,從而減少刷票的發生。但隨著軟體技術、識別技術的發展越來越多的驗證碼面對著先進的刷票軟體也失去了其防範的作用、但是專業刷票機可以攻破。如果不用驗證碼,投票基本就歇菜了,驗證碼擷取方式,採用非同步載入,即點擊輸入框時,才去請求,投票成功後,刪除驗證碼的 Session
3、限時投票
比如:從早8點至晚23 點
4、設定投票間隔
使用者投票後,需要隔多長時間才能繼續投。很多投票網站基本上都有這個限制,但是對於更改 IP的攻擊,就沒辦法了
5、投票結果展示:延遲展示,友好展示
頁面上投票,JS 立馬加1,但是重新整理頁面,不一定立馬展示最新投票結果,返回狀態給頁面(感謝您的投票!或者 投票成功!至於有沒有成功,另說了!)
6、扣量邏輯:常見於一些軟體評選之類的投票
- 這是個殺手鐧,後台跑指令碼即時監控異常增長(刷票)的項,然後實施扣量邏輯
- 即對於這個項,投 10 票才算一票
7、Cookie:常用的手段。比較低級
- 投票後,在用戶端寫入 Cookie,下次投票時判斷 Cookie 是否存在
- 但是,這種方式非常容易攻破,因為 Cookie 可刪除
8、加密選項 ID:對一些投票選項的ID,進行隨機加密
- 密碼編譯演算法,加Salt,並且設定有效時間,比如5分鐘內
- 伺服器端進行解密並且驗證
9、nginx限制連結數
- ngx_http_limit_conn_module
- ngx_http_limit_req_module
- nginx_limit_speed_module
可以使用這三個模組來限制,不過這不是一個好的解決方案
具體可以參見:關於nginx的限速模組
10、iptables限制
/sbin/iptables -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --rcheck --seconds 60 --hitcount 10 -j LOG --log-prefix 'DDOS:' --log-ip-options#60秒10個新串連,超過記錄日誌。/sbin/iptables -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --rcheck --seconds 60 --hitcount 10 -j DROP#60秒10個新串連,超過丟棄資料包。/sbin/iptables -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --set -j ACCEPT#範圍內允許通過。/sbin/iptables -t filter -A INPUT -p tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -m connlimit --connlimit-above 10 --connlimit-mask 32 -j REJECT#限制與80連接埠串連的IP最大串連數為10#參考其它/sbin/iptables -A INPUT -f -m limit –-limit 100/s –-limit-burst 100 -j ACCEPT#每秒鐘最多允許100個新串連/sbin/iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 10 -j ACCEPT #防止ping洪水攻擊,限制每秒的ping包不超過10個/sbin/iptables -A INPUT -p tcp -m tcp –tcp-flags SYN,RST,ACK SYN -m limit --limit 20/s --limit-burst 200 -j ACCEPT#防止各種連接埠掃描,將SYN及ACK SYN限制為每秒鐘不超過200個,免得把數務器頻寬耗盡了/sbin/iptables -A OUTPUT -p icmp -o eth0 -j ACCEPT/sbin/iptables -A INPUT -p icmp --icmp-type echo-reply -s 0/0 -i eth0 -j ACCEPT/sbin/iptables -A INPUT -p icmp --icmp-type destination-unreachable -s 0/0 -i eth0 -j ACCEPT/sbin/iptables -A INPUT -p icmp --icmp-type time-exceeded -s 0/0 -i eth0 -j ACCEPT/sbin/iptables -A INPUT -p icmp -i eth0 -j DROP#拒絕ping請求或者net.ipv4.icmp_echo_ignore_all = 1
具體指令碼
#!/bin/bash# Date: 2015-09-29# # Author: [email protected]shopt -s -o nounsetexport PATH=/usr/bin/:/biniptables_log="/tmp/iptables_conf.log"/sbin/iptables -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --rcheck --seconds 60 --hitcount 10 -j DROP /sbin/iptables -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --set -j ACCEPT/sbin/iptables -t filter -A INPUT -p tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -m connlimit --connlimit-above 10 --connlimit-mask 32 -j REJECTwhile [ true ]; do #sleep 1 for IP in `netstat -an | grep -i ':80 '|grep 'ESTAB' | awk '{print $5}' | cut -d : -f 1 | sort | uniq -c | awk '{if($1 > 30 && $2!="127.0.0.1" ) {print $2}}'` do /sbin/iptables -L -n | grep $IP >/dev/null || /sbin/iptables -A INPUT -p tcp --dport 80 -s $IP -j DROP echo "/sbin/iptables -A INPUT -p tcp -s $IP -j DROP" >> ${iptables_log} donedone