http://blog.csdn.net/broadview2006/article/details/54570943
When we visit the services on the Internet, most of the time, the client is not directly access to the service side, but the client first request to the reverse proxy, reverse proxy forwarding to the server to achieve service access, through the reverse proxy to achieve routing/load balancing policies. As a result, the client IP on the server will be a reverse proxy IP rather than a real client IP, so a way is needed to obtain the real client IP.
As shown in the following illustration, clients access specific services Nginx backend (or tomcat services, for example) through the Nginx Proxy1 and Nginx Proxy2 Two-tier reverse proxy. That Nginx backend how to get real client IP.
Let's see how we can get to the client real IP. Scene 1
Scene 1 is a very simple scene, Nginx proxy forwards the request directly, without any processing.
Nginx Proxy
192.168.107.107 nginx.conf
location/test {
proxy_pass http://192.168.107.112:8080;
}
192.168.107.112 nginx.conf
location/test {
proxy_pass http://192.168.107.114:8080;
}
Nginx Proxy is simply to forward the request backwards.
Nginx backend
192.168.107.114 nginx.conf
location/test default_type {text/html
;
CharSet GBK;
echo "$remote _addr | | $http _x_forwarded_for ";
}
Nginx Backend Output Client IP ($remote _addr) and X-forwarded-for request headers ($http _x_forwarded_for), the output results are as follows when the service is accessed:
192.168.107.112 | |
Analysis
1. $remote _ADDR represents the client IP, the current configuration output is the last proxy server IP, not the real client IP;
2. In the absence of a special configuration, the X-forwarded-for request header is not automatically added to the request header, that is, the $http_x_forwarded_for output of the Nginx backend is empty. Scene 2
Scenario 2 captures the client's true IP by adding X-real-ip and x-forwarded-for.
Nginx Proxy
192.168.107.107 nginx.conf
location/test {proxy_set_header x-real-ip
$remote _addr;
Proxy_set_header x-forwarded-for $proxy _add_x_forwarded_for;
Proxy_pass http://192.168.107.112:8080;
}
192.168.107.112 nginx.conf
location/test {
proxy_set_header x-forwarded-for $proxy _add_x_forwarded_for;
Proxy_pass http://192.168.107.114:8080;
}
Nginx backend
192.168.107.114 nginx.conf
location/test default_type {text/html
;
CharSet GBK;
echo "$remote _addr | | $http _x_real_ip | | $http _x_forwarded_for ";
}
When the service is accessed, the output results are:
192.168.107.112 | | 192.168.162.16 | | 192.168.162.16, 192.168.107.107
Analysis
1. In the nearest user to the reverse proxy nginxproxy 1, through the "Proxy_set_header x-real-ip $remote _addr" to write the real client IP to the request header X-real-ip, nginxbackend output $http _X_REAL_IP obtains the real client IP, while Nginx backend's "$remote _addr" output as the last reverse proxy IP;
2. "Proxy_set_headerx-forwarded-for $proxy _add_x_forwarded_for" is to combine x-forwarded-for and $remote_addr in the request header with commas, $proxy_add_x_forwarded_for is $remote_addr if there is no x-forwarded-for in the request header.
X-forwarded-for represents the client IP, and the reverse proxy, such as Nginx, is added by $proxy_add_x_forwarded_for, x-forwarded-for in the format of X-forwarded-for:real Client IP, proxy IP 1, proxy IP N, each through a reverse proxy in the request header x-forwarded-for after the reverse proxy IP.
Here we can use the request headers X-real-ip and x-forwarded-for to get the client IP and the client to the server through the reverse proxy IP. This approach is still very troublesome, $remote _addr is not real client IP. Scene 3
In order to obtain the real client IP more conveniently, the Nginx Http_realip_module module can be used to solve the problem, and the module is installed through –with-http_realip_module when the Nginx is installed. Nginxproxy configuration is the same as Scenario 2.
Nginx backend
192.168.107.114 nginx.conf
real_ip_header x-forwarded-for;
Set_real_ip_from 192.168.0.0/16;
Real_ip_recursive on;
location/test {
default_type text/html;
CharSet GBK;
echo "$remote _addr | | $http _x_real_ip | | $http _x_forwarded_for ";
}
When the service is accessed, the output results are:
192.168.162.16 | | 192.168.162.16 | | 192.168.162.16, 192.168.107.107
Analysis
1.x-real-ip and X-forwarded-for are the same as Scene 2;
2. After using the Realip module, $remote _addr output is real client IP, you can use $REALIP_REMOTE_ADDR to obtain the last reverse proxy IP;
3.real_ip_headerx-forwarded-for: Tell nginx Real client IP from which request header to obtain, such as x-forwarded-for;
4.SET_REAL_IP_FROM192.168.0.0/16: Tell Nginx which is the reverse proxy IP, that is, after the exclusion of the real client IP, support the configuration of specific IP address, CIDR address;
5.real_ip_recursive on: Whether recursive parsing, when Real_ip_recursive is configured to OFF, nginx the last IP in the requested header specified by Real_ip_header as the real client IP; when Real_ip_ When recursive is configured on, nginx recursively resolves the real_ip_header-specified request header, and the last mismatch Set_real_ip_from IP as the real client IP.
If the configuration "real_ip_recursive off;" , the output is:
192.168.107.107 | | 192.168.162.16 | | 192.168.162.16, 192.168.107.107
Summarize
1. Through the "Proxy_set_header x-forwarded-for $proxy _add_x_forwarded_for" from the real client IP and reverse proxy IP separated by commas, added to the request header;
2. Can be configured on the first reverse proxy "Proxy_set_header x-real-ip $remote _addr" To obtain real client IP;
3. With Realip module can also be obtained from x-forwarded-for to real client IP.
The first reverse proxy in the entire reverse agent chain can not be configured with "Proxy_set_header x-forwarded-for $proxy _add_x_forwarded_for", Otherwise, the client can forge x-forwarded-for to fake client real IP, if the server uses X-forwarded-for first IP as the real client IP, then there is a problem. This problem does not occur if you configure the X-REAL-IP request header or with the Realip module. If you parse x-forwarded-for, remember to use the Realip algorithm to parse, rather than take the first one.
When we do limit the flow must be aware of the restrictions are real client IP, rather than reverse proxy IP, I met a lot of colleagues in this piece of problems.