13

I want to secure some locations in nginx by supplying deny/allow directives, but I do not want outsider to know that a location is denied. I want outsider to get 404, not 403 http code. My configuration snippet is

location /admin/ {
    uwsgi_pass myupstream1;
    include /path/to/uwsgi_params;

    allow 127.0.0.1;
    deny all;
}

When I try to visit /admin/ nginx responds with HTTP 403, but I want it respond with HTTP 404. Any recipe for this?

Dmitry Mugtasimov
  • 3,858
  • 2
  • 18
  • 26

4 Answers4

10
error_page 403 404 /404.html;

location = /404.html {
    internal; #return 404
}

location /admin/ {
    uwsgi_pass myupstream1;
    include /path/to/uwsgi_params;

    allow 127.0.0.1;
    deny all;
}

The 'internal' returns 404 by default.

Adapted from this answer here

Community
  • 1
  • 1
ARGB32
  • 109
  • 1
  • 6
  • Does this actually return the right error code, or just the right resource? – Nathan Tuggy Feb 03 '15 at 01:03
  • I haven't checked the response headers but I'd assume it's going to respond 403. I found another solution which might work a lot better. – ARGB32 Feb 04 '15 at 01:24
  • But this will change all 403 to 404, or not? I like the other answer more where you add the `return 404;` line after deny. – therealmarv Jul 27 '15 at 01:05
  • This will indeed change all 403 responses to 404. If you wanted to make this behaviour specific to /admin/ you would move the 'error_page 403 404 /404.html;' into its location block – Neil Bryson May 17 '17 at 14:06
  • 2
    While this answer does work, the nginx docs suggest that the first line should have an assignment operator i.e. 'error_page 403 =404 /404.html;' – Neil Bryson May 17 '17 at 14:09
2

A more elegant way is to create a custom error page. In that page instead of showing http error code, you can specify a custom message.

Name an error page

error_page 403 =404 /40X.html;

    location /admin/ {
        uwsgi_pass myupstream1;
        include /path/to/uwsgi_params;
        allow 127.0.0.1;
        deny all;  
    }

    location /40X.html {
    root path/to/public;
    }

In your 40x.html you can write any message

<html>
<body> The requested resource is not available </body>
</html>

place this 40x.html in your path/to/public directory

dev0z
  • 2,275
  • 1
  • 15
  • 16
  • Thanks for this. Already had this in my config file for the 50x didn't know this was the way of doing things, really nice, know they don't know if a location actually exists or not :) – Rens Tillmann Nov 12 '15 at 18:59
  • I verified the returned 404 headers with addons.mozilla.org/en-US/firefox/addon/live-http-headers - using `internal` in the `/40X.html` stanza (instead of `root path`) returns the default `404` page. – Stuart Cardall Mar 02 '16 at 22:42
-1

You can use "rewrite" instead of "deny all"

location /admin/ {
    uwsgi_pass myupstream1;
    include /path/to/uwsgi_params;

    #allow 127.0.0.1;
    #deny all;

    rewrite ^/admin/(.*)$ /404.php?id=$1;

}

Put 404.php into the root of your domain (eg _http://127.0.0.1/404.php) or change "path/to/file/404.php?id=$1"

Jonny
  • 29
  • 1
  • 2
-2

return 404; will do what you want . Look bellow

    location /admin/ {
        uwsgi_pass myupstream1;
        include /path/to/uwsgi_params;

        allow 127.0.0.1;
        deny all;
        #Following line returns 404
        return 404;
    }
Omid Kosari
  • 287
  • 5
  • 16