Header RSS Feed
 
If you only want to see the articles of a certain category, please click on the desired category below:
ALL Android Backup BSD Database Hacks Hardware Internet Linux Mail MySQL Monitoring Network Personal PHP Proxy Shell Solaris Unix Virtualization VMware Windows Wyse

Limit http request methods in Nginx (authentication except for GET)
Tuesday - May 31st 2016 - by - (0 comments)

Was looking for a way to tell Nginx to let all GET requests through but all other requests (e.g. POST, PUT, etc) should be authenticated.

On my research I found a lot of examples using "if", like this one (found on https://www.acunetix.com/blog/articles/nginx-server-security-hardening-configuration-1/):

if ($request_method !~ ^(GET|HEAD|POST)$ )
{
    return 444;
}

However there are two problems.

1) if is evil: https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/ 

2) basic auth does not work within an if clause in Nginx. So the following snippet doesn't work:

if ($request_method !~ ^GET$ )
{
  auth_basic "Login required";
  auth_basic_user_file /etc/nginx/auth/.htpasswd;
}

Belive me, I tried it and fell on my nose... On my research WHY it fails, I came across this page: https://t37.net/the-good-the-bad-and-the-ugly-of-virtual-hosting-with-nginx.html, which explains it nicely:

The reason why it fails is because if is not part of the general configuration module as one should believe. if is part of the rewrite module and auth_basic is another module. That’s one of the reason why the Nginx community thinks if is evil.

Eventually I came across the limit_except method, which is part of the Nginx core module. By using this method, one can define special limits for http request methods. The documentation (http://nginx.org/en/docs/http/ngx_http_core_module.html#limit_except) describes the method in a bizarre way though:

Limits allowed HTTP methods inside a location. The method parameter can be one of the following: GET, HEAD, POST, PUT, DELETE, MKCOL, COPY, MOVE, OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, or PATCH. Allowing the GET method makes the HEAD method also allowed. Access to other methods can be limited using the ngx_http_access_module and ngx_http_auth_basic_module modules directives

What I mean with bizarre: It's not clear whether the limitation is now for the mentioned request methods or for the unlisted request methods. But a configuration change quickly showed me that it works the following way:

  location /api/ {

    # Only allow GET, all other methods require basic auth
    limit_except GET {
      auth_basic           "Login required";
      auth_basic_user_file /etc/nginx/auth/.htpasswd;
    }

    include /etc/nginx/proxy.conf;
    proxy_pass       http://127.0.0.1:8080;
  }

The comment I added just above limit_except explains it: Set a limit for all http request methods (load the auth_basic stuff) EXCEPT the request method is GET.

Works nicely and I didn't have to use "if" either.

 

Add a comment

Show form to leave a comment

Comments (newest first):

No comments yet.

Go to Homepage home
Linux Howtos how to's
Monitoring Plugins monitoring plugins
Links links

Valid HTML 4.01 Transitional
Valid CSS!
[Valid RSS]

6939 Days
until Death of Computers
Why?