How to obtain the User IP on the second level of Nginx on the two-tier server
A Prior to the Nginx server configuration encountered a problem, before the server is useful to a limit the client's maximum concurrent connection function, and the implementation of this feature depends on the server to do
$remote-addr
Such a configuration to achieve. However, after the addition of the front-end (load, CDN, firewall, security services) server, the received client IP becomes the IP of the front-end server, not the real User IP address.
Two Such a problem, I re-read a few times the Nginx website introduction, also found that another particularly important variables
$proxy _add_x_forwarded_for
This variable is the value of the X-forwarded-for field in the Client access request, and if the request does not contain the field, the variable that is used automatically is equivalent to REMOTE-ADDR. This allows us to get the field of the real IP address of the client that the front end server normally holds in the HTTP request, usually the x_forwarded_for field we are talking about, and then we can implement a variety of functions in this way.
Three Let me give you a brief demonstration of the situation. Many deficiencies, welcome correction.
First we build the nginx environment, here we use the latest version of the 1.7 series 1.7.9 for example, (for version of the problem see FAQ 1)
Download, wget required address http://nginx.org/download/nginx-1.7.9.tar.gz
1. Download Nginx
[lugt@localhostmysql]$ wget http://nginx.org/download/nginx-1.7.9.tar.gz
2. Unzip
[Lugt@localhostmysql]$ Tar zxvf nginx-1.7.9.tar.gz
3. Direct compilation (need to consider the need for support for plugins such as OpenSSL)
[Lugt@localhost MySQL] $cd nginx-1.7.9
[Lugt@localhost nginx-1.7.9]$./configure
[Lugt@localhost nginx-1.7.9]$ make
[Lugt@localhost nginx-1.7.9]$ su
[lugt@localhostnginx-1.7.9]$ make Install
4. Then next modify the nginx.conf configuration file
[Lugt@localhost nginx-1.7.9]$ su
[Lugt@localhost nginx-1.7.9] $CD/usr/local/nginx
[lugt@localhostnginx]$ VI conf/nginx.conf
Then find here in nginx.conf, join to set up load balancer, emulate CDN
Upstream dnsnginx1 { server[*.*.*.*/yourhostname]:8080 weight=10000; #填IP, domain name}server { listen ; server_name #access_log logs/host.access.log main location /{ proxy_pass http://dnsnginx1; Proxy_set_header Host $host; Proxy_set_header x-real-ip $remote _addr; Proxy_set_header x-forwarded-for $proxy _add_x_forwarded_for; Proxy_set_header http_x_forwarded_for $remote _addr; Proxy_redirect default;}}
In setting up a virtual server on port 8080,
Limit_conn_zone $proxy _add_x_forwarded_for zone=addr:10m; # Concurrent Set space 10Mserver { listen 8080; server_name [*.*.*.*/yourhostname]:8080 weight=10000; #填IP, domain name limit_conn addr 1; #限制客户端最大并发连接数为 1 Location/{ root html; Index index.html index.htm; }}
Save. Then test the configuration file syntax
[lugt@localhostnginx]$./sbin/nginx–t
Start the server
[lugt@localhostnginx]$./sbin/nginx
Four Use the AB tool to see the effect.
[Lugt@localhost nginx]$ ab–c 10–n 100–v 4 HTTP://127.0.0.1/| grep http/1.1
This line means: Access the address through the AB test tool, the number of concurrent connections is 30, the total test 300 times, display the HTTP return header information
The AB tool can measure how many connections are sent at the same time, and the last successful return of 200 is the maximum number of concurrent connections that have previously limited nginx, so it is possible to prove that the restrictions on IP are already available. Reference data See FAQ2
FAQ 1 Version Issue
If the Nginx version currently in use does not reach version 1.7.1, it is possible that Nginx does not support this feature.
This is the time to get the X_forwarded_for value from the request through a code clip in the Limit_conn_handler function.
In the case of version 1.6.1, the code is added as follows. SRC/HTTP/MODULES/NGX_HTTP_LIMIT_CONN.C Line 184th
Hash =ngx_crc32_short (Key.data, Key.len); if ("" = = &ctx->key) { if (null!= r->main->headers_in->x_forwarded_for->elts) { Key.data= * (char*) r->main->headers_in->x_forwarded_for->elts; Key.len = 4; Hash =ngx_crc32_short (Key.data, Key.len); } }
FAQ 2 Reference data
Here is a reference data that gets
[lugt@localhost~]$ ab-c 10-n 100-v 4 HTTP://127.0.0.1/| grep http/1.1
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1 OK
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1 OK
<. Repeated down are repeated 8 times http/503 and 1 times http/200 alternately appear >
中文版 Version
How to Retrievethe True IP of the client user if there is both layers of servers
Days before, wehave been faced such a difficulty which are we can ' t use the variable$remote _addr for gathering the Clients ' IP address. This problem surfaces if we used a proxy server between the Trueserver and client, which is actually a CDN. And that makes we functions oflimiting the maximum connections a client can make to a server at a time. Thissituation can also found if the load balance or any anti-spam service is inuse. So that's why we can ' t use REMOTE_ADDR variable further.
After I do someresearch the documentation and the code, I found out of that problem canbe solved by replacing the
Variable with the
$proxy _add_x_forwarded_for
Variable. As this variable allows to retrievethe data from the column x_forwarded_for from the request, we can use thisvariable func Tioning in many ways.
And now I shall the Makean easy example to practically with this method.
First of All,build up a Nginx server.
Here, I'll usethe 1.7.9 version (latest to the written time) for instance, therefore, thereexist some differences betwee n Older versions than 1.7.1 (see FAQ 1)
1. Download A Nginx Copy:
[lugt@localhostmysql]$ wget http://nginx.org/download/nginx-1.7.9.tar.gz
2. Decompress the file
[Lugt@localhostmysql]$ Tar zxvf nginx-1.7.9.tar.gz
3. Compile the Code
[lugt@localhostmysql]$ CD nginx-1.7.9
[lugt@localhostnginx-1.7.9]$./configure
[lugt@localhostnginx-1.7.9]$ Make
[lugt@localhostnginx-1.7.9]$ su
[lugt@localhostnginx-1.7.9]$ make Install
4. and edit the config file nginx.conf
[Lugt@localhost nginx-1.7.9]$ su
[Lugt@localhostnginx-1.7.9]$ Cd/usr/local/nginx
[lugt@localhostnginx]$ VI conf/nginx.conf
There add suchdirectives to the Server1 for emulate for a CDN server
Upstream dnsnginx1 { server[*.*.*.*/yourhostname]:8080 weight=1000; #fill in your ip/hostname}server { listen< c2/>80; server_name [hostname] #fill your ip/hostname here#access_log logs/host.access.log main Location/{ proxy_pass http://dnsnginx1; Proxy_set_header Host $host; Proxy_set_header x-real-ip $remote _addr; Proxy_set_header x-forwarded-for $proxy _add_x_forwarded_for; Proxy_set_header http_x_forwarded_for $remote _addr; Proxy_redirect default;}}
After the end ofone server directive, and with the HTTP directive, add so to function the Sever2
Limit_conn_zone $proxy _add_x_forwarded_for zone=addr:10m; # sample Settingserver { listen 8080; server_name [*.*.*.*/hostname]:8080 weight=10000; #fill in ip/hostname here limit_conn addr 1; # enablethe Limitation of connection per IP at a time to 1. Location/{ root html; Index index.html index.htm; }}
And then you cansave, test the config file and run Nginx
Test your configfile:
[lugt@localhostnginx]$./sbin/nginx–t
Start the Nginx server
[lugt@localhostnginx]$./sbin/nginx
Now, the Serverhas been set and your can run a test at instance.
/* This Commandmeans to run a tool to connect to server as 10conn/once and Conns in total*/
[lugt@localhost~]$ ab-c 10-n 100-v 4 HTTP://127.0.0.1/| grep http/1.1
FAQ 1
There is actuallysome little malfunctions when using elder versions than 1.7.1 (Probably the newversion have it for a new F Eature). So-use the directive in earlier Versions,some code need to be added.
As a Example inthe version 1.6.1
In Filesrc/http/modules/ngx_http_limit_conn.c line around 184
Hash =ngx_crc32_short (Key.data, Key.len); if ("" = = &ctx->key) { if (null!= r->main->headers_in->x_forwarded_for->elts) { key.data= * (char*) r->main->headers_in->x_forwarded_for->elts; Key.len = 4; Hash =ngx_crc32_short (Key.data, Key.len); }
}
FAQ 2 Testingresults
[lugt@localhost~]$ ab-c 10-n 100-v 4 HTTP://127.0.0.1/| grep http/1.1
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1 OK
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1503 Service temporarily unavailable
http/1.1 OK
<. Repeated as 8times of http/503 and 1 time of http/200 and so on>
The above describes how to get the User IP on the second level of the two-tier server Nginx, including the content of the aspects, I hope that the PHP tutorial interested in a friend helpful.