Linux下apache防惡意訪問(攻擊)腳本

一、場景:由於公司在行業這塊比較出名,經常會受到競爭對手的惡意攻擊,導致網站經常訪問癱瘓

二、分析:1、某一天內某些IP訪問量非常大,2、某一IP連接訪問超過的次數到達一定的次數(本文中設置爲8)

三、解決思路:通過第二點分析出來的兩點問題進行攔截,但要注意的只,只攔截有效URL或者是我們想攔截的URL,舉個例子,一個客戶訪問了網站首頁,但客戶的請求一次網站首頁,連帶的同時客戶也請求了網站首頁所需求加載的各個圖片、css、js等資源,這些請求我們是不能算在客戶請求裏的,對於這樣的客戶有效訪問只算一次,即他只訪問了首頁

四、提前說明:網站的apache訪問日誌是一天分割兩次的,這樣的話,每天的apache訪問日誌量不會太大,程序分析起來效率會快很多

五、先看一下shell腳本(該shell腳本可以在linux crontab裏設置分1到3分鐘執行一次):

#!/bin/sh
#危險負載閾值,當系統負載達到該值時啓動攔截程序
TOP_SYS_LOAD_NUM=2.1
#安全負載閾值,當系統負載達到該值時關閉攔截程序
SAFE_SYS_LOAD_NUM=0.5
#apache危險連接數,當apache連接數達到該值時啓動攔截程序(與系統負載的閾值是“或”的關係)
HTTPD_PROCESS_NUMBER_MAX=350
#apache危險連接數,當apache連接數低於該值時關閉攔截程序(與系統負載的閾值是“且”的關係)
HTTPD_PROCESS_NUMBER_SAFE=250
SYS_LOAD_NUM=`uptime | awk '{print $(NF-2)}' | sed 's/,//'`
HTTPD_PROCESS_NUMBER=`ps -ef | grep httpd | wc -l`
#攔截文件標識(以些來判斷是否已經處理攔截狀態)
FILEPATH=/var/www/html/test/.htaccess_under_attack.id
ISOLDCONFIGFILE=""

echo $(date +"%y-%m-%d") `uptime`
echo $HTTPD_PROCESS_NUMBER

#滿足條件時啓動攔截
if [ `echo "$TOP_SYS_LOAD_NUM < $SYS_LOAD_NUM"|bc` -eq 1 ] || [ `echo "$HTTPD_PROCESS_NUMBER_MAX < $HTTPD_PROCESS_NUMBER"|bc` -eq 1 ]
then
        #如果之前已經開始攔截(創建了攔截文件),那麼攔截日誌一行的後面會加多加一段顯示“更新後”,如【圖1】
	if [ -f $FILEPATH ]
        then
                ISOLDCONFIGFILE="\t更新後"
        #否則創建攔截文件,如下【圖2】
	else
                touch $FILEPATH
        fi
	#切換到攔截網站的根目錄
        cd /var/www/html/test/crond/
	#運行攔截php程序
        /usr/bin/php -q crond_under_attack.php > /dev/null 2>&2
	#將php程序更新好的apache的重寫文件.htaccess_under_attack覆蓋到根目錄
        cp /var/www/html/test/.htaccess_under_attack /var/www/html/test/.htaccess_under_attack_temp
        mv -f /var/www/html/test/.htaccess_under_attack_temp /var/www/html/test/.htaccess
        #已啓動攔截程序,並將“使用黑名單(智能加強)配置文件”記錄日誌,如【圖2】
	echo -e "##" $(date +"%Y-%m-%d %H:%M:%S") " 使用黑名單(智能加強)配置文件"""$ISOLDCONFIGFILE >> /var/www/html/test/log/apache_access/apache_access_$(date +%Y%m%d).txt
#否則我們不執行攔截程序,或者記錄日誌告訴我們:之前處於攔截狀態,現在已安全,並使用了默認配置文件,並將“使用了默認配置文件”這段話記錄在日誌,如【圖3】
else
	if [ -f $FILEPATH ] && [ `echo "$SAFE_SYS_LOAD_NUM > $SYS_LOAD_NUM"|bc` -eq 1 ] && [ `echo "$HTTPD_PROCESS_NUMBER_SAFE > $HTTPD_PROCESS_NUMBER"|bc` -eq 1 ]
	then
		rm -f $FILEPATH
		cp /var/www/html/test/.htaccess_default /var/www/html/test/.htaccess_default_temp
		mv -f /var/www/html/test/.htaccess_default_temp /var/www/html/test/.htaccess
		echo "##" $(date +"%Y-%m-%d %H:%M:%S") " 使用默認配置文件" >> /var/www/html/test/log/apache_access/apache_access_$(date +%Y%m%d).txt
	else
		echo "Do nothing" `uptime`
	fi
fi

六、shell腳本調用的php腳本(自動檢測和更新黑名單)如下:

<?php
	$match_string = "index.php?action=login";
	$match_string_second = "script>";
	//連續訪問最大次數
	$match_time = 8;
	//日誌文件最後300行最多訪問次數
	$matched_numbers_300 = 40;
	//ip白名單
	$ip_white_array = array('172.68.34.45','172.68.46.82');
	//根據不同的時間段,設置一個IP最大的訪問次數,如現在是16點那麼,一個判斷的標準就是該ip在日誌中出現的有效訪問次數不能超過4000
	$matched_numbers = 3000;
	$date_hour = date("H");
	if(in_array($date_hour, array('06', '07', '19', '20'))) {
		$matched_numbers = 800;
	} else if(in_array($date_hour, array('03', '04', '05', '16', '17', '18'))) {
		$matched_numbers = 4000;
	}	
	
	$log_dir = "../log/under_attack";
	//獲取apache配置文件的內容
	$htaccess_content = file_get_contents("/var/log/httpd/access_test_log");
	$htaccess_content_array = explode("\n", $htaccess_content);
	$htaccess_content_array_count = count($htaccess_content_array);
	$htaccess_content_array_300 = array_splice($htaccess_content_array, $htaccess_content_array_count - 300, 300);

	$hack_array = array();
	$hack_array_number = array();
	//字符串中帶有這些訪問標識的不記錄在有效訪問次數中
	$match_char = "/(OPTIONS |ajax_|.jpg|.jpeg|.png|.gif|.bmp|.js|.css)/i";
	$date_hour = intval(date("H"));
	foreach($htaccess_content_array as $htaccess_value) {
		$line_array = explode(" - - ", $htaccess_value);
		if(!preg_match($match_char, $htaccess_value)) {
			array_push($hack_array_number, $line_array[0]);
		} else if(strstr($htaccess_value, $match_string)) {
			array_push($hack_array, $line_array[0]);
		} else if(strstr($htaccess_value, $match_string_second)) {
			array_push($hack_array, $line_array[0]);
		}
	}
	
	$hack_array_300 = array();
	$hack_array_number_300 = array();
	foreach($htaccess_content_array_300 as $htaccess_value_300) {
		$line_array_300 = explode(" - - ", $htaccess_value_300);
		if(!preg_match($match_char, $htaccess_value_300)) {
			array_push($hack_array_number_300, $line_array_300[0]);
		} else {
			array_push($hack_array_300, $line_array_300[0]);
		}
	}
	
	$under_attack_ips_insert = "";
	$under_attack_log = "";
	
	$hack_total = array();

	foreach($hack_array_number as $hack_value) {
		if(!in_array($hack_value, $ip_white_array)) {
			if(!isset($hack_total[$hack_value])) {
				$hack_total[$hack_value] = 1;
			} else {
				$hack_total[$hack_value] = $hack_total[$hack_value] + 1;
			}
		}
	}
	
	foreach($hack_total as $total_key => $total_value) {
		if($total_value < $matched_numbers) {
			unset($hack_total[$total_key]);
		}
	}
		
	foreach($hack_array as $hack_value) {
		if(!in_array($hack_value, $ip_white_array)) {
			if(!isset($hack_total[$hack_value])) {
				$hack_total[$hack_value] = 1;
			} else {
				$hack_total[$hack_value] = $hack_total[$hack_value] + 1;
			}
		}
	}

	foreach($hack_total as $hack_key => $hack_time) {
		if($hack_time >= $match_time) {
			$under_attack_ips_insert .= "Deny from " . $hack_key . "\n";
			$under_attack_log .= $hack_key . "\t" . $hack_time . "\n";
		}
	}
	
	
	/***********取倒數300行數據進行分析開始************/
	
	$hack_total_300 = array();

	foreach($hack_array_number_300 as $hack_value_300) {
		if(!in_array($hack_value_300, $ip_white_array)) {
			if(!isset($hack_total_300[$hack_value_300])) {
				$hack_total_300[$hack_value_300] = 1;
			} else {
				$hack_total_300[$hack_value_300] = $hack_total_300[$hack_value_300] + 1;
			}
		}
	}
	
	foreach($hack_total_300 as $total_key => $total_value) {
		if($total_value < $matched_numbers) {
			unset($hack_total_300[$total_key]);
		}
	}
		
	foreach($hack_array_300 as $hack_value_300) {
		if(!in_array($hack_value_300, $ip_white_array)) {
			if(!isset($hack_total_300[$hack_value_300])) {
				$hack_total_300[$hack_value_300] = 1;
			} else {
				$hack_total_300[$hack_value_300] = $hack_total_300[$hack_value_300] + 1;
			}
		}
	}
	
	foreach($hack_total_300 as $hack_key_300 => $hack_time_300) {
		if($hack_time_300 >= $matched_numbers_300) {
			$under_attack_ips_insert .= "Deny from " . $hack_key_300 . "\n";
			$under_attack_log .= $hack_key_300 . "\t" . $hack_time_300 . "\texceed " . $matched_numbers_300 . " in line " . count($hack_array_number_300) . "/300\n";
		}
	}
	
	/***********取倒數300行數據進行分析結束***********/
	
	//要切割的文件模式如【圖4】
	$under_attack_split = "#under_attack_ips";
	$under_attack_htaccess = file_get_contents("../.htaccess_under_attack");
	$under_attack_htaccess_array = explode($under_attack_split, $under_attack_htaccess);
	//寫入配置文件
	$under_attack_htaccess_content = $under_attack_htaccess_array[0] . $under_attack_split . "\n" . $under_attack_ips_insert . $under_attack_split . $under_attack_htaccess_array[2];
	file_put_contents("../.htaccess_under_attack", $under_attack_htaccess_content);
	file_put_contents($log_dir . "/under_attack_log_" . date("YmdHis") . "_" . $htaccess_content_array_count . ".txt", $under_attack_log);
?>

七、大功告成,至此之後網站抵禦了99%的攻擊

推薦閱讀:http://www.laikanxia.com

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章