skip to Main Content

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.

2

Answers


  1. 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.

    Login or Signup to reply.
  2. You can try this out and let me know:

    Step 1: Enable Real IP Recursive
    Set real_ip_recursive to on to make sure Nginx uses the correct client IP from the X-Forwarded-For header.
    
    Step 2: Configure the Trusted Proxy IPs
    Ensure you configure the set_real_ip_from directives for all trusted proxies.
    
    Step 3: Deny by Default
    Deny access by default and allow access only to the trusted internal IP ranges without authentication.
    
    Updated Nginx Configuration
    
    
    http {
        real_ip_header X-Forwarded-For;
        real_ip_recursive on;
    
        # IPs trusted to forward the visitor's remote IP (your reverse proxies)
        set_real_ip_from 192.168.1.1; # pfSense proxy
        set_real_ip_from 172.17.0.1;  # Docker default gateway (adjust as needed)
        set_real_ip_from 10.0.0.0/8;  # Example for internal network (adjust as needed)
        set_real_ip_from 172.16.0.0/12;
        set_real_ip_from 192.168.0.0/16;
    
        server {
            listen 80;
    
            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;
            }
        }
    }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search