Search code examples
nginxnginx-configdigest-authentication

NGINX Digest, limit_except GET, but allow localhost


I am trying to configure Digest Auth in nginx, I am using the unoffical module for that, NGINX Digest module, and for the most part I can get it to work just fine, I am able to lock down an endpoint, unless it's a GET, here is my location config.

location /config {
    proxy_pass http://internal_config_service/config;
    
    limit_except GET {
        auth_digest "peek a boo";
    }
}

However, I have a scenario, where I want to allow localhost to be unchallenged, and I'm not really finding a great way to do that.

Things I've explored, I've tried allow 127.0.0.1; I've even looked into trying to do something with if and checking $host is local, and not adding the digest directives, but I don't think that's even possible, because my understanding is config is pretty static.

The one solution I can think of that might work, but requires a fair amount of work, and extra confusion to someone new, is to basically create 2 servers, one that is accessible by localhost only, and allows localhost through unchallenged, and cannot be accessed externally. And then a 2nd server that is publicly accessible and is locked down with digest.

I'm hoping for a better solution, but I am still kind of learning the intricacies of NGINX as I go, but not optimistic of a better solution.


Solution

  • you can use the satisfy directive: http://nginx.org/en/docs/http/ngx_http_core_module.html#satisfy

    The problem: I dont know if the auth_digest (unofficial module) will be part auf the Auth-Face in the NGINX request processing. But, if this is the case you can make use of auth_request in addition. But give this a try:

    ...
    location /authreq {
    
      satisfy any;
      allow 127.0.0.1;
      deny all;
      auth_digest "something";
      # If auth_digest is not working try
      auth_request /_authdigest;
    
    }
    
    location = /_authdigest {
      internal;
      auth_digest "something";
    }
    

    Update to your question regarding allow 127.0.0.1; deny all

    This will NOT block all other clients / traffic. Its telling NGINX in combination with satisfy any that if the IP is not 127.0.0.1 any other auth function (auth_basic, auth_jwt, auth_request) has to be successfull to let the request pass. In my demo: If I am not send a request to localhost I will have to go through the auth_request location. If the auth_request is something like 200 it satisfies my configuration and I am allowed to be connected to the proxy upstream.

    I have build a little njs script disabling the auth_digest for the user and authenticating the proxy request against an digest auth protected backend. But thats not what you need, isnt't it?

    If you want to split up the configuration one for localhost and the other one for the public ip your server configuration could look like this:

    server {
      listen 127.0.0.1:80;
    
      ## do localhost configuration here
    }
    
    server {
       listen 80;
     ## apply configuration for the IP of nic eth0 (for example) here.
    }