Nginx not returning custom error page when user fails to authenticate

17 Views Asked by At

I am using HTTP Basic Auth with Nginx and when I send a curl request without credentials or fail to provide credentials on my browser I get default Nginx 401 error page instead of the custom one I have provided. e40x.html is in right place because I get custom response when I send a POST request using curl, so we can ignore all of that.

Nginx is used as a reverse proxy for another app that is running in Docker container, but all of that can also be ignored since it is working well. Please ignore everything except for error page handling.

My nginx.conf:

server {
    listen 3000;
    server_name .domain.com;

    # Custom errors redirect
    error_page 400 401 402 403 404 405 /e40x.html;
    error_page 500 501 502 503 504 /e50x.html;
    
    # Basic auth definition
    auth_basic "Restricted Content";
    auth_basic_user_file /etc/nginx/conf/.htpasswd;

    # Disable server tokens
    server_tokens off;
    more_set_headers 'Server: My-Value';

    location / {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        limit_except GET {
            deny all;
        }
    }

    location /health {
        auth_basic off;
        proxy_pass http://localhost:3001/health;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        limit_except GET {
            deny all;
        }
    }

    # Custom errors definitions
    location = /e50x.html {
        root /etc/nginx/conf;
        allow all;
        internal;
    }

    location = /e40x.html {
        root /etc/nginx/conf;
        allow all;
        internal;
    }

    # Security headers definition
    add_header Content-Security-Policy "connect-src 'self' *.domain.com; font-src 'self' *.googleapis.com *.gstatic.com; frame-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' *.googleapis.com 'unsafe-inline'; frame-ancestors 'self'; img-src 'self' data: ; manifest-src 'self'; media-src 'self'; object-src 'self'; worker-src 'self';" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
    add_header X-Content-Type-Options "nosniff";
    add_header X-Frame-Options "DENY";
    
}

I tried resolving this in multiple ways, but I am unable to give snippets, as all of those tries made nginx fail so I didn't save them.

First I thought there has to be something wrong with indentation, but I am not sure why nginx doesn't serve my custom error page instead of the default one.

After losing a couple of hours for this I think it has to do something to do with authentication, but I am not sure how to handle it.

I also tried finding the default error pages to just edit the content there, but I wasn't able to find them.

1

There are 1 best solutions below

0
hermanoff On

I have found a solution. It was pretty simple in the end. It indeed was an auth problem. Since I wasn't able to pass the auth, I was receiving default nginx 401 html page.

The solution was setting basic auth to off for my custom error pages:

location = /e50x.html {
    auth_basic off;
    root /etc/nginx/conf;
    allow all;
    internal;
}

location = /e40x.html {
    auth_basic off;
    root /etc/nginx/conf;
    allow all;
    internal;
}