2

How can I apply basic auth only if an htaccess file exists?

If first tried to put the auth_basic directives in an if block, but that is not allowed.

Then, I tried redirecting to a named location, but while the location with basic auth works fine, the redirection (which happens when there is no htaccess file) is erroring out.

Here's what that config looks like:

server {
    listen 80;
    server_name ~^(?<instance>.+?)\.foo.example.com$;

    set $htaccess_user_file /var/htaccess/$instance.foo.example.com.htaccess;

    if (!-f $htaccess_user_file) {
        rewrite ^ @foo;
    }

    location / {
        auth_basic "Restricted";
        auth_basic_user_file $htaccess_user_file;

        root /var/www/$instance.foo.example.com;
        try_files $uri /index.html =404;
    }

    location @foo {
        root /var/www/$instance.foo.example.com;
        try_files $uri /index.html =404;
    }
}

And here's the error message I'm getting when there's no htaccess file:

2013/07/12 08:37:08 [error] 32082#0:
*192 open() "/usr/html@foo" failed (2: No such file or directory),
client: 1.2.3.4, server: ~^(?<instance>.+?)\.foo.example.com$,
request: "GET / HTTP/1.1", host: "bar.foo.example.com"

I have a feeling it has to do with some variables getting overwritten by the named location, but I'm not sure.

Finally, I tried using alias in the named location, that way the @foo wouldn't be part of the search dir, but alias are not allowed in named locations.... fuuuu

2 Answers 2

3

This is what MTecknology and kolbyjack advised me to do on #nginx.

server {
    listen 80;
    server_name ~^(?<instance>.+?)\.foo.example.com$;
    root /var/www/$instance.foo.example.com;

    set $htaccess_user_file /var/htaccess/$instance.foo.example.com/.htaccess;

    if (!-f $htaccess_user_file) {
        return 599;
    }

    location / {
        auth_basic "Restricted";
        auth_basic_user_file $htaccess_user_file;

        try_files $uri /index.html =404;
    }

    error_page 599 = @foo;

    location @foo {
        root /var/www/$instance.foo.example.com;
        try_files $uri /index.html =404;
    }
}

Worked flawlessly!

0

An extension of this answer if you have multiple /location entries you need to move the if block into the relevant location.

worker_processes 1;

events {
    worker_connections 1024;
    accept_mutex off;
    use epoll;
}

http {
    include mime.types;
    default_type application/octet-stream;

    sendfile on;

    upstream app_server {
        server localhost:8000 fail_timeout=0;
    }

    server {
        listen 80;

        set $htaccess_user_file /etc/secrets/nginx-proxy/htaccess;

        error_log stderr info;

        keepalive_timeout 5;

        location /static {
            expires 30d;
            add_header Pragma public;
            add_header Cache-Control "public";

            autoindex off;
            alias /mnt/static/;

            gzip on;
            gzip_buffers 16 8k;
            gzip_comp_level 9;
            gzip_http_version 1.0;
            gzip_min_length 0;
            gzip_types text/plain
                text/css
                image/x-icon
                image/svg+xml
                image/png
                image/jpg
                image/jpeg
                text/js
                application/javascript
                application/x-javascript;
            gzip_vary on;
            gzip_proxied expired no-cache no-store private auth;
            gzip_disable "MSIE [1-6]\.";
        }

        location /media {
            autoindex off;
            alias /mnt/media/;
        }

        error_page 599 = @noauth;

        location / {
                if (!-f $htaccess_user_file) {
                        return 599;
                }

                auth_basic "Restricted";
                auth_basic_user_file $htaccess_user_file;
                try_files $uri @proxy_to_app;
        }

        location @noauth {
            try_files $uri @proxy_to_app;
        }

        location @proxy_to_app {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_buffering off;

            proxy_pass http://app_server;
        }
    }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .