ban特征
需要有tcpdump工具
apt-get install tcpdump
tcpdump -s0 -A -n -i any | grep -o -E '(GET|POST|HEAD).*'
tcpdump -s0 -A -n -i any | grep -o -E '(GET|POST|HEAD|Host).*'
tcpdump還有其他的命令:
tcpdump -s0 -A -n -i any | grep ^User-Agent
tcpdump -s0 -A -n -i any | grep -o -E '(X-Forwarded-For).*'
tcpdump -s0 -A -n -i any | grep -o -E '(Referer).*'

Paste_Image.png
像這種某一個(gè)頁面被重復(fù)請求,并且服務(wù)器CPU和流量大增,那肯定是cc了。
我們需要使用nginx來限制訪問頻率,以及ban掉這些特征
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
listen 80;
server_name www.mysite.com;
#訪問日志
# access_log /mnt/www/mysite/logs/access.log;
#error_log /mnt/www/mysite/logs/access.log;
#靜態(tài)文件直接從目錄返回
location ^~ /static/ {
root /mnt/www/mysite/app;
}
#搜索頁面判斷來路,并且設(shè)置
location ^~ /search {
#非淘客喵來路全部禁止訪問搜索
if ($http_referer !~* .*\.mysite.com){
return 403;
}
#deny all;
#搜索限制訪問次數(shù)
limit_conn addr 2;
limit_req zone=one burst=3 nodelay;
proxy_pass http://127.0.0.1:8000;
break;
}
#其他頁面
location / {
#限制訪問次數(shù)
limit_conn addr 3;
limit_req zone=one burst=5;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
#文件不存在則轉(zhuǎn)到gunicorn服務(wù)
if (!-f $request_filename) {
proxy_pass http://127.0.0.1:8000;
break;
}
}
}
BAN IP
用這個(gè)命令查看大于并發(fā)大于20的IP,里面有些是服務(wù)器的云盾或者之類的IP段,ban掉就無法訪問了
#查詢訪問次數(shù)大于20次的ip
#-c 2000的意思是,總訪問數(shù)達(dá)到2000次退出并返回結(jié)果
tcpdump -i eth1 -tnn dst port 80 -c 2000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr |awk -v str=20 '{if ($1>str){print $1,$3}}'| head -20

Paste_Image.png
監(jiān)聽到有很多ip大量訪問,最前面是訪問次數(shù)。
那么我們可以寫一個(gè)腳本利用iptables防火墻ban掉他們。
cd /root
vi deny.sh
寫入以下腳本
#!/bin/bash
#Author:ZhangGe&Corek
#Desc:Auto Deny Black_IP Script.
#Date:2016-11-16
#從第一個(gè)參數(shù)取得限制閾值,如果未設(shè)置最高并發(fā),將設(shè)置為30
if [[ -z $1 ]];then
num=30
else
num=$1
fi
#進(jìn)入到腳本所在目錄
cd $(cd $(dirname $BASH_SOURCE) && pwd)
#取得當(dāng)前請求大于閾值$num的IP列表
iplist=`tcpdump -i eth1 -tnn dst port 80 -c 5000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr |awk -v str=$num '{if ($1>str){print $3}}'`
#循環(huán)IP列表進(jìn)行篩選和處理
if [[ ! -z $iplist ]];
then
for black_ip in $iplist
do
#取得IP所在段
ip_section=`echo $black_ip | awk -F"." '{print $1"."$2"."$3}'`
#先檢查白名單中是否存在匹配的IP段(為了支持整段IP為白名單)
grep -q $ip_section ./white_ip.txt
if [[ $? -eq 0 ]];then
#若發(fā)現(xiàn)black_ip和白名單的一個(gè)段匹配,則寫入到待驗(yàn)證列表,并暫時(shí)放過
echo $black_ip >>./recheck_ip.txt
else
#若不再白名單當(dāng)中,則直接將black_ip加入到防火墻的DROP規(guī)則當(dāng)中,并記錄
#封單IP
#iptables -nL | grep $black_ip || iptables -I INPUT -s $black_ip -j DROP
#echo $black_ip >>./black_ip.txt
#直接封IP段
iptables -nL | grep $ip_section.0/24 || iptables -I INPUT -s $ip_section.0/24 -j DROP
echo $ip_section.0/24 >>./black_ip.txt
fi
done
fi
保存后。
我們建立一個(gè)白名單txt,把服務(wù)器IP和爬蟲IP以及阿里云云盾的IP段寫進(jìn)去,要是這些IP被ban掉,web就無法訪問了
比如
vi white_ip.txt
#寫入
#服務(wù)器的IP
106.14.30.*
#云盾IP
140.205.16.*
保存。
運(yùn)行,后面的參數(shù)20表示這段結(jié)果中訪問數(shù)大于20的段全部ban掉
nohup ./deny.sh 20
附上iptables的操作
#查看ban掉的IP
iptables -nL
#清空iptables防火墻的記錄
iptables -F
#將某個(gè)ip單獨(dú)ban
iptables -I INPUT -s 115.219.59.126 -j DROP
#將某個(gè)IP取消屏蔽
iptables -D INPUT -s 119.182.160.132 -j DROP
#屏蔽ip段
iptables -I INPUT -s 115.219.59.0/24 -j DROP
2017年8月1日更新
其實(shí)最有用的還是屏蔽來路,現(xiàn)在的很多CC都是用腳本嵌套刷,來路都是各種亂七八糟的網(wǎng)頁。
編輯站點(diǎn)nginx配置文件
cd /etc/nginx/sites-available
vi mysite
內(nèi)容如下
server {
listen 80;
server_name www.mysite.com;
#修改最大上傳為10M,默認(rèn)為2M,超出大小出現(xiàn)413 Request Entity Too Large錯(cuò)誤
client_max_body_size 10M;
#搜索頁面防CC
location ^~ /search {
set $deny 1;
if ($http_referer ~* .*\.mysite.com){
set $deny 0;
}
if ($http_referer ~* .*\.baidu.com){
set $deny 0;
}
if ($http_referer ~* .*\.sogou.com){
set $deny 0;
}
if ($http_referer = ''){
set $deny 0;
}
#如果來路驗(yàn)證不通過,則拒絕
if ($deny = 1){
rewrite .+ http://www.163.com redirect;
#rewrite ^/(.*) http://www.163.com redirect;
#return 403;
}
#將訪客IP加入headers中,否則獲取到的將是127.0.0.1
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
#如果請求的文件不存在,則將路由轉(zhuǎn)發(fā)到gunicorn的8000端口
if (!-f $request_filename) {
proxy_pass http://127.0.0.1:8000;
break;
}
}
#默認(rèn)請求,nginx反向代理(動態(tài)頁面轉(zhuǎn)發(fā)至gunicorn)
location / {
#將訪客IP加入headers中,否則獲取到的將是127.0.0.1
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
#如果請求的文件不存在,則將路由轉(zhuǎn)發(fā)到gunicorn的8000端口
if (!-f $request_filename) {
proxy_pass http://127.0.0.1:8000;
break;
}
}
#靜態(tài)文件請求轉(zhuǎn)發(fā)給目錄
location ^~ /static/ {
root /var/www/mysite/app;
}
}
立竿見影,加上這個(gè)nginx配置,然后重啟nginx。

Paste_Image.png
馬上帶寬就降了。