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

PHP 精準封鎖 IP 與 IP 段:從單個禁止到 CIDR 範圍匹配的完整方案

     編輯:PHP 相關知識

場景痛點

面對惡意刷單、爬蟲騷擾或特定區域合規需求,開發者常需在 PHP 層面實現:

  • 禁止單一 IP 訪問/提交表單
  • 封鎖整個 IP 段(如 192.168.0.0/16)
  • 支援代理頭(X-Forwarded-For、Client-IP)獲取真實客戶端 IP

核心工具函數:穩健獲取客戶端 IP

function getRealIp(): string {
    $headers = [
        'HTTP_CLIENT_IP',
        'HTTP_X_FORWARDED_FOR',
        'REMOTE_ADDR'
    ];
    foreach ($headers as $header) {
        $val = getenv($header) ?: ($_SERVER[$header] ?? '');
        if ($val && strcasecmp($val, 'unknown') !== 0) {
            // X-Forwarded-For 可能包含多個 IP,取第一個非未知
            $ips = array_map('trim', explode(',', $val));
            foreach ($ips as $ip) {
                if (filter_var($ip, FILTER_VALIDATE_IP)) return $ip;
            }
        }
    }
    return '127.0.0.1'; // fallback
}

方案一:精確匹配單個 IP

$blockedIps = ['192.168.1.88', '10.0.0.5'];
if (in_array(getRealIp(), $blockedIps)) {
    header('HTTP/1.1 403 Forbidden');
    exit('Access Denied');
}

方案二:CIDR 範圍封鎖(推薦)

使用 ip2long 與位運算判斷 IP 是否落在 CIDR 區間,支援 IPv4:

function ipInCidr(string $ip, string $cidr): bool {
    [$range, $netmask] = explode('/', $cidr);
    $mask = ~((1 << (32 - $netmask)) - 1);
    return (ip2long($ip) & $mask) === (ip2long($range) & $mask);
}

// 使用示例
$blockedCidrs = ['192.168.0.0/16', '10.0.0.0/8', '172.16.0.0/12'];
$clientIp = getRealIp();
foreach ($blockedCidrs as $cidr) {
    if (ipInCidr($clientIp, $cidr)) {
        header('Location: https://example.com/blocked.html');
        exit;
    }
}

方案三:簡易陣列比對(適用於固定前綴)

若無需完整 CIDR,僅匹配前綴(如 192.168.*.*),可拆分八位組比對:

$ipSeg = explode('.', getRealIp());
if ($ipSeg[0] === '192' && $ipSeg[1] === '168') {
    // 屬於 192.168.0.0/16
    header('HTTP/1.1 403 Forbidden');
    exit;
}

進階建議

  • 將封鎖名單存入 Redis/資料庫,支援動態熱更新,無需重啟服務。
  • 結合 Middleware(Laravel/Slim/ThinkPHP 中間件)統一攔截,避免業務代碼耦合。
  • 記錄被封鎖請求日誌(IP、UA、URL、時間),便於事後分析誤封情況。
  • 注意:X-Forwarded-For 可偽造,高安全場景需結合可信代理鏈驗證。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved