0

I have a running website where I have a specific directory where I store random stuff (it sounds very informal and it indeed is).

So, I wanted to have some sort of index there that lists the contents of that directory (and subdirectories). autoindex would work perfectly.

Then, I don't really want others to browse that index. auth_basic would work perfectly.

But, I'd like to be able to link to specific files or directories inside that directory (that is a directory that does contain an index file and not an autoindex) without having them password protected.

So, the final idea would be to have a location with autoindices that are password protected with basic auth but leaving the rest of the files and directories untouched.

I came up with a hacky solution that works: since an HTTP status 403 is issued when an index that does not exist is accessed, I redirect that to a custom location block that enables autoindex with auth_basic.

See here an example:

server {
    root ...;
    index index.php index.html index.htm;
    server_name ...;
    access_log ...;
    error_log ...;

    # general site
    location / {
        try_files $uri $uri/ @rewrite;
        location ~ \.php(/|$) {
            include fastcgi.conf;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
            fastcgi_param DOCUMENT_ROOT $realpath_root;
            try_files $uri $uri/;
            fastcgi_pass unix:/run/php/php-fpm-....sock;
        }
    }

    # rewrite for the general site
    /location @rewrite {
        rewrite ...;
    }

    # that specific directory
    location /directory {
        try_files $uri $uri/ =404;
        error_page 403 = @autoindex; # hack 1

        location ~ \.php(/|$) {
            # include snippets/fastcgi-php.conf;
            include fastcgi.conf;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
            fastcgi_param DOCUMENT_ROOT $realpath_root;
            try_files $uri $uri/;
            fastcgi_pass unix:/run/php/php-fpm-....sock;
        }
    }
    
    # password-protected autoindices
    location @autoindex {
        autoindex on;
        autoindex_exact_size off;
        auth_basic "directory";
        auth_basic_user_file /.../.htpasswd;
    }
}

So... is there a better idea? Is this hack a bad idea?

Thank you!

0

1 Answer 1

0

So, the final idea would be to have a location with autoindices that are password protected with basic auth but leaving the rest of the files and directories untouched.

Try using regex location to specify any locations you need to protect with basic_auth.

Prefix-based location will always checked first, but used last, after all regex-based location checked. If no regex-based location matches current request, longest-matching prefix-based location will be used.

Here, you can do something like

index index.html;

location ~ /directory(/$|$) { # http://example.com/directory, http://example.com/directory/
    autoindex on;
    autoindex_exact_size off;
    auth_basic "directory";
    auth_basic_user_file /.../.htpasswd;
}

location /directory { # http://example.com/directory/favicon.ico
    try_files $uri $uri/ =404;

    location ~ \.php(/|$) {
        # include snippets/fastcgi-php.conf;
        include fastcgi.conf;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        try_files $uri $uri/;
        fastcgi_pass unix:/run/php/php-fpm-....sock;
    }
}

Using http://example.com as your base URL:

  • any requests to http://example.com/directory and http://example.com/directory/ will be autoindex-ed and having auth_basic enabled, according to location ~ /directory(/$|$) directive.
  • any other requests to http://example.com/directory/* will be served according to location /directory directive.
2
  • Aha, but what about requests to http;//example.com/directory/inner/? I'd like to have those _autoindex_ed. And then, what would happen if http://example.com/directory/other/ does have an index.html file? I'd like that to be served. Thanks!
    – nerestaren
    May 14, 2021 at 18:40
  • would specifying the directories manually suffice, e.g. location ~ /(directory|directory/inner)(/$|$) {? and any directories with index.html, as long as index directive is set with index.html and regex-based location doesn't include the directory, its index.html will be served.
    – mforsetti
    May 14, 2021 at 18:45

You must log in to answer this question.

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