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

ASP.NET 獲取真實客戶端 IP 完整指南:6 種方法、代理穿透、雲端負載均衡器適用方案

     編輯:ASP.NET 基礎

核心挑戰:代理/負載均衡器隱藏真實 IP

請求鏈路:`Client → [Proxy/CDN/WAF] → Load Balancer → Web Server`。每一層都可能插入/覆蓋 `X-Forwarded-For`、`X-Real-IP`、`True-Client-IP` 等標頭。伺服器端 `Request.UserHostAddress` 僅見**直接上游 IP** (通常為 LB 內網 IP)。

方法對照表

方法程式碼適用場景可信度
1. 直接屬性`Request.UserHostAddress`無代理、內網直連★☆☆☆☆ (見上游 IP)
2. ServerVariables`Request.ServerVariables["REMOTE_ADDR"]`同方法 1★☆☆☆☆
3. DNS 反查 (錯誤示範)`Dns.GetHostAddresses(Dns.GetHostName())`**錯誤**:取得伺服器自身 IP,非客戶端✖️
4. X-Forwarded-For (標準)`Request.ServerVariables["HTTP_X_FORWARDED_FOR"]`單層代理、信任代理標頭★★★☆☆ (需驗證代理可信)
5. 客戶端 JS 回傳`var ip = '';` (SSI) 或 AJAX 送 `/api/myip`頁面嵌入、需 JS 執行★★☆☆☆ (可被偽造)
6. ActiveX (舊 IE 專用)`new ActiveXObject("rcbdyctl.Setting").GetIPAddress`極舊環境✖️ (已淘汰)

生產級最佳實踐:可信代理鏈驗證


public static class ClientIpResolver
{
    // 可信代理 IP 範圍 (CIDR),例如雲端 LB、公司 Proxy、CDN 邊緣節點
    private static readonly string[] TrustedProxyCidrs = 
    {
        "10.0.0.0/8",      // 內網
        "172.16.0.0/12",   // 內網
        "192.168.0.0/16",  // 內網
        "100.64.0.0/10",   // CGNAT / AWS ALB
        // 加入具體 CDN/LB IP 範圍 (如 Cloudflare: 173.245.48.0/20 ...)
    };

    private static readonly IPNetwork[] _trustedNetworks = 
        TrustedProxyCidrs.Select(c => IPNetwork.Parse(c)).ToArray();

    public static string GetClientIp(HttpRequest request)
    {
        // 1. 取得直接連線 IP
        string remoteIp = request.UserHostAddress; // 或 request.ServerVariables["REMOTE_ADDR"]

        // 2. 若直接 IP 不在可信代理清單 → 視為真實客戶端 (無代理或不可信代理)
        if (!_trustedNetworks.Any(n => n.Contains(IPAddress.Parse(remoteIp))))
            return remoteIp;

        // 3. 直接 IP 為可信代理 → 解析 X-Forwarded-For
        string xff = request.Headers["X-Forwarded-For"] 
                   ?? request.ServerVariables["HTTP_X_FORWARDED_FOR"];

        if (string.IsNullOrWhiteSpace(xff))
            return remoteIp; // 代理未傳標頭,回退

        // 4. XFF 格式: "client, proxy1, proxy2" (最左為原始客戶端)
        // 從右向左跳過可信代理,第一個不可信即為真實客戶端
        var ips = xff.Split(',').Select(s => s.Trim()).ToArray();
        for (int i = ips.Length - 1; i >= 0; i--)
        {
            if (IPAddress.TryParse(ips[i], out var ip) && !_trustedNetworks.Any(n => n.Contains(ip)))
                return ips[i];
        }

        // 5. 全鏈路皆可信 (極罕見) → 取最左
        return ips.FirstOrDefault() ?? remoteIp;
    }
}

// 輔助:CIDR 判斷 (需引用 System.Net.IPNetwork 或自行實作)
public class IPNetwork
{
    public IPAddress NetworkAddress { get; }
    public int PrefixLength { get; }
    public static IPNetwork Parse(string cidr) { /* 解析網址/前綴長度 */ }
    public bool Contains(IPAddress address) { /* 位元運算判斷 */ }
}

雲端平台專屬標頭

平台標頭備註
AWS ALB / CloudFront`X-Forwarded-For` (標準)、`X-Amzn-Trace-Id`ALB 固定加在最右,CloudFront 在最左
Azure Front Door / App Gateway`X-Forwarded-For`、`X-Azure-ClientIP``X-Azure-ClientIP` 為 Azure 專屬真實 IP
Google Cloud Load Balancing`X-Forwarded-For`、`X-Cloud-Trace-Context`
Cloudflare`CF-Connecting-IP` (真實 IP)、`X-Forwarded-For``CF-Connecting-IP` 最可信,僅 Cloudflare 設定
Akamai`True-Client-IP`、`X-Forwarded-For``True-Client-IP` 為 Akamai 專屬
Nginx/HAProxy (自建)`X-Real-IP` (單一)、`X-Forwarded-For` (鏈)需在設定 `proxy_set_header X-Real-IP $remote_addr;`

ASP.NET Core 現代寫法 (ForwardedHeadersMiddleware)


// Program.cs / Startup.cs
services.Configure(options =>
{
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    // 必須明確加入已知代理網段,否則中間件會忽略標頭 (安全預設)
    options.KnownNetworks.Clear();
    options.KnownProxies.Clear();
    foreach (var cidr in ClientIpResolver.TrustedProxyCidrs)
        options.KnownNetworks.Add(IPNetwork.Parse(cidr));
});

app.UseForwardedHeaders(); // 必須在 UseAuthentication/UseAuthorization 之前

// Controller 中
string clientIp = HttpContext.Connection.RemoteIpAddress?.ToString(); // 已自動解析 XFF

安全警示

  • **不可盲信 `X-Forwarded-For`** — 攻擊者可偽造標頭繞過 IP 封鎖/限流。
  • **必須維護可信代理 IP 清單** (CIDR),隨基礎設施變更更新。
  • **日誌記錄雙 IP**:`真實客戶端 IP (解析後)` + `直接上游 IP (REMOTE_ADDR)`,便於審計追蹤。
  • **GDPR/隱私法規**:IP 屬個人資料,需告知、最小化保留、加密儲存。

總結

**無代理**:`Request.UserHostAddress` 即可。
**單層可信代理**:`Request.Headers["X-Forwarded-For"]` 取最左。
**多層/雲端/混合**:**部署 `ForwardedHeadersMiddleware` (Core) 或自寫 `ClientIpResolver` (Framework),配合可信 CIDR 清單從右向左解析 XFF**。
**客戶端 JS/ActiveX 方案已淘汰**,不可用於安全決策。統一全站 HTTPS + 標頭驗證,才是正道。

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