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

防止網站被惡意反向代理/鏡像:多層次防護策略與代碼實現

     編輯:PHP 綜合知識

前言:理解反向代理與鏡像站的威脅

正向代理:客戶端主動配置,代理替用戶訪問目標站(如 VPN、科學上網)。
反向代理:服務端部署,對外隱藏真實後端(如 Nginx 反代、CDN、負載均衡)。
惡意反向代理/鏡像:攻擊者在自己的域名下配置反向代理指向你的站點,用戶訪問攻擊者域名時,實際內容來自你的服務器,但攻擊者可:

  • 竊取流量、SEO 權重(搜索引擎可能收錄鏡像站導致降權)
  • 注入廣告、挖礦腳本、釣魚表單
  • 替換聯盟廣告 ID 導致賬號封禁
  • 繞過你的 WAF/限流/認證機制

防護層級總覽

層級方案優點缺點推薦指數
應用層 (PHP)校驗 $_SERVER['HTTP_HOST'] / SERVER_NAME邏輯靈活、可記錄日誌、可返回 JSON 錯誤需 PHP 執行、性能稍低⭐⭐⭐⭐⭐
Web Server (Nginx/Apache)拒絕非法 Host、limit_req、geo 模組極高性能、攔截最早、不佔 PHP 進程配置相對複雜、調試較難⭐⭐⭐⭐⭐
客戶端 (JavaScript)檢查 document.domain / top.location零服務端成本、可破 iframe 嵌套可被禁用/繞過、對 SEO 無效⭐⭐⭐
DNS/邊緣Cloudflare/CloudFront 設定允許 Host、WAF 規則流量進入前攔截、隱藏源站 IP需付費/配置、非自建環境適用⭐⭐⭐⭐

方案一:PHP 應用層校驗(核心防線)

在公共入口文件(如 public/index.php)或中間件最早處執行:

<?php
// config/allowed_hosts.php
return [
    'example.com',
    'www.example.com',
    'api.example.com',
    // 內網/健康檢查 IP 可選
    '10.0.0.5',
    '127.0.0.1',
];

// bootstrap/app.php 或 public/index.php 最頂部
$allowedHosts = require __DIR__ . '/../config/allowed_hosts.php';

// 獲取真實 Host(考慮反代頭)
$host = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? '';
// 移除端口號
$host = preg_replace('/:\d+$/', '', $host);

if (!in_array($host, $allowedHosts, true)) {
    // 記錄攻擊日誌
    error_log(sprintf(
        "[MIRROR_BLOCK] IP=%s Host=%s UA=%s URI=%s Time=%s",
        $_SERVER['REMOTE_ADDR'] ?? 'unknown',
        $host,
        $_SERVER['HTTP_USER_AGENT'] ?? 'unknown',
        $_SERVER['REQUEST_URI'] ?? '/',
        date('c')
    ));

    // 根據請求類型返回不同響應
    if (str_starts_with($_SERVER['REQUEST_URI'] ?? '', '/api/')) {
        http_response_code(403);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode(['error' => 'Forbidden: Invalid host', 'code' => 403]);
    } else {
        http_response_code(403);
        header('Content-Type: text/html; charset=utf-8');
        echo '<!DOCTYPE html><html><head><meta charset="utf-8"><title>403 Forbidden</title></head><body>';
        echo '<h1>403 - 非法訪問</h1><p>請通過官方域名訪問本站。</p>';
        echo '</body></html>';
    }
    exit;
}
// 繼續正常啟動框架...
?>

進階:支援通配子域名

function isHostAllowed(string $host, array $allowedPatterns): bool {
    foreach ($allowedPatterns as $pattern) {
        // 精確匹配
        if ($pattern === $host) return true;
        // 通配子域名 *.example.com
        if (str_starts_with($pattern, '*.')) {
            $suffix = substr($pattern, 1); // .example.com
            if (str_ends_with($host, $suffix)) return true;
        }
        // 正則匹配(謹慎使用)
        if (str_starts_with($pattern, '/') && str_ends_with($pattern, '/')) {
            if (preg_match($pattern, $host)) return true;
        }
    }
    return false;
}

$allowedPatterns = [
    'example.com',
    'www.example.com',
    '*.example.com',           // 所有子域名
    '/^api-\d+\.example\.com$/', // 正則
];
?>

方案二:Nginx 層級攔截(最高性能)

# nginx.conf / site.conf
server {
    listen 80;
    listen 443 ssl;
    server_name example.com www.example.com; # 僅響應合法域名

    # 關鍵:拒絕非法 Host(包括直接訪問 IP)
    if ($host !~* ^(example\.com|www\.example\.com|api\.example\.com)$) {
        return 444; # Nginx 特有:直接斷開連接,不返回任何響應
    }

    # 可選:限制單 IP 請求頻率防采集
    limit_req_zone $binary_remote_addr zone=mirror:10m rate=30r/s;
    limit_req zone=mirror burst=50 nodelay;

    location / {
        proxy_pass https://php_upstream;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

# 另開一個 server 捕獲所有非法 Host(可選,用於記錄日誌)
server {
    listen 80 default_server;
    listen 443 ssl default_server;
    server_name _;
    ssl_certificate /path/selfsigned.crt;
    ssl_certificate_key /path/selfsigned.key;
    return 444;
}

方案三:Apache .htaccess / httpd.conf

# .htaccess (需開啟 AllowOverride All)
RewriteEngine On
# 僅允許合法域名
RewriteCond %{HTTP_HOST} !^(example\.com|www\.example\.com|api\.example\.com)$ [NC]
RewriteRule ^ - [F,L]  # 返回 403

# 或重導向到官方域名(保留路徑)
# RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
# RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]

方案四:JavaScript 客戶端輔助(破 iframe/鏡像頁面跳轉)

<script>
// 1. 防止被 iframe 嵌套
if (window.top !== window.self) {
    window.top.location = window.self.location;
}

// 2. 檢查域名是否為官方域名(配合 PHP 雙重保險)
(function() {
    var allowed = ['example.com', 'www.example.com', 'api.example.com'];
    var hostname = window.location.hostname.replace(/:\d+$/, ''); // 去端口
    if (!allowed.includes(hostname) && !hostname.endsWith('.example.com')) {
        // 延遲跳轉避免被鏡像站 JS 攔截
        setTimeout(function() {
            window.location.href = 'https://www.example.com' + window.location.pathname + window.location.search;
        }, 100);
    }
})();
</script>

方案五:利用 HTTP 標頭增強防護

在 Nginx/PHP 統一輸出以下安全標頭:

# 防止被 iframe 嵌套(現代瀏覽器支援)
add_header X-Frame-Options "DENY" always;
# 或更靈活的 CSP frame-ancestors
add_header Content-Security-Policy "frame-ancestors 'none';" always;

# 防 MIME 類型嗅探
add_header X-Content-Type-Options "nosniff" always;

# 強制 HTTPS(HSTS)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

關鍵注意事項與最佳實踐

  1. 獲取真實 Host:反代鏈路中 $_SERVER['HTTP_HOST'] 可能被竄改,建議在 Nginx 設定 proxy_set_header Host $host; 並信任 X-Forwarded-Host(需配置 set_real_ip_from)。
  2. 健康檢查/內網監控:負載均衡器健康檢查通常用 IP 直接訪問,務必在白名單加入 LB IP 或內網 IP 段,否則會誤殺導致節點被踢出集群。
  3. CDN 回源 Host:CDN 回源時 Host 可能為源站域名或 CDN 節點域名,需在白名單包含 CDN 回源 Host(查看 CDN 文檔或日誌分析)。
  4. 不要只靠 JS:搜索引擎爬蟲不執行 JS,SEO 降權無法靠 JS 防禦;攻擊者可直接過濾/修改返回的 HTML 移除 JS 代碼。
  5. 記錄與告警:記錄非法 Host 訪問的 IP、UA、頻率,接入日誌分析系統(ELK/Loki)設置告警,及時發現大規模鏡像攻擊。
  6. 源站 IP 隱藏:配合 Cloudflare/Shield/高防 CDN 隱藏真實源站 IP,攻擊者無法直接繞過邊緣防護訪問源站。

總結:分層防禦體系

┌─────────────────────────────────────┐
│  DNS/邊緣層 (Cloudflare/WAF)        │  ← 首選:隱藏源站、預置規則攔截
├─────────────────────────────────────┤
│  Web Server 層 (Nginx/Apache)       │  ← 核心:高性能 Host 白名單、444 斷連
├─────────────────────────────────────┤
│  應用層                             │  ← 兜底:邏輯靈活、記錄詳盡、API 友好
├─────────────────────────────────────┤
│  客戶端層                           │  ← 輔助:破 iframe、用戶端跳轉
└─────────────────────────────────────┘

採用 Nginx 白名單 + PHP 兜底 + 安全標頭 + 可選 JS 的組合拳,可將惡意鏡像站的生存空間壓縮至最小,保護流量、SEO 與用戶安全。

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