How to obtain the real IP address of nginx for reverse proxy?
Real IP address used by nginxto reverse proxy
1. Compile
For client-> nginxreverseproxy-> apache,
To get the real IP address in the program, you must specify the parameter "-- with-http_realip_module" when executing nginx configure, for example:
./Configure -- prefix =/data/nginx -- with-http_realip_module -- with-stream -- with-pcre =/tmp/X/pcre-8.32 -- with-openssl =/tmp/X/openssl-1.0.2a
Parameter description:
-- Prefix = specifies the installation directory, that is, the directory for storing program files after makeinstall
-- With-http_realip_module allows the program to get the real client IP address through the Environment Variable HTTP_X_REAL_IP
-- With-stream indicates that TCP proxy is enabled.
-- With-pcre = specifies the dependent pcre. Note that the directory path after the pcre source code is decompressed is not the installation path.
-- With-openssl = specifies the dependent openssl. Note that the directory path after openssl source code extraction is not the installation path.
In addition, the simplest way to confirm is to use the nm command to view the nginx program file to see if there is a real-related symbol, for version nginx-1.9.4, you can find that there is "0809c54btngx_http_realip ".
2. program code
Test the program code (based on it in subsequent tests ):
// G ++-g-ohello.cgihello.cpp
# Include <stdio. h>
# Include <stdlib. h>
Intmain ()
{
Printf ("Content-Type: text/html; charset = UTF-8 \ r \ n ");
Printf ("<p> HTTP_X_FORWARDED_FOR: % s \ n", getenv ("HTTP_X_FORWARDED_FOR "));
Printf ("<p> HTTP_X_REAL_IP: % s \ n", getenv ("HTTP_X_REAL_IP "));
Printf ("<p> REMOTE_ADDR: % s \ n", getenv ("REMOTE_ADDR "));
Printf ("<p> ");
Return0;
}
The test is to modify the nginx. conf configuration file:
Proxy_set_header can be added to the http segment of nginx. conf, server segment, location segment, and inheritance and overwrite relationships between level 1 and level 1.
3. Related Configuration
Example:
Location /{
# Roothtml;
Define indexindex.htmlindex.htm;
Proxy_passhttp: // 201761.28.11: 80;
Proxy_redirectoff;
Proxy_set_headerHost $ host;
Proxy_set_headerX-Real-IP $ remote_addr; # This is required
Proxy_set_headerX-Forwarded-For $ proxy_add_x_forwarded_for;
}
The difference between X-Forwarded-For and X-Real-IP is that if X-Forwarded-For is included in the request, the nginx append method is used, in this way, the forwarding track can be displayed.
Of course, the request can completely construct a false X-Forwarded-For, when the configuration file opens X-Real-IP and the compilation specifies -- with-http_realip_module, the environment variable HTTP_X_REAL_IP is always the real client IP address.
If:
Client-> nginxreverseproxy (A)-> nginxreverseproxy (B)-> apache
What Will HTTP_X_REAL_IP be?
4. Test 1
Assume the following deployment:
Client (10.6.81.39)-> nginx (10.6.223.44: 8080)-> nginx (10.6.208.101: 8080)-> apache (10.6.208.101: 80)
? A
Assume that all the configurations of nginx (10.6.223.44: 8080) are (modified on the default nginx configuration ):
Server {
Listen8080;
Server_name10.6.223.44;
Location /{
# Roothtml;
Define indexindex.htmlindex.htm;
Proxy_passhttp: // 10.6.208.101: 8080;
Proxy_redirectoff;
Proxy_set_headerHost $ host;
The proxy_set_headerX-Real-IP $ remote_addr;
Proxy_set_headerX-Forwarded-For $ proxy_add_x_forwarded_for;
}
Assume that all the configurations of nginx (10.6.208.101: 8080) are (modified on the default nginx configuration ):
Server {
Listen8080;
Server_name10.6.208.101;
Location /{
# Roothtml;
Define indexindex.htmlindex.htm;
Proxy_passhttp: // 10.6.208.101: 80;
Proxy_redirectoff;
Proxy_set_headerHost $ host;
The proxy_set_headerX-Real-IP $ remote_addr;
Proxy_set_headerX-Forwarded-For $ proxy_add_x_forwarded_for;
}
The output result of the above test program is:
<P> HTTP_X_FORWARDED_FOR: 10.6.81.39, 10.6.223.44
<P> HTTP_X_REAL_IP: 10.6.223.44
<P> REMOTE_ADDR: 10.6.81.39
? B
However, if the client adds the following content to the HTTP request header:
X-FORWARDED-FOR: 8.8.8.7.
CLIENT-IP: 8.8.8.8.
X-REAL-IP: 8.8.8.10.
Then the output result is:
<P> HTTP_X_FORWARDED_FOR: 8.8.8.7, 10.6.81.39, 10.6.223.44
<P> HTTP_X_REAL_IP: 10.6.223.44
<P> REMOTE_ADDR: 8.8.8.7
? C
Based on A, if only nginx (10.6.223.44: 8080) is configured to comment out "X-Forwarded-For", the output result is:
<P> HTTP_X_FORWARDED_FOR: 10.6.223.44
<P> HTTP_X_REAL_IP: 10.6.223.44
<P> REMOTE_ADDR: 10.6.223.44
? D
Based on A, if only nginx (10.6.208.101: 8080) is configured to comment out "X-Forwarded-For", the output result is:
<P> HTTP_X_FORWARDED_FOR: 10.6.81.39
<P> HTTP_X_REAL_IP: 10.6.223.44
<P> REMOTE_ADDR: 10.6.81.39
5. Test 2
Configuration Based on Test 1,
When the access path is changed to client (10.6.81.39)-> nginx (10.6.208.101: 8080)-> apache (10.6.208.101: 80), the output result of the program is:
<P> HTTP_X_FORWARDED_FOR: 10.6.81.39
<P> HTTP_X_REAL_IP: 10.6.81.39
<P> REMOTE_ADDR: 10.6.81.39
However, if the client adds the following content to the HTTP request header:
X-FORWARDED-FOR: 8.8.8.7.
CLIENT-IP: 8.8.8.8.
X-REAL-IP: 8.8.8.10.
Then the output result is:
<P> HTTP_X_FORWARDED_FOR: 8.8.8.7, 10.6.81.39
<P> HTTP_X_REAL_IP: 10.6.81.39
<P> REMOTE_ADDR: 8.8.8.7
As can be seen from the above, only the real-ip function is correctly configured and used. In addition to HTTP_X_REAL_IP, other content can be disturbed, and the client can tamper with them.
6. Conclusion
If nginx reverse proxy is correctly compiled and configured, you can use "HTTP_X_REAL_IP" to obtain the real IP address of the client when there is only one layer of nginx reverse proxy.
If there is a layer-2 nginx reverse proxy, the real IP address of the client is included in "HTTP_X_FORWARDED_FOR.
The least trustable is "REMOTE_ADDR". Its content can be completely specified by the client! In short, as long as the compilation and configuration are correct, "HTTP_X_FORWARDED_FOR" always contains the real IP address of the client.