【问题标题】:UserHostAddress gives wrong IPsUserHostAddress 提供了错误的 IP
【发布时间】:2010-09-17 01:31:36
【问题描述】:

我收集了用户访问我网站的 IP 地址的统计信息,我注意到只显示了两个 IP 地址,172.16.16.1 和 172.16.16.248。我用来确定IP地址的属性是

Request.UserHostAddress

IP 地址信息丢失的原因可能是什么?所有用户都来自世界各地,所以他们不能只支持两个代理。

【问题讨论】:

    标签: asp.net networking ip-address


    【解决方案1】:

    你可能想要这样的东西;

    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 地址。

    查看此页面以更详细地解释原因; Getting The Real IP of your Users

    【讨论】:

    • 我知道 HTTP_X_FORWARDED_FOR 标头,但我对问题的原因更感兴趣。还是谢谢!
    • 请注意,链式代理可能会导致多个 HTTP_X_FORWARDED_FOR 标头。
    • @Marc Climent:您能否为这个问题添加一个新的答案来解决这个问题?我想看看它是如何工作的。 Request.ServerVariables["HTTP_X_FORWARDED_FOR"] 会返回一个分隔的 IP 字符串,还是只返回第一个/最后一个标头?
    • @MikeWyatt 看看这个问题:stackoverflow.com/questions/753645/…
    • @MarcCliment 已添加拆分以获取第一个逗号分隔值
    【解决方案2】:

    这看起来像是反向代理的工作。 当您使用反向代理时,客户端会连接到代理,而代理本身会打开与您的服务器的新连接。由于 ASP.NET 使用传入连接的信息来填充用户地址,因此您将获得反向代理的地址。

    如果您确实处于此配置中,则需要反向代理的帮助才能获得正确的信息。大多数反向代理都提供了向 HTTP 请求添加标头的可能性,其中包含客户端的真实 IP 地址。检查代理的文档。

    【讨论】:

      【解决方案3】:

      以 Dave Anderson 的回答为基础,这里有一个考虑到反向代理链的 sn-p。

      string forwardedFor = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
      
      string ipStr = string.IsNullOrWhiteSpace(forwardedFor) 
                         ? Request.ServerVariables["REMOTE_ADDR"] 
                         : forwardedFor.Split(',').Select(s => s.Trim()).First();
      

      【讨论】:

        【解决方案4】:

        我假设您在 NAT/反向代理之后,所以我认为您必须使用:

        Request.ServerVariables("REMOTE_ADDR") 
        

        172.16.0.0/12 很可能是您的私有 LAN,其中 172.16.16.248 是您自己的地址,而 172.16.16.1 是您的路由器/代理的地址。

        【讨论】:

        【解决方案5】:

        Request.ServerVariables("REMOTE_ADDR") 不起作用。 这个问题是因为你的服务器可能在某个代理之后。(或通过某个网络连接到互联网)或者你的路由器设置被设置为 NAT(网络地址转换)这种技术不会将 ip 传递给服务器。在这种情况下,您无法使用 Asp.net 获取 IP 地址 但是 Java 提供了一个小程序,在任何情况下你都可以使用它来获取 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>
        

        【讨论】:

          【解决方案6】:

          您在此处列出的两个地址来自定义为私有的范围之一。 (说明见here

          听起来更像是在获取自己防火墙的内部地址?

          【讨论】:

            【解决方案7】:

            基于 tomfannings 的回答...

             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);
            }
            

            【讨论】:

            • 根据所提出的问题解释您的代码会有所帮助。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-03-15
            • 2022-01-24
            • 1970-01-01
            • 1970-01-01
            • 2018-08-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多