When a client sends a request to GF, it is forwarded via the Gorouter agent. When forwarding, Gorouter modifies the values of remoteaddr and RemoteHost in the header, So the values of remoteaddr and RemoteHost obtained in GF are gorouter remoteaddr and remotehost values that are inconsistent with the standard specifications. When a
forwards a request using gorouter, it stores the request IP in the header x-forwarded-for, so the client IP can be obtained by parsing the x-forwarded-for header.
X-forwarded-for: The XFF header, which represents the client, that is, the HTTP request-side real IP. The format of this HTTP header x-forwarded-for is as follows:
X-forwarded-for:client1, Proxy1, Proxy2
where IP addresses the IP address area separated by a comma + space, the leftmost (client1 ) is the IP address of the most original client, and the proxy server adds the requested source IP address to the right as each request is successfully received. This is stated in the RFC7239 specification, and Gorouter also complies with the specification.
Set the Remotaddr and RemoteHost properties of the request with two scenarios:
"Scenario 1"
Remove the first IP address of the X-FORWARDED-FOR header because the request request will be credited to the X-forwarded-for header and each time it is added to the end of the proxy. , then it is the client's IP. The implementation is as follows:
1. Determines whether the X-forwarded-for header exists and is not empty.
2. If blank, the Remotaddr and RemoteHost properties of the request are not set.
3. If the x-forwarded-for header is present and not empty, take its first IP address and assign it to the Remoteaddr and RemoteHost properties of the request.
Example:
X-forwarded-for:client_ip, Proxy1, Cf_ip, 192.168.0.10 (192.168.0.10 is the internal address)
CLIENT_IP is the first IP in the x-forwarded-for header, so it is the client IP that is assigned to the REMOTEADDR and RemoteHost properties of the request.
Code:
private string getfirstipofxff () { string remoteIp = null; StringBuilder Concatremoteipheadervalue = new stringbuilder (); for (Iterator<string> headeriterator = getheaders (Remoteipheader) .iterator (); Headeriterator.hasnext ();) { if (Concatremoteipheadervalue.length () > 0) { concatremoteipheadervalue.append (", "); } concatremoteipheadErvalue.append (Headeriterator.next ()); } string[] remoteipheadervalue = commadelimitedlisttostringarray ( concatremoteipheadervalue .tostring ()); if (remoteIpHeaderValue.length != 0) { remoteip = remoteipheadervalue[0].trim (); } return remoteip; }
"Scenario 2"
How Tomcat is implemented
Because the request requests the IP that sends the request to the X-forwarded-for header and each time it is added to the end, the IP of the proxy server is removed at the end, so the last one remaining is the client's IP. The specific implementation is as follows:
1.
Configuration file
<valve classname= "Org.apache.catalina.valves.RemoteIpValve" internalproxies= "192\.168\.0\.10, 192\.168\.0\.11" Remoteipheader= "X-forwarded-for" remoteipproxiesheader= "x-forwarded-by" trustedproxies= "192\.168\.0\.13, 192\.1 68\.0\.12 "/>
2.
If the x-forwarded-for header is present and not empty, from which the IP list is read, the individual IPs are scanned in right-to-left order, with the following rules:
1) If the IP list current IP matches the IP in the internalproxies, the IP is deleted and the next IP is processed.
2) If the IP list current IP matches the IP in the truestedproxies, the IP is added to the Proxiesheadervalue and the next IP is processed.
If the current IP in the IP list does not match the IP in the truestedproxies, the IP is placed as the client IP.
3) Add the remaining IP in the IP list to Newremoteipheadervalue, and the scan ends.
3.
If the client IP that matches the rule is not found at the end of the scan, the last scanned IP is set to the client IP.
4.
Assign the client IP generated in the above scan to the REMOTEADDR and RemoteHost properties of the request.
Set the IP in the proxiesheadervalue generated in the above scan to the Remoteipproxiesheader header.
Set the IP in the newremoteipheadervalue generated in the above cycle to the Remoteipheader header.
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M02/74/46/wKiom1YXsUHCj_X1AAIDrpm7ky0979.jpg "title=" X-forwarded-for parsing Process "alt=" wkiom1yxsuhcj_x1aaidrpm7ky0979.jpg "/>
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M02/74/43/wKioL1YXsVvxvFuyAAEXUC_dGd4923.jpg "title=" X-forwarded-for parsing Process "alt=" wkiol1yxsvvxvfuyaaexuc_dgd4923.jpg "/>
Example:
X-forwarded-for:client_ip, Elb_ip, Cf_ip, 192.168.0.10 (192.168.0.10 is the internal address)
Configuration file
<valve classname= "Org.apache.catalina.valves.RemoteIpValve" internalproxies= "192\.168\.0\.10" Remoteiphead Er= "X-forwarded-for" remoteipproxiesheader= "x-forwarded-by" trustedproxies= "Cf_ip"/>
The procedure to get the client IP is as follows:
1, x-forwarded-for Head is not empty, get IP list client_ip, Elb_ip, Cf_ip, 192.168.0.10.
2, gets to 192.168.0.10, matches the IP in Internalproxies, matches successfully, deletes this IP and then obtains the next IP.
3. Get to Cf_ip, match with IP in Internalproxies, match failed, match IP in truestedproxies, match successfully, add this IP to Proxiesheadervalue and get next IP.
4, get to ELB_IP, and internalproxies IP match, matching failure, and truestedproxies in the IP match, matching failed, so ELB_IP is the client IP.
5. Assign elb_ip to the Remoteaddr and RemoteHost properties of the request.
6, set the CF_IP to the Remoteipproxiesheader head.
7, set the CLIENT_IP to the Remoteipheader head.
Code:
Private hashmap<string, linkedlist<string>> getmatchedipofxff () { String remoteIp = null; LinkedList<String> remoteIpValue = new LinkedList<String> (); linkedlist<string> proxiesheadervalue = new LinkedList<String> (); linkedlist<string> newRemoteIpHeaderValue = new LinkedList<String> (); hashmap<string, linkedlist<string>> headervaluemap = new HashMap<String, LinkedList<String>> (); Stringbuilder concatremoteipheadervalue = new stringbuilder (); for (iterator<string> headeriterator = getheaders (Remoteipheader) .iterator (); Headeriterator.hasnext ();) { if (Concatremoteipheadervalue.length () > 0) { concatremoteipheadervalue.append (", "); } concatremoteipheadervalue.append (Headeriterator.next ()); } string[] remoteipheadervalue = commadelimitedlisttostringarray (concatremoteipheadervalue .tostring ()); int idx; for (idx = remoteipheadervalue.length - 1; idx > = 0; idx--) { string currentRemoteIp = remoteIpHeaderValue[idx]; remoteIp = currentRemoteIp; if (Internalproxies.matcher (CURRENTREMOTEIP). Matches ()) { // do nothing, ignore internal proxies. } else if (trustedproxies != null &nbsP; && trustedproxies.matcher (CurrentRemoteIp). Matches ()) { // if currentRemoteIp match with trusted proxies,add this ip to // proxiesheader. Proxiesheadervalue.addfirst (CURRENTREMOTEIP); } else { &NBSP;&NBSP;&NBSP;IDX--;&NBSP;//&NBSP;DECREMENT&NBSP;IDX&NBSP;BECAUSE&NBSP;BREAK&NBSP;STATEMENT&NBSP;DOESN ' t do it. break; } } // continue to loop on remoteipheadervalue to build the new value of the // remoteIpHeader. for (; idx >= 0; idx--) { String currentremoteip = remoteipheadervalue[idx]; newremoteipheadervalue.addfirst (CURRENTREMOTEIP); } remoteipvalue.addfirst (remoteIp); headervaluemap.put ("Remoteipvalue", remoteipvalue); headervaluemAp.put ("Proxiesheadervalue", proxiesheadervalue); Headervaluemap.put ("Newremoteipheadervalue", newremoteipheadervalue); return headervaluemap; }
This article is from the "Night" blog, be sure to keep this source http://icyore.blog.51cto.com/8486958/1701322
"GlassFish Investigation" gets the client addr and host