1. 程式人生 > >比較全面的vps防止cc攻擊

比較全面的vps防止cc攻擊

本文真的很好,我現在的防禦方法都來自於此文,再次我轉載這位高手的文章來共享給大家

CC攻擊可以歸 為DDoS攻擊的一種。他們之間都原理都是一樣的,即傳送大量的請求資料來導致伺服器拒絕服務,是一種連線攻擊。CC攻擊又可分為代理CC攻擊,和肉雞 CC攻擊。代理CC攻擊是黑客藉助代理伺服器生成指向受害主機的合法網頁請求,實現DOS,和偽裝就叫:cc(ChallengeCollapsar)。 而肉雞CC攻擊是黑客使用CC攻擊軟體,控制大量肉雞,發動攻擊,相比來後者比前者更難防禦。因為肉雞可以模擬正常使用者訪問網站的請求。偽造成合法資料 包。防禦CC攻擊可以通過多種方法,禁止網站代理訪問,儘量將網站做成靜態頁面,限制連線數量等。

  Nginx是一款輕量級的Web伺服器,由俄羅斯的程式設計師Igor Sysoev所開發,最初供俄國大型的入口網站及搜尋引Rambler使用。 其特點是佔有記憶體少,併發能力強,事實上Nginx的併發能力確實在同類型的網站伺服器中表現較好。

  Nginx雖然可以比Apache處理更大的連線數,但是HTTP GET FLOOD針對的不僅僅是WEB伺服器,還有資料庫伺服器。大量HTTP請求產生了大量的資料庫查詢,可以在幾秒之內使資料庫停止響應,系統負載升高,最終導致伺服器當機。

   本文主要介紹Centos+Nginx下如何快速有效得防禦CC攻擊。至於如何安裝Nginx就不詳細介紹了,有興趣的讀者可以在Nginx官方網站 (http://www.nginx.org/)下載原始碼進行編譯。如果你使用的是Centos5,也可以使用rpm包進行安裝(http: //centos.alt.ru/repository/centos/5/i386/nginx-stable- 0.7.65-1.el5.i386.rpm)。

一、主動抑制方法

  為了讓Nginx支援更多的併發連線數,根據實際 情況對工作執行緒數和每個工作執行緒支援的最大連線數進行調整。例如設定"worker_processes 10"和"worker_connections 1024",那這臺伺服器支援的最大連線數就是10×1024=10240。

worker_processes 10;
events {
use epoll;
worker_connections 10240;
}

  Nginx 0.7開始提供了2個限制使用者連線的模組:NginxHttpLimitZoneModule和NginxHttpLimitReqModule。NginxHttpLimitZoneModule可以根據條件進行併發連線數控制。

例如可以定義以下程式碼
http {
limit_zone   my_zone  $binary_remote_addr  10m;
server {
location /somedir/ {
limit_conn   my_zone  1;
}
}
}

   其中"limit_zone my_zone $binary_remote_addr 10m"的意思是定義一個名稱為my_zone的儲存區域、my_zone中的內容為遠端IP地址、my_zone的大小為10M;"location /somedir/"的意思是針對somedir目錄應用規則;"limit_conn my_zone 1"的意思是針對上面定義的my_zone記錄區記錄的IP地址在指定的目錄中只能建立一個連線。

  Nginx Http Limit Req Module可以根據條件進行請求頻率的控制。例如可以定義以下程式碼:

http {
limit_req_zone  $binary_remote_addr  zone=my_req_zone:10m   rate=1r/s;
...
server {
...
location /somedir/ {
limit_req_zone   zone= my_req_zone  burst=2;
}

   其中"limit_req_zone $binary_remote_addr zone=my_req_zone:10m rate=1r/s"的意思是定義一個名稱為my_req_zone的儲存區域,my_req_zone內容為遠端IP地址,my_req_zone大小 為10M,my_req_zone中的平均請求速率只能為1個每秒;"location /somedir/"的意思是針對somedir目錄應用規則;"limit_req_zone zone= my_req_zone burst=2"的意思是針對上面定義的my_req_zone記錄區記錄的IP地址在請求指定的目錄中的內容時最高2個每秒的突發請求速率。

  當有連線觸發上訴規則時,Nginx會報"503 Service Temporarily Unavailable"的錯誤,停止使用者請求。返回一個503,對伺服器來說影響不大,只佔用一個nginx的執行緒而已,相對來說還是很划算的。

   為了測試效果,我將以上程式碼放入Nginx的配置檔案,並編寫了一個php檔案顯示phpinfo;另外還寫了一個html檔案,其中嵌入了多個 iframe呼叫php檔案。當我開啟這個html檔案了,可以看到只有一個iframe中的php檔案正常顯示了,其他的iframe都顯示503錯 誤。

應用舉例(Discuz!)

  Discuz!是使用比較多的一個php論壇程式。 以Discuz!7.0為例,程式目錄下有比較多的可以直接訪問的php檔案,但其中最容易受到攻擊的一般有index.php(首頁)、 forumdisplay.php(板塊顯示)、viewthread.php(帖子顯示)。攻擊者一般會對這些頁面發起大量的請求,導致HTTP伺服器 連線數耗盡、mysql資料庫停止響應,最終導致伺服器崩潰。為了防止上述頁面被攻擊,我們可以設定以下的規則進行防禦:

http {
limit_zone   myzone_bbs  $binary_remote_addr  10m;
limit_req_zone $binary_remote_addr zone=bbs:10m rate=1r/s;
...
server {
...
location ~ ^/bbs/(index|forumdisplay|viewthread).php$ {
limit_conn   myzone_bbs  3;
limit_req zone=bbs burst=2 nodelay;
root           html;
fastcgi_pass   unix:/dev/shm/php-cgi.sock;
fastcgi_index  index.php;
fastcgi_param  SCRIPT_FILENAME  /usr/share/nginx/html$fastcgi_script_name;
include        fastcgi_params;
}
}
}

應用這條規則後,bbs目錄下的index.php、forumdisplay.php和viewthread.php這些頁面同一個IP只許建立3個 連線,並且每秒只能有1個請求(突發請求可以達到2個)。雖然這樣的規則一般來說對正常的使用者不會產生影響(極少有人在1秒內開啟3個頁面),但是為了防 止影響那些手快的使用者訪問,可以在nginx中自定義503頁面,503頁面對使用者進行提示,然後自動重新整理。在Nginx中自定義503頁面:
error_page   503   /errpage/503.html;

503頁面的原始碼:
<html>
<head>
<title>頁面即將載入....</title>
<meta http-equiv=content-type c>
<META NAME="ROBOTS" C>
</head>
<body bgcolor="#FFFFFF">
<table cellpadding="0" cellspacing="0" border="0" width="700" align="center" height="85%">
<tr align="center" valign="middle">
<td>
<table cellpadding="10" cellspacing="0" border="0" width="80%" align="center" style="font-family: Verdana, Tahoma; color: #666666; font-size: 11px">
<tr>
<td valign="middle" align="center" bgcolor="#EBEBEB">
<br /><b style="font-size: 16px">頁面即將載入</b>
<br /><br />你重新整理頁面的速度過快。請少安毋躁,頁面即將載入...
<br /><br />[<a href="javascript:window.location.reload();"><font color=#666666>立即重新載入</font></a>]
<br /><br />
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>

<SCRIPT language=javascript>
function update()
{
window.location.reload();
}
setTimeout("update()",2000);
</script>

二、被動防禦方法

  雖然主動防禦已經抵擋了大多數HTTP GET FLOOD攻擊,但是道高一尺魔高一丈,攻擊者會總會找到你薄弱的環節進行攻擊。所以我們在這裡也要介紹一下被動防禦的一些方法。

封IP地址

  訪問者通過瀏覽器正常訪問網站,與伺服器建立的連線一般不會超過20個,我們可以通過指令碼禁止連線數過大的IP訪問。以下指令碼通過netstat命令列舉所有連線,將連線數最高的一個IP如果連線數超過150,則通過 iptables阻止訪問:

#!/bin/sh
status=`netstat -na|awk '$5 ~ /[0-9]+:[0-9]+/ {print $5}' |awk -F ":" -- '{print $1}' |sort -n|uniq -c |sort -n|tail -n 1`
NUM=`echo $status|awk '{print $1}'`
IP=`echo $status|awk '{print $2}'`
result=`echo "$NUM > 150" | bc`
if [ $result = 1 ]
then
echo IP:$IP is over $NUM, BAN IT!
/sbin/iptables -I INPUT -s $IP -j DROP
fi

執行crontab -e,將上述指令碼新增到crontab每分鐘自動執行:

* * * * * /root/xxxx.sh

通過apache自帶的ab工具進行伺服器壓力測試:

# ab -n 1000 -c 100 http://www.xxx.com/bbs/index.php

測試完成後,我們就可以看到系統中有IP被封的提示:

#tail /var/spool/mail/root
Content-Type: text/plain; charset=ANSI_X3.4-1968
Auto-Submitted: auto-generated
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/root>
X-Cron-Env: <;PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=root>
X-Cron-Env: <USER=root>

IP:58.246.xx.xx is over 1047, BAN IT!

至此,又一次HTTP GET FLOOD防禦成功。

根據特徵碼遮蔽請求(對CC攻擊效果較好)

   一般同一種CC攻擊工具發起的攻擊請求包總是相同的,而且和正常請求有所差異。當伺服器遭遇CC攻擊時,我們可以快速檢視日誌,分析其請求的特徵,比如 User-agent。下面的是某一次CC攻擊時的User-agent,Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; MyIE 3.01)Cache-Control: no-store, must-revalidate幾乎沒有正常的瀏覽器會在User-agent中帶上"must-revalidate"這樣的關鍵字。所以我們可以以這 個為特徵進行過濾,將User-agent中帶有"must-revalidate"的請求全部拒絕訪問:

if ($http_user_agent ~ must-revalidate) {
return 403;
}

本文主要介紹了nginx下的HTTP GET FLOOD防禦,如果有不對的地方,希望大家可以向我提出。同時,也希望大家能夠舉一反三,把這種思路應用到apache、lighttpd等常見的web伺服器中。