首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 防禦 CC 攻擊實戰:從日誌分析到程式碼升級的完整防護策略

     編輯:PHP 綜合知識

攻擊現況分析

某日發現網站遭受大規模 CC 攻擊,單日攻擊次數高達 125,008 次。攻擊特徵:

  • 3-5 個不同 IP 同時發起攻擊
  • 頻率:每秒 3-5 次,合併後每秒 9-25 次
  • IP 輪換週期:1-6 小時換一次,且不重複
  • 主要來源:土耳其、哥倫比亞、意大利、印度尼西亞等國

原有防護機制(600 秒周期)已失效,攻擊者改用「攻擊 2 分鐘、停 5 分鐘」的智能輪流策略繞過防禦。

防護策略升級

參數調整

  • 原策略:600 秒周期,保守方案
  • 新策略:120 秒內允許 120 次請求
  • 誤殺率:< 0.5%(經日誌驗證,僅 1 例因網路重刷觸發)

核心防護程式碼 (Ver 2.0)

<?php
// 版本:Anti-IP attack code website 2.0
// 作者:www.mydalle.com

// 1. 檢查 IP 是否在黑名單
$ip = $_SERVER['REMOTE_ADDR'];
$fileht = ".htaccess2";
if (!file_exists($fileht)) file_put_contents($fileht, "");
$filehtarr = @file($fileht);
if (in_array($ip . "\r\n", $filehtarr)) {
    die("Warning: Your IP is forbidden. Contact shop@mydalle.com");
}

// 2. 封禁檢查機制(120 秒觀察期)
$time = time();
$fileforbid = "log/forbidchk.dat";

if (file_exists($fileforbid)) {
    if ($time - filemtime($fileforbid) > 30) {
        unlink($fileforbid); // 超過 30 秒未達標,清除記錄
    } else {
        $fileforbidarr = @file($fileforbid);
        if ($ip == substr($fileforbidarr[0], 0, strlen($ip))) {
            if ($time - substr($fileforbidarr[1], 0, strlen($time)) > 120) {
                unlink($fileforbid); // 觀察期結束
            } elseif ($fileforbidarr[2] > 120) {
                // 超過閾值,寫入黑名單
                file_put_contents($fileht, $ip . "\r\n", FILE_APPEND);
                unlink($fileforbid);
            } else {
                $fileforbidarr[2]++;
                file_put_contents($fileforbid, $fileforbidarr);
            }
        }
    }
}

// 3. 防刷新機制(60 秒內最多 5 次同頁請求)
$allowTime = 60;
$allowNum = 5;
$uri = $_SERVER['REQUEST_URI'];
$checkip = md5($ip);
$checkuri = md5($uri);
$file = "log/ipdate.dat";

if (!file_exists("log") && !is_dir("log")) mkdir("log", 0777);
if (!file_exists($file)) file_put_contents($file, "");

$ipdate = @file($file);
$str = "";
$yesno = true;

foreach ($ipdate as $v) {
    $iptem = substr($v, 0, 32);
    $uritem = substr($v, 32, 32);
    $timetem = substr($v, 64, 10);
    $numtem = substr($v, 74);

    if ($time - $timetem < $allowTime) {
        if ($iptem != $checkip) {
            $str .= $v; // 保留其他 IP 記錄
        } else {
            $yesno = false;
            if ($uritem != $checkuri) {
                $str .= $iptem . $checkuri . $time . "1\r\n";
            } elseif ($numtem < $allowNum) {
                $str .= $iptem . $uritem . $timetem . ($numtem + 1) . "\r\n";
            } else {
                // 觸發封禁流程
                if (!file_exists($fileforbid)) {
                    $addforbidarr = array($ip . "\r\n", time() . "\r\n", 1);
                    file_put_contents($fileforbid, $addforbidarr);
                }
                file_put_contents("log/forbided_ip.log", $ip . "--" . date("Y-m-d H:i:s", $time) . "--" . $uri . "\r\n", FILE_APPEND);
                $timepass = $timetem + $allowTime - $time;
                die("Warning: Don't refresh too frequently. Wait {$timepass} seconds.");
            }
        }
    }
}

if ($yesno) $str .= $checkip . $checkuri . $time . "1\r\n";
file_put_contents($file, $str);
?>

部署建議

  1. 將程式碼置於網站入口檔案(如 index.php)最頂端
  2. 確保 log/ 目錄可寫入(權限 0777)
  3. 根據業務特性調整 $allowTime、$allowNum 參數
  4. 定期清理 log/forbided_ip.log 避免檔案過大

實測成果

部署新版本後連續測試兩天,成功攔截 62 個新攻擊 IP(多為土耳其),100% 精準識別攻擊行為,零誤殺正常用戶。

此程式碼僅供參考,實際部署需因地制宜調整參數。核心思想:時間窗口 + 頻率閾值 + 漸進式封禁,兼顧防護效果與用戶體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved