nginx deny to allow a single IP

Juicy asked:

I’m trying to set up an nginx config that allows only one source IP to access /admin.

I tried the following nginx.conf:

user root;

events {
}

http {
  server {
    listen       5000;

    location /admin {
      allow 1.2.3.4;
      deny all;
      return 200;
    }
  }
}

What I was expecting:

Only requests originating from 1.2.3.4 would receive the 200 OK response. Other requests would receive a 403 Unauthorised.

What I’m seeing:

Regardless of the source IP, I’m getting a 200 OK response.

$ docker run -it -v /tmp/test/nginx.conf:/etc/nginx/nginx.conf -p 127.0.0.1:5000:5000 nginx:alpine
...
$ curl localhost:5000/admin -v
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5000 (#0)
> GET /admin HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx/1.15.11
< Date: Sun, 14 Apr 2019 20:33:32 GMT
< Content-Type: text/plain
< Content-Length: 0
< Connection: keep-alive

How can I whitelist a certain IP address for a path in nginx?

My answer:


The return statement is processed in the nginx rewrite phase, which is before the access phase where access control is checked.

To solve the problem, put in a real configuration for your virtual server instead of a “test” configuration. For instance, set a document root and put an index.html file in it, or proxy_pass to a web application.


View the full question and any other answers on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.