Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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

share|improve this question
up vote 2 down vote accepted

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!

share|improve this answer

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;
        }
    }
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.