UserHostAddress дает неправильные IP-адреса - PullRequest
9 голосов
/ 14 октября 2008

Я собираю статистику по IP-адресам, с которых пользователи посещают мой сайт, и я заметил, что представлены только два IP-адреса, 172.16.16.1 и 172.16.16.248. Свойство, которое я использую для определения IP-адреса:

Request.UserHostAddress

Что может быть причиной потери информации IP-адреса? Все пользователи со всего мира, поэтому они не могут быть позади только двух прокси.

Ответы [ 7 ]

24 голосов
/ 14 октября 2008

Возможно, вы захотите что-то вроде этого;

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

Заголовок HTTP_X_FORWARDED_FOR получает IP-адрес за прокси-серверами.

См. Эту страницу, которая объясняет почему более подробно; Получение реального IP-адреса ваших пользователей

9 голосов
/ 14 октября 2008

Это похоже на работу обратного прокси. Когда вы используете обратный прокси, клиент подключается к прокси, который сам открывает новое соединение с вашим сервером. Поскольку ASP.NET использует информацию о входящем соединении для заполнения адреса пользователя, вы получаете адрес обратного прокси.

Если вы действительно находитесь в этой конфигурации, вам понадобится помощь обратного прокси-сервера, чтобы получить правильную информацию. Большинство обратных прокси предоставляют возможность добавить заголовок к HTTP-запросу с реальным IP-адресом клиента. Проверьте документацию вашего прокси.

5 голосов
/ 31 октября 2012

Основываясь на ответе Дейва Андерсона, здесь приведен фрагмент, который учитывает цепочку обратных прокси.

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

string ipStr = string.IsNullOrWhiteSpace(forwardedFor) 
                   ? Request.ServerVariables["REMOTE_ADDR"] 
                   : forwardedFor.Split(',').Select(s => s.Trim()).First();
1 голос
/ 03 июля 2009

Request.ServerVariables ("REMOTE_ADDR") не работает. Эта проблема связана с тем, что ваш сервер, вероятно, находится за каким-то прокси-сервером (или подключен к Интернету через какую-то сеть), или настройки вашего маршрутизатора настроены как NAT (преобразование сетевых адресов). Этот метод не передает IP на сервер. в таких ситуациях вы не можете получить IP-адрес, используя Asp.net однако апплет Java Provide позволяет использовать IP-адрес в любом случае.

(только для Netscape, Mozilla и Firefox, и Java должна быть включена)

<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 голос
/ 14 октября 2008

Я предполагаю, что вы находитесь за NAT / Reverse Proxy, поэтому я думаю, что вы должны использовать:

Request.ServerVariables("REMOTE_ADDR") 

Скорее всего, 172.16.0.0/12 - ваша приватная локальная сеть, где 172.16.16.248 - ваш собственный адрес, а 172.16.16.1 - адрес вашего маршрутизатора / прокси.

0 голосов
/ 02 августа 2016

Построение ответа на вопрос ...

 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 голосов
/ 14 октября 2008

Два указанных вами адреса относятся к одному из диапазонов, определенных как частные. (см. здесь для описания)

Звучит так, будто вы выбираете внутренний адрес своего брандмауэра (ов)?

...