Protecting a location by IP while applying basic auth everywhere else

7,929

As you've found, it isn't advisable to but the auth settings at the server level because they will apply to all locations. While it is possible to turn basic auth off there doesn't appear to be a way to clear an existing IP whitelist.

A better solution would be to add the authentication to the / location so that it isn't inherited by /hello.

The problem comes if you have other locations that require the basic auth and IP whitelisting in which case it might be worth considering moving the auth components to an include file or nesting them under /.

server {
    listen 80 default;

    # Lock down the "root" directory to specific IP addresses
    location / {
        satisfy any;

        # Basic auth
        auth_basic "Restricted";
        auth_basic_user_file /etc/nginx/.htpasswd;

        # IP whitelist
        include /etc/nginx/conf.d/ip-whitelist.conf.include;
        deny all;

        # Inherits auth settings from parent
        location ~ \.php$ {
            # PHP specific config
        }
    }

    # Lock down the "hello" directory to specific IP addresses
    location /hello/ {
        # Developers only - ever!
        allow 12.34.56.78;
        deny all;
    }
    # ...
}
Share:
7,929

Related videos on Youtube

scrowler
Author by

scrowler

engineering @ properly / former silverstripe core team and commerce.js twitter / github

Updated on September 18, 2022

Comments

  • scrowler
    scrowler almost 2 years

    I want to achieve the following results:

    • Apply basic authentication to ANY location, file, path
    • Remove basic authentication for an IP/CIDR range whitelist
    • Prevent ALL access to a specific directory, and everything underneath it, for everyone except one IP address (the above included)

    This is the nginx configuration I'm using:

    server {
        listen 80 default;
    
        # Basic auth
        auth_basic "Restricted";
        auth_basic_user_file /etc/nginx/.htpasswd;
    
        satisfy any;
        # IP whitelist
        include /etc/nginx/conf.d/ip-whitelist.conf.include;
        deny all;
    
        # Lock down the "hello" directory to specific IP addresses
        location /hello/ {
            # Developers only - ever!
            allow 12.34.56.78;
            deny all;
        }
        # ...
    }
    

    What's happening at the moment is that point one and two in the bullet list above are working - that is that any IP in the whitelist has no basic authentication across the site, but if the IP is not whitelisted then they are prompted for basic authentication.

    The location block for "hello" however doesn't seem to work, and is still allowing the same conditions as above for anything under the "hello" directory, e.g. if I try to access /hello/world.php from a whitelisted IP, it is served. If I access it from a non-whitelisted IP, I get basic authentication.

    I want to prevent any access to the "hello" directory for everyone other than the IP 12.34.56.78 (example).

    What do I need to change?