Nginx 如何設定
情況1
在只有1層nginx代理的情況下,設定nginx配置“proxy_set_header X-Forwarded-For $remote_addr;”。(此時$remote_addr獲取的是使用者的真是ip)
情況2
在有多層反向代理的情況下,
1)設定“最外層”nginx配置和情況1一樣“proxy_set_header X-Forwarded-For $remote_addr;”。
2)除了“最外層”之外的nginx配置“proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;”。
注意
如果你的 nginx 使用了 http_realip_module 模組,那麼必須再配置一下受信任的cdn、nginx節點,否則 nginx 會認為X-Forwarded-For的內容都是可靠的,無法識別別人偽造的 X-Forwarded-For 頭。
proxy_pass http://8.2.158.1:11029;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
set_real_ip_from 8.168.31.5;
set_real_ip_from 8.168.31.6;
set_real_ip_from 16.18.22.0/24;
8.168.31.5、8.168.31.6、16.18.22.*網段 是cdn的ip地址,告訴 nginx 可以信任
Asp.Net 獲取客戶端真實ip
編寫一個靜態方法:
public static string GetRemoteIpAddress(HttpContext httpContext, string[] trustXForwardedFor)
{
var remoteIpAddr = httpContext.Connection.RemoteIpAddress.ToString();
if (trustXForwardedFor != null && trustXForwardedFor.Length > 0 && httpContext.Request.Headers.TryGetValue("X-Forwarded-For", out StringValues x_for))
{
var x_forArr = x_for.ToString().Split(',').Select(m => m.Trim()).Where(m => m.Length > 0).ToArray();
if (trustXForwardedFor.Contains(remoteIpAddr))
{
for (int i = x_forArr.Length - 1; i >= 0; i--)
{
var ip = x_forArr[i];
if (trustXForwardedFor.Contains(ip) == false)
return ip;
}
}
else
{
return remoteIpAddr;
}
}
return remoteIpAddr;
}
然後在controller內部呼叫:
GetRemoteIpAddress(this.HttpContext, new string[] { "127.0.0.1", "::ffff:127.0.0.1", "172.19.149.142" })
"127.0.0.1", "::ffff:127.0.0.1", "172.19.149.142" 這是指定3個被排除的反向代理以及cdn的ip , 如果不傳這些ip,那就表示伺服器那邊沒有部署nginx這型別的反向代理服務,也沒有使用cdn。
JMSFramework 微服務獲取客戶端真實ip
JMS 的 controller 自身就包含 GetRemoteIpAddress 方法,在controller 裡面直接呼叫即可。
this.GetRemoteIpAddress(new string[] { "127.0.0.1", "::ffff:127.0.0.1", "172.19.149.142" });