11

I collect statistics on IP addresses from where users visit my site and I have noticed what there are only two IP addresses presented, 172.16.16.1 and 172.16.16.248. The property I use to determine IP address is

Request.UserHostAddress

What could be a reason of IP address information losing? All the users are from around the world, so they cann't be behind only two proxies.

Tomalak
  • 332,285
  • 67
  • 532
  • 628
Alexander Prokofyev
  • 33,874
  • 33
  • 95
  • 118

7 Answers7

27

You might want to something like this;

string SourceIP = String.IsNullOrEmpty(Request.ServerVariables["HTTP_X_FORWARDED_FOR"]) ? Request.ServerVariables["REMOTE_ADDR"] : Request.ServerVariables["HTTP_X_FORWARDED_FOR"].Split(",")[0];

The HTTP_X_FORWARDED_FOR header gets the IP address behind proxy servers.

See this page that explains why in more detail; Getting The Real IP of your Users

Jon Limjap
  • 94,284
  • 15
  • 101
  • 152
Dave Anderson
  • 11,836
  • 3
  • 58
  • 79
  • I know about HTTP_X_FORWARDED_FOR header, but I am more interested in reasons of the problem. Thanks anyway! – Alexander Prokofyev Oct 15 '08 at 05:20
  • 5
    Beware that chained proxies can lead to several HTTP_X_FORWARDED_FOR headers. – Marc Climent May 21 '10 at 10:46
  • @Marc Climent: Could you add a new answer to this question that accounts for that? I'd like to see how that works. Would `Request.ServerVariables["HTTP_X_FORWARDED_FOR"]` return a delimited string of IPs, or would it just return the first/last header? – MikeWyatt Oct 07 '11 at 15:17
  • @MikeWyatt Check out this question: http://stackoverflow.com/questions/753645/how-do-i-get-the-correct-ip-from-http-x-forwarded-for-if-it-contains-multiple-ip – Marc Climent Oct 08 '11 at 13:12
  • 1
    @MarcCliment have added split to get first comma separated value – Dave Anderson Sep 16 '15 at 00:35
10

This looks like the work of a reverse proxy. When you use a reverse proxy, the client connects to the proxy, which itself opens a new connection to your server. Since ASP.NET uses the infos of the incoming connection to fill the user address, you get the address of the reverse proxy.

If you are indeed in this configuration, you'll need help from the reverse proxy to get the right information. Most reverse proxies offer the possibility to add a header to the HTTP request, with the real IP address of the client. Check the documentation of your proxy.

Mathieu Garstecki
  • 1,589
  • 1
  • 13
  • 18
6

Building on Dave Anderson's answer, here is a snippet that takes into account a chain of reverse proxies.

string forwardedFor = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

string ipStr = string.IsNullOrWhiteSpace(forwardedFor) 
                   ? Request.ServerVariables["REMOTE_ADDR"] 
                   : forwardedFor.Split(',').Select(s => s.Trim()).First();
tomfanning
  • 9,552
  • 4
  • 50
  • 78
1

Request.ServerVariables("REMOTE_ADDR") isn't work. this problem is because ur server is probably behind some proxy.(or connected to internet via some network) or your router settings are set as NAT (Network Address Translation) this technique doesnt pass ip to server. in such situations u can't get IP address using Asp.net however Java Provide applet using which u can get IP Address in any case.

( for Netscape, Mozilla and Firefox only, and Java must be enabled)

<script language="javascript" type="text/javascript">   

if (navigator.appName.indexOf("Netscape") != -1){
ip = "" + java.net.InetAddress.getLocalHost().getHostAddress();
document.write("<b>Your IP address is " + ip+'</b>');
}
else {
document.write("<b>IP Address only shown in Netscape with Java enabled!</b>");
}

</script>
1

I assume you are behind a NAT/Reverse Proxy so I think you have to use:

Request.ServerVariables("REMOTE_ADDR") 

Most likely 172.16.0.0/12 is your privat LAN where 172.16.16.248 is your own address and 172.16.16.1 the address of your router/proxy.

Node
  • 21,706
  • 2
  • 31
  • 35
  • Nope, /12 should be right as default. =) http://en.wikipedia.org/wiki/Private_network – Node Oct 14 '08 at 10:21
1

Building on tomfannings answer...

 public static string ClientIp(this HttpRequestBase @this) {
  var clientIp = string.Empty;
  string forwardedFor = @this.ServerVariables["HTTP_X_FORWARDED_FOR"];

  if (string.IsNullOrWhiteSpace(forwardedFor)) {
    clientIp = @this.ServerVariables["REMOTE_ADDR"];
  } else {

    var array = forwardedFor
      .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
      .Select(s => s.Trim());

    foreach (var element in array) {
      if (element.IsValidIp4() || element.IsValidIp6()) {
        clientIp = element;
        break;
      }
    }
  }
  return clientIp;
}

public static bool IsValidIp4(this string @this) {
  var pattern = new Regex(@"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$");
  return pattern.IsMatch(@this);
}

public static bool IsValidIp6(this string @this) {
  var pattern = new Regex(@"^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(d|dd|1[0-1]d|12[0-8]))$");
  return pattern.IsMatch(@this);
}
0

The two addresses you've listed there are from one of the ranges defined as being private. (see here for description)

It sounds more like you're picking up the internal address of your own firewall(s)?

Andrew Edgecombe
  • 39,594
  • 3
  • 35
  • 61