user5539517
user5539517

Reputation:

Nginx allow only root and api locations

I have a server configured as a reverse proxy to my server. I want to reject all the requests except to two locations, one for root and another the api root.

so the server should only allow requests to the given paths

example.com/ (only the root)
example.com/api/ (every url after the api root)

The expected behaviour is that the server should reject all the below possibilities.

example.com/location
example.com/location/sublocation
example.com/dynamic-location

my current nginx configuration,

server {

   # server configurations

   location / {

        # reverse proxy configurations

    }

}

How do I set up this configuration?

Upvotes: 8

Views: 26714

Answers (2)

cnst
cnst

Reputation: 27218

You could use an if statement to test for $request_uri being equal to root, or starting from /api/, all within the same location statement, or within the server context:

if ($request_uri !~ ^/$|^/api/) {return 403;}

However, alternatively, due to the way processing is done, the most efficient way with nginx would be to have 3 separate location directives, each handling one of the 3 possibilities — the / root exact match, the /api/ prefix, and then all the other stuff, as per http://nginx.org/r/location.

Additionally, if you also require that the root location prohibit the the query string, you can either test for $is_args (or $args/$query_string as appropriate), or, outright test whether the whole request URL is exactly / or whether it has anything more to it (note that location directives themselves don't operate based on $request_uri, but based on $uri, which are slightly different).

location = / {
    # handle root
    if ($request_uri != "/") {
        # ensure $query_string and $is_args are not allowed
        return 403 "<h1>403: query_string not allowed</h1>\n";
    }
}
location /api/ {
    # handle the /api/ prefix
}

location / {
    # handle everything else
    return 403;
}

Upvotes: 6

Oleg Kuralenko
Oleg Kuralenko

Reputation: 11553

Here it is:

   location = / {
        # would serve only the root
        # ...
    }

    location /api/ {
        # would serve everything after the /api/
        # ...
    }

You need a special '=' modifier for the root location to work as expected

From the docs:

Using the “=” modifier it is possible to define an exact match of URI and location. If an exact match is found, the search terminates. For example, if a “/” request happens frequently, defining “location = /” will speed up the processing of these requests, as search terminates right after the first comparison.

Upvotes: 12

Related Questions