Note: The content in this article is based on my blog posts and materials in the MSDN discussion area on the blog Park, which can be obtained through actual tests,There are few original content to tell the truthAnd write this article to record what you have done in the project. The referenced blog posts and their authors are mentioned below.Later, I will learn more about HTTP, TCP/IP, and other knowledge. I will discuss this in depth here.
I. Terms
First, let's talk about some terms that we will talk about next.
In Web development, most of us are used to using some attributes in the HTTP request header to obtain the Client IP address. The common attribute isREMOTE_ADDR,HTTP_VIAAndHTTP_X_FORWARDED_FOR.
These threeAttribute meaningThis is probably the case: (from the Internet, please confirm)
REMOTE_ADDR: the value of this attribute is the IP address used to "Shake hands" between the client and the server. If "anonymous proxy" is used, REMOTE_ADDR displays the IP address of the proxy server.
X-Forwarded-For: it is an HTTP request header field used to identify the original IP address of the client connecting to the Web server through HTTP proxy or Server Load balancer.
The validity of XFF depends on the authenticity of the original IP Address Provided by the proxy server. Therefore, the effective use of XFF should ensure that the proxy server is credible. For example, you can establish a trusted server whitelist.
The general format of this HTTP header is as follows:
X-Forwarded-For: client1, proxy1, proxy2
The values are separated by commas and spaces. The leftmost (client1) is the IP address of the original client. Each time the proxy receives a requestRequest source IP addressAdd to the right. In the preceding example, the request successfully passed three proxy servers: proxy1, proxy2, and proxy3. The request is sent by client1 and reaches proxy3 (proxy3 may be the end of the request ). When a request is sent from client1, XFF is blank and the request is sent to proxy1. When proxy1 is passed, client1 is added to XFF, and then the request is sent to proxy2; when proxy2 is used, proxy1 is added to XFF, and then the request is sent to proxy3; When proxy3 is used, proxy2 is added to XFF, And the request direction is unknown. If proxy3 is not the end of the request, the request will be forwarded.
The X-Forwarded-For field should be used with caution because it is very easy to forge this field. Normally, the last IP address in XFF is the IP address of the last proxy server, which is usually a reliable information source.
(A complete introduction to X-Forwarded-For in the Wiki: http://zh.wikipedia.org/wiki/X-Forwarded-For)
When using these attributes,Attribute ValueWhat is the difference between the three attributes of getting a user's IP address (the original author is unknown ).
In ASP. NET, you can also obtain the IP address of the client in another way, that is, throughUserHostAddress attribute in the Request object. In the MSDN Library, this attribute is interpreted as follows:The property value is the IP address of the remote client.
If the client uses a proxy server, the Request. UserHostAddress attribute obtains the IP address of the proxy server.
Ii. Method
Well, I have talked about so many conceptual things. Let's talk about the implementation methods.
The idea of most methods on the internet is:If a proxy IP address exists, the proxy IP address is obtained first. Otherwise, the IP address connecting to the client is obtained. Or, if a client fails to be obtained, the proxy IP address is obtained first.
For the following method, refer to asp.net in the blog post to obtain the Client IP address (by comeonfyz)
Bytes -----------------------------------------------------------------------------------------------------------
/// <Summary> /// obtain the Client IP address /// </summary> /// <returns> If the client fails, return the return address </returns> public static string GetIP () {// if the client uses a proxy server, use HTTP_X_FORWARDED_FOR to find the Client IP address string userHostAddress = HttpContext. current. request. serverVariables ["HTTP_X_FORWARDED_FOR"]. toString (). split (',') [0]. trim (); // otherwise, directly read REMOTE_ADDR to obtain the Client IP address if (string. isNullOrEmpty (userHostAddress) {userHostAddress = HttpContext. current. request. ser VerVariables ["REMOTE_ADDR"];} // if neither of the preceding two fails, the Request is used. the UserHostAddress attribute obtains the IP address, but it cannot be determined whether the IP address is the Client IP address or the proxy IP address if (string. isNullOrEmpty (userHostAddress) {userHostAddress = HttpContext. current. request. userHostAddress;} // determine whether the obtained IP address is successful and check the IP address format (it is very important to check its format) if (! String. isNullOrEmpty (userHostAddress) & IsIP (userHostAddress) {return userHostAddress;} return "127.0.0.1 ";} /// <summary> /// check the ip address format /// </summary> /// <param name = "ip"> </param> /// <returns> </returns> public static bool IsIP (string ip) {return System. text. regularExpressions. regex. isMatch (ip, @ "^ (2 [0-4] \ d | 25 [0-5] | [01]? \ D ?) \.) {3} (2 [0-4] \ d | 25 [0-5] | [01]? \ D ?) $ ");}
Bytes -----------------------------------------------------------------------------------------------------------
However, this is a serious defect, as described in the severe consequences of Daniel Kingthy's use of HTTP_X_FORWARDED_FOR to obtain the Client IP address in his blog post, the value of "HTTP_X_FORWARDED_FOR" is obtained by obtaining the "X_FORWARDED_FOR" attribute of the HTTP header. The attacker can easily forge IP addresses, the validity of XFF depends on the authenticity of the original IP Address Provided by the proxy server. Therefore, the effective use of XFF should ensure that the proxy server is credible. However, as a developer, we do not know the authenticity of the user's IP address, but it is difficult to distinguish the credibility of the proxy server.
Therefore, my personal thoughts are the same as those of Daniel Kingthy based on various materials:Ignore proxy.
Bytes -----------------------------------------------------------------------------------------------------------
1 // <summary> 2 // obtain the Client IP address (ignore proxy) 3 /// </summary> 4 /// <returns> If the request fails, the return address is returned. </returns> 5 public static string GetHostAddress () 6 {7 string userHostAddress = HttpContext. current. request. userHostAddress; 8 9 if (string. isNullOrEmpty (userHostAddress) 10 {11 userHostAddress = HttpContext. current. request. serverVariables ["REMOTE_ADDR"]; 12} 13 14 // Finally, determine whether the obtained IP address is successful and check the IP address format (check whether the format is very important) 15 if (! String. isNullOrEmpty (userHostAddress) & IsIP (userHostAddress) 16 {17 return userHostAddress; 18} 19 return "127.0.0.1 "; 20} 21 22 /// <summary> 23 // check the ip address format 24 /// </summary> 25 /// <param name = "ip"> </param> 26 // <returns> </returns> 27 public static bool IsIP (string ip) 28 {29 return System. text. regularExpressions. regex. isMatch (ip, @ "^ (2 [0-4] \ d | 25 [0-5] | [01]? \ D ?) \.) {3} (2 [0-4] \ d | 25 [0-5] | [01]? \ D ?) $ "); 30}
Bytes -----------------------------------------------------------------------------------------------------------
Iii. Summary
Ignoring the proxy server is definitely not the best solution. If the project needs to explicitly ask for the real address of the client, you must not ignore the proxy server.
In addition, I have also consulted Artech Daniel about this issue. Although he has not studied these issues in depth, he also believes that there is no way to obtain IP addresses that are completely trustworthy, this is determined by the TCP/IP protocol.
I have attached a piece of information that Artech Daniel gave me to share with me. Http://www.symantec.com/connect/articles/ip-spoofing-introduction
I hope this blog post will inspire others and welcome criticism and suggestions.