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

PHP 防 CC 攻擊與限制頁面刷新頻率

     編輯:PHP 相關知識

簡單的 Session 限流可緩解小規模 CC 攻擊 (HTTP Flood) 與惡意快速重新整理。本文提供基礎防護代碼,並說明其局限性與生產環境建議架構。

基礎 Session 限流實作

<?php
// 1. 阻擋代理 IP (可選,易誤傷企業用戶)
if (!empty($_SERVER['HTTP_VIA']) || !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    // exit('Access Denied: Proxy detected'); // 建議改為記錄日誌而非直接阻擋
}

// 2. Session 限流核心
session_start();

$windowSeconds = 3;   // 時間窗 (秒)
$maxRequests   = 5;   // 最大請求數

$now = time();
$key = 'ratelimit_' . md5($_SERVER['REQUEST_URI'] ?? 'global');

if (!isset($_SESSION[$key])) {
    $_SESSION[$key] = ['count' => 1, 'start' => $now];
} else {
    $data = &$_SESSION[$key];
    if ($now - $data['start'] < $windowSeconds) {
        $data['count']++;
        if ($data['count'] > $maxRequests) {
            // 觸發限流
            http_response_code(429);
            header('Retry-After: ' . $windowSeconds);
            exit('請求過於頻繁,請稍後再試 (429 Too Many Requests)');
        }
    } else {
        // 窗口重置
        $data['count'] = 1;
        $data['start'] = $now;
    }
}

// 正常業務邏輯繼續...
echo "請求通過";

進階:多層級限流策略

class RateLimiter {
    private $redis;
    private $limits = [
        'global'    => [100, 60],    // 100 req/min 全站
        'ip'        => [30, 60],     // 30 req/min 單 IP
        'user'      => [60, 60],     // 60 req/min 登入用戶
        'endpoint'  => [10, 10],     // 10 req/10s 特定端點
        'login'     => [5, 300],     // 5 req/5min 登入端點
    ];
    
    public function __construct(Redis $redis) { $this->redis = $redis; }
    
    public function check(string $scope, string $id): bool {
        [$max, $window] = $this->limits[$scope] ?? [100, 60];
        $key = "ratelimit:$scope:$id";
        
        $pipe = $this->redis->multi();
        $pipe->incr($key);
        $pipe->expire($key, $window);
        $results = $pipe->exec();
        
        $current = $results[0];
        if ($current > $max) {
            $ttl = $this->redis->ttl($key);
            throw new RateLimitExceededException($scope, $max, $window, $ttl);
        }
        return true;
    }
}

// 使用
$limiter = new RateLimiter($redis);
try {
    $limiter->check('ip', $_SERVER['REMOTE_ADDR']);
    $limiter->check('endpoint', $_SERVER['REQUEST_URI']);
    // 通過
} catch (RateLimitExceededException $e) {
    http_response_code(429);
    header("Retry-After: {$e->ttl}");
    exit(json_encode(['error' => 'rate_limited', 'retry_after' => $e->ttl]));
}

生產環境建議架構

層級工具/位置特點
邊緣/雲端Cloudflare WAF, AWS Shield, Alibaba Cloud Anti-DDoS吸收大流量攻擊、隱藏源站 IP、零程式碼改動
負載均衡器Nginx limit_req_module, HAProxy stick-table高效能、共享記憶體、支援漏桶/令牌桶
應用層Redis + Lua 腳本 / PHP 中介軟體精細業務邏輯、分散式一致、可自訂回應
資料庫連線池限制、查詢超時防止資源耗盡

Nginx limit_req 範例 (推薦前置層)

# nginx.conf http 區塊
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;

server {
    location /api/ {
        limit_req zone=api burst=20 nodelay;
        limit_req_status 429;
        proxy_pass https://php_upstream;
    }
    location /login {
        limit_req zone=login burst=3 nodelay;
        limit_req_status 429;
    }
}

Session 限流的缺陷與風險

  • ❌ Session 檔案鎖競爭:高併發下 session_start() 會阻塞,反而加劇延遲。
  • ❌ 無法跨伺服器:多機部署需共享 Session (Redis/Memcached),增加複雜度。
  • ❌ 易繞過:攻擊者可清除 Cookie、換 IP、使用無頭瀏覽器。
  • ❌ 誤傷正常用戶:企業 NAT、公共 WiFi 共用 IP 易觸發限制。

最佳實踐總結

  1. 雲端 WAF 為第一道防線,吸收 99% 體積攻擊。
  2. Nginx limit_req 為第二道,低延遲、高吞吐、共享記憶體。
  3. 應用層 Redis 限流為精細控制,針對登入、API、付費端點差異化策略。
  4. 監控與告警:記錄 429 回應、IP 信譽、流量基線,自動封鎖異常源。
  5. 優雅降級:限流時回傳 JSON + Retry-After,前端顯示倒數計時,避免使用者以為當機。

單純 PHP Session 限流僅適合極小型專案或臨時緩解,正式上線請採用多層防護體系。

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