Restrictions are made in NGINX based on the user's real IP

This article was last updated on: February 7, 2024 pm

demand

It needs to be restricted based on the user’s real IP, but NGINX also has an F5 in front of it, which leads deny The instruction does not take effect.

Block the user’s real IP No 192.168.14.* and 192.168.15.* Access request.

implement

The simplest implementation is as follows:

📓 preconditions:

The load balancer device (such as F5) on the front of nginx needs to be turned on X-Forwarded-For In the tank.

1
2
3
4
5
proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

if ($proxy_add_x_forwarded_for !~ "192\.168\.1[45]") {
return 403;
}

The instructions are as follows:

  • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; Gets the request header X-Forwarded-For and attach to the user’s real IP $proxy_add_x_forwarded_for variable
  • if...
    • (...) variable $proxy_add_x_forwarded_for Does not match the regular 192\.168\.1[45] (ie 192.168.14.* and 192.168.15.*)
    • return 403, if the above condition is met, returns 403
    • Namely: if the real IP is not 192.168.14.* and 192.168.15.*, returns 403.

If you have more complex needs, you can refer to this example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
proxy_set_header HOST $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

if ($http_host ~ "yourdomain.hypernode.io:8443") {
set $block_me_now A;
}

if ($proxy_add_x_forwarded_for != YOURIP) {
set $block_me_now "${block_me_now}B";
}


if ($block_me_now = AB) {
return 403;
break;
}

Why deny Configuration not working?

🤔 Question: Why doesn’t the following configuration work?

1
2
3
allow 192.168.14.0/24;
allow 192.168.15.0/24;
deny all;

According to the official nginx documentation, deny Directives are restricted according to the “client address”.

📓 Reference:

The ngx_http_access_module module allows limiting access to certain client addresses.

The variables corresponding to “client address” are: $remote_addr

📓 Reference:

$remote_addr:
​ client address

concerning $remote_addr:

It is the real address of the client obtained by nginx during the TCP connection with the client. The Remote Address cannot be forged because a three-way handshake is required to establish a TCP connection, and if the source IP is forged, a TCP connection cannot be established, let alone a subsequent HTTP request

remote_addr Represents the IP of the client, but its value is not provided by the client, but the server is specified according to the IP of the client, when your browser visits a website, assuming there is no proxy in the middle, then the web server of the website (Nginx, Apache, etc.) will put it remote_addr Set it to your machine IP, if you use a proxy (in fact, F5 is this reverse proxy), then your browser will first access this proxy, and then this proxy will forward to the website, so that the web server will put it remote_addr Set to the IP of this proxy machine.

But in fact, in some special scenarios, even if we have an agent, we need to put it $remote_addr Set to the real user IP so that it can be recorded in the log, of course, nginx has this function, but it needs to be added when compiling --with-http_realip_module This module, by default, is not installed. (I didn’t install it either)


Restrictions are made in NGINX based on the user's real IP
https://e-whisper.com/posts/36827/
Author
east4ming
Posted on
September 26, 2021
Licensed under