ASP.NET Request.ServerVariables gives local IP, not remote IP
Got an asp.net webpage in C #. One thing we would like to do is track hits on the site, including their IP address. I have implemented some code (thanks to SO) but the registered IP always seems to be local, ie: 192.168.xx I tried it from different devices, even my phone and MiFi version to make sure it is not something weird with the ISP but the log always lists the same 2-3 different internal IPs (seems to change a bit as the day goes on).
Here is my function that gets the IP (again thanks to posts here on SO):
protected IPAddress GetIp(HttpRequest request)
{
string ipString;
if (string.IsNullOrEmpty(request.ServerVariables["HTTP_X_FORWARDED_FOR"]))
ipString = request.ServerVariables["REMOTE_ADDR"];
else
ipString = request.ServerVariables["HTTP_X_FORWARDED_FOR"].Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
IPAddress result;
if (!IPAddress.TryParse(ipString, out result))
result = IPAddress.None;
return result;
}
public void logHit()
{
IPAddress ip = GetIp(Request);
string sIP = ip.ToString();
}
I tried this too, which gives the same result:
HttpContext.Current.Request.UserHostAddress;
When I make a client side call using something like a service on appspot it works fine:
<script type="application/javascript">
function getip(json) {
//txtIP is a input box on the form
document.getElementById("txtIP").value = json.ip;
}
</script>
<script type="application/javascript" src="http://jsonip.appspot.com/?callback=getip"></script>
I guess I could make a round by hitting that appspot link and parsing it, but that looks like a ton of annoyance for something that should be simple.
Could it be IIS on the server? Is there some kind of redirection going on? Registered IP addresses are NOT servers. The problem is I don't have direct access to it, so I have to talk to the guys who administer it and would like to give them some direction before they start changing.
thank
Ernie
source to share
It depends on the structure of your network. It's just that a firewall or load balancer can change the variables you check.
if you are using a load balancer check this: How to get visitor IP on load balancer machine using asp.net
if your server is behind a firewall check this: Find if the request was sent from the firewall to IIS .
source to share
If the HTTP_X_FORWARDED_FOR header is indeed supported, then I think it won't be either a forward or reverse proxy causing this, but more likely dynamic network address translation or dynamic port address translation that happens below the application layer to TCP / IP and, therefore, will not affect the HTTP request header.
There are many ways to configure NAT, most of which will not cause these symptoms, but it is certainly possible to configure NAT to present a problem. Dynamic NAT or Dynamic PAT would be two such examples, and I would guess that this is what you ask your network admins.
You can read more about dynamic NAT / PAT with good examples: http://www.cisco.com/en/US/docs/security/asa/asa82/configuration/guide/nat_dynamic.html
In a typical NAT scenario, request packets reach the NAT device (firewall or router) as: OT - 5.5.5.5 (client public address) TO - 6.6.6.6 (server public address)
A "typical" NAT configuration would only rewrite the destination as follows: FROM - 5.5.5.5 TO - 192.168.6.6 (server private address)
In this typical case, the server will still see REMOTE_ADDR as 5.5.5.5, since that is the source address of the incoming request. Then the packages will be returned in 5.5.5.5 and the response will get back to the client successfully.
Now, in the case of dynamic PAT, for example, the request will reach the NAT device as follows: OT - 5.5.5.5 TO - 6.6.6.6
The NAT device will then rewrite both source and destination packets, maintaining this "dynamic" mapping only for the lifetime of the request: FROM - 192.168.1.1:12345 (dynamic PAT) TO - 192.168.6.6 (private server address)
Now when the server sees this request, it looks from the private address 192.168.1.1. In fact, with strict PAT, all requests will appear from this address. In your case, there are 2 or 3 of these addresses, perhaps because you may have enough traffic that you run the risk of running out of ports if you only use one dynamic PAT address.
So your REMOTE_ADDR is 192.168.1.1 because it is actually the source address in the request packets. There is no HTTP_X_FORWARDED_FOR as the dynamic PAT happens at the lower TCP / IP level (address, not application).
Finally, the response is sent back to 192.168.1.1:12345, which is directed to the NAT device, which maps it back to 5.5.5.5 for the duration of the request / response (see Cisco documentation above) and then resets the "dynamic" mapping.
Everything works fine, the client gets a response back, except that you are not presenting the client's actual address from the server's point of view. And if it is dynamic NAT in the game, I don't see how you could get this information from the server.
Luckily, you did exactly that to get the information in javascript on the client, so this probably solves your problem and it can also be solved.
source to share