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

PHP 限制 IP 存取與防表單惡意提交:IP 區段封鎖實作

     編輯:PHP 綜合知識

基於 IP 的存取控制是基礎安全手段,可封鎖特定 IP、IP 區段 (CIDR) 或僅允許白名單。本文提供完整實作代碼,支援 IPv4 區段判斷。

核心功能:取得真實客戶端 IP

function getClientIP() {
    $headers = [
        'HTTP_CLIENT_IP',
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_FORWARDED',
        'HTTP_X_CLUSTER_CLIENT_IP',
        'HTTP_FORWARDED_FOR',
        'HTTP_FORWARDED',
        'REMOTE_ADDR'
    ];
    
    foreach ($headers as $header) {
        if (!empty($_SERVER[$header])) {
            $ips = explode(',', $_SERVER[$header]);
            $ip = trim($ips[0]); // 取第一個 (最接近客戶端)
            if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                return $ip;
            }
        }
    }
    return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}

IP 區段判斷 (CIDR 表示法)

function ipInRange($ip, $cidr) {
    list($range, $netmask) = explode('/', $cidr, 2);
    $rangeDec = ip2long($range);
    $ipDec = ip2long($ip);
    $maskDec = ~((1 << (32 - $netmask)) - 1);
    return ($ipDec & $maskDec) === ($rangeDec & $maskDec);
}

// 使用範例
$blockedRanges = ['192.168.1.0/24', '10.0.0.0/8', '172.16.0.0/12'];
$clientIP = getClientIP();

foreach ($blockedRanges as $range) {
    if (ipInRange($clientIP, $range)) {
        header('Location: https://example.com/blocked.html');
        exit;
    }
}

完整防護腳本 (可直接 include)

 ['192.168.1.88'],           // 單一 IP
    'blocked_ranges' => ['192.168.1.0/24'],      // CIDR 區段
    'allowed_ips' => [],                         // 白名單 (空=不限制)
    'redirect_url' => 'https://example.com/403.html',
];

$clientIP = getClientIP();

// 白名單優先
if (!empty($config['allowed_ips'])) {
    $allowed = false;
    foreach ($config['allowed_ips'] as $allow) {
        if (strpos($allow, '/') !== false) {
            if (ipInRange($clientIP, $allow)) { $allowed = true; break; }
        } elseif ($clientIP === $allow) {
            $allowed = true; break;
        }
    }
    if (!$allowed) { redirectBlock(); }
}

// 黑名單檢查
foreach ($config['blocked_ips'] as $ip) {
    if ($clientIP === $ip) { redirectBlock(); }
}
foreach ($config['blocked_ranges'] as $range) {
    if (ipInRange($clientIP, $range)) { redirectBlock(); }
}

function redirectBlock() {
    global $config;
    header('Location: ' . $config['redirect_url']);
    exit;
}

function getClientIP() { /* 同上 */ }
function ipInRange($ip, $cidr) { /* 同上 */ }
?>

進階:表單提交專用 Token + IP 綁定

// 產生表單 Token
function generateFormToken() {
    $token = bin2hex(random_bytes(32));
    $_SESSION['form_tokens'][$token] = [
        'ip' => getClientIP(),
        'time' => time(),
        'used' => false
    ];
    // 清理過期 token (超過 1 小時)
    foreach ($_SESSION['form_tokens'] as $k => $v) {
        if (time() - $v['time'] > 3600) unset($_SESSION['form_tokens'][$k]);
    }
    return $token;
}

// 驗證表單 Token
function verifyFormToken($token) {
    if (empty($_SESSION['form_tokens'][$token])) return false;
    $data = $_SESSION['form_tokens'][$token];
    if ($data['used']) return false; // 防重放
    if ($data['ip'] !== getClientIP()) return false; // IP 綁定
    if (time() - $data['time'] > 3600) return false; // 過期
    $_SESSION['form_tokens'][$token]['used'] = true;
    return true;
}

部署建議

層級建議位置優點
Web ServerNginx deny 192.168.1.0/24; / Apache Require not ip 192.168.1效能最好、PHP 不啟動
PHP 入口auto_prepend_file 或框架中介層全域生效、易維護
應用業務敏感 Controller (登入、付款、刪除)精細控制、結合業務邏輯

注意:IP 可偽造 (代理、VPN、Tor)、NAT 環境下多用戶共用 IP。IP 封鎖僅為輔助手段,**核心安全仍須依賴認證授權、CSRF Token、速率限制、行為分析** 等多層防護。

此實作提供可直接部署的 IP 區段封鎖與表單 Token 綁定機制,適合快速整合至現有 PHP 專案。

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