1

Currently I'm using nginx as a proxy server to multiple docker containers running in different hosts.

Each container or pair of containers is mapped using a location block in a virtual hosts file, like this dev.conf:

server {
    server_name dev.mydomain.xyz

    location / {
        proxy_pass http://172.16.18.2:8080/dashboard
        proxy_buffering off;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /api {
        proxy_pass http://172.16.18.2:5000/api
        proxy_buffering off;
        proxy_set_header X-Real-IP $remote_addr;
    }
    ...
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/dev.mydomain.xyz/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/dev.mydomain.xyz/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {

    if ($host = dev.mydomain.xyz) {

        return 301 https://$host$request_uri;
        } # managed by Certbot

        server_name dev.mydomain.xyz;
        listen 80;
        return 404; # managed by Certbot
    }

What I would expect of this setup is that if I request a url like: https://dev.mydomain.xyz/aaaaaa it would give me a 404, but instead what is happening is that it is solving to the root block (the first location / block).

What I want to achieve now, for security and usability reasons is to block/deny all requests that are made in the aforementioned way (location block nonexistent/not listed). I saw this question: about a similar issue, but that didn't work as I would expect. Bear in mind that I am using multiple virtual hosts file, all being included by nginx.conf.

Example:

Request to dev.mydomain.xyz/api is allowed and processed
Request to dev.mydomain.xyz/nothing is denied

Nginx is version nginx/1.14.2, installed in a Debian 10 x64 bit. Let me know if there's any additional info needed. Thanks in advance.

EDIT 1 To be clear, by wanted requests I meant the location I have mapped for a given virtual host (it's endpoints), of which each of this locations must be proxied for a different container. So like, requests to / must go to container1, requests to /api must go to container2, etc.

inblank
  • 396
  • 1
  • 8
  • 26
  • Interesting, is there any way I could use some kind of regex to deny the unwanted requests. – inblank Jan 16 '20 at 11:55
  • My accepted requests would be the locations I have mapped (`/`, `/api`, `/database` for example). Thing is, each of those routes must be proxied to a different container. I'll add this information to the post. – inblank Jan 16 '20 at 12:07
  • 1
    Your locations accept URIs that **begin with** `/api` and as I said, `location /` accepts URIs that **begin with** `/` (which is everything else). If you want to just process the `/`, `/api` and `/database` URI, use the `=` modifier. See [this document](http://nginx.org/en/docs/http/ngx_http_core_module.html#location). – Richard Smith Jan 16 '20 at 12:57
  • Oh, I see what you mean, I looked up this part of the docs and it didn't looked like what I wanted to do. Could you post a proper answer so I can mark this as solved? – inblank Jan 16 '20 at 13:36

1 Answers1

1

The location / { ... } block is the default location and used to process any requests that do not match any other more specific location statement. The rules for location processing is documented here.

The location /api { ... } block is a prefix location that matches any URI that begins with /api.

If you want to only proxy the specific URIs / and /api, then use the location directive with an = operator. For example:

location / {
    return 403;
}
location = / {
    # proxy for only /
}
location = /api {
    # proxy for only /api
}

The above will return a "Forbidden" status code for any URI except / and /api.

However, a very strict approach will not work for most applications, as there are generally a multiutde of resource files (e.g. *.css, *.js) with unique URIs that also need to be handled by the server or its upstream proxies.

Richard Smith
  • 45,711
  • 6
  • 82
  • 81