Danny Beckett
Danny Beckett

Reputation: 20806

How to change Nginx to deny by default instead of allow, when using X-Forwarded-For, with visitors inside the LAN allowed access without a login?

In an Nginx config we have the following code to allow viewing the site from inside the LAN without a login, otherwise require a login if outside the LAN:

real_ip_header X-Forwarded-For;
# IPs trusted to forward the visitor's remote IP (our reverse proxy)
set_real_ip_from 172.17.0.1;
set_real_ip_from 192.168.1.1;

location / {
    satisfy               any;

    # Allow visitors inside the LAN to access the site without a login
    allow                 10.0.0.0/8;
    allow                 127.0.0.1/32;
    allow                 172.16.0.0/12;
    allow                 192.168.0.0/16;

    # Require a login for visitors outside the LAN
    deny                  all;
    auth_basic            "Login required";
    auth_basic_user_file  /etc/nginx/.htpasswd;

    # Basic config
    root                  /usr/share/nginx/html;
    index                 index.html;
}

is running inside a container. Visits to the site are made through a running on at 192.168.1.1 using .

Initially we were using . Visits to the site from an external internet IP would show up as being made from 172.17.0.1 - which I understand is the IP address of the gateway between the Docker host and the bridge network on default networking. This required the use of set_real_ip_from 172.17.0.1 (/ ) in order to show the real IP of the visitor and therefore require a login. Note that it did not show the reverse proxy server’s IP of 192.168.1.1 at this point, it instead showed 172.17.0.1.

When we switched to another server, running (not Docker Desktop), visits to the site now show up as being made from 192.168.1.1 - the actual IP address of our pfSense router (our reverse proxy). This meant we had to switch it to set_real_ip_from 192.168.1.1; in order for external visitors to be shown a login prompt. Otherwise internet users would be able to access the site without a login.

How can we flip this so that it denies by default? Currently if for any reason the IP address changes again, visits to the site would be allowed to all users (I.E. those outside the LAN/on the external internet), without requiring a login - since our reverse proxy is inside the LAN - so Nginx would think their IP was E.G. 192.168.123.45 - instead of their external IP, E.G. 99.88.77.66.

Should real_ip_recursive be set to on?

The site that this is protecting is purely HTML files (about 100 files at the moment) - there are no PHP files, but the server is capable of running PHP. Maybe there is an outside-of-the-box solution, such as incorporating some GitHub PHP project to do the login/logout/etc. Or some other indirect way of solving this problem.

Upvotes: 3

Views: 490

Answers (1)

Anastasios3
Anastasios3

Reputation: 129

real_ip_header X-Forwarded-For;
real_ip_recursive on;

set_real_ip_from 172.17.0.1;
set_real_ip_from 192.168.1.1;

location / {
    satisfy any;
    
    deny all;
    allow 10.0.0.0/8;
    allow 127.0.0.1/32;
    allow 172.16.0.0/12;
    allow 192.168.0.0/16;

    auth_basic "Login required";
    auth_basic_user_file /etc/nginx/.htpasswd;

    root /usr/share/nginx/html;
    index index.html;
}

Set real_ip_recursive on; to get last IP in X-Forwarded-For. Deny all first, then allow LAN IPs. This make deny default.

Upvotes: 0

Related Questions