Trying to combine basicauth with other directives for h5ai restricted access, and some SSL issues depending on the computers used to visit

1. Caddy version (caddy version):

v2.2.1 h1:Q62GWHMtztnvyRU+KPOpw6fNfeCD3SkwH7SfT1Tgt2c=

2. How I run Caddy:

I have a Caddy service (automatically created when installing Caddy on Debian Buster) and I reload my Caddyfile configuration using sudo caddy reload.

a. System environment:

Debian Buster, php7.3-fpm.

b. Command:

sudo systemctl start caddy
sudo caddy reload

c. Service/unit/compose file:

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

d. My complete Caddyfile or JSON config:

mlaparie.fr, www.mlaparie.fr {
        tls ma@email.com
        root * /var/www/mlaparie.fr/wordpress
        # /work/
        handle /work/* {
        php_fastcgi unix//run/php/php7.3-fpm.sock
        file_server
        @no_index {
                not file {
                try_files {path}.html {path} {path}/index.html
                }
        }
        rewrite @no_index /work/_h5ai/public/index.php
        }
        handle /work/_h5ai/private/* {
                respond 404
        }
        # /misc/
        handle /misc/* {
                php_fastcgi unix//run/php/php7.3-fpm.sock
                file_server
                @no_index {
                        not file {
                                try_files {path}.html {path} {path}/index.html
                        }
                }
                rewrite @no_index /misc/_h5ai/public/index.php
        }
        handle /misc/_h5ai/private/* {
                respond 404
        }
        encode gzip
        php_fastcgi unix//run/php/php7.3-fpm.sock
        # Prevent malicious PHP uploads from running
        @uploads {
                path_regexp path /uploads\/(.*)\.php
        }
        rewrite @uploads /
        file_server
}

grav.mlaparie.fr, www.grav.mlaparie.fr {
        tls ma@email.com
        root * /var/www/mlaparie.fr/grav/base
        encode gzip
        php_fastcgi unix//run/php/php7.3-fpm.sock
        file_server
}

mattermost.mlaparie.fr, www.mattermost.mlaparie.fr {
        tls ma@email.com
        reverse_proxy 127.0.0.1:8065
}

syncthing.mlaparie.fr, www.syncthing.mlaparie.fr {
        tls ma@email.com
        reverse_proxy 127.0.0.1:8384 {
                header_up Host 127.0.0.1
        }
}

3. The problem I’m having:

  1. I would like the h5ai browsing mode to be restricted to authenticated users for /work, but I don’t know how to combine caddy’s basicauth with the somewhat complex syntax that currently works for h5ai public access. Failure to authenticate should either redirect to the homepage or throw an error.

  2. I would like the h5ai browsing mode to be restricted to authenticated users for /misc, while allowing access to direct files URL to anyone, provided they got the URL correct. Situational example: if I post an image somewhere, I want all viewers to see it where it was posted, but I want to be the only one with browsing access in /misc to get the exact picture URL in the first place).

  3. Depending on computers (mine, plus reports from friends on their own) and browsers, I sometimes get SSL errors on some of the subdomains or the main domain. What is wrong with my configuration? Could it be some kind of cache or TTL issue that would solve itself if I just wait?

4. Error messages and/or full log output:

N/A

5. What I already tried:

I am new to Caddy (and loving it so far, it’s so much straightforward than Nginx to me), but it is still difficult for me to really know what I am doing for those kind of specific uses. I tried combining the different directives but obviously didn’t do it correctly because caddy reload would throw errors, so I just reverted my changes.

6. Links to relevant resources:

h5ai

You can use request matchers to decide when to require basicauth.

For your “if the file exists, serve it” thing, you can do it like this:

@fileNotExists not file
basicauth @fileNotExists {
	...
}

And you can put that inside your handle blocks.

You may need to use a route block to ensure that rewrites don’t happen before basicauth gets a chance to look at the request paths, due to the default directive order:

Also, I recommend using the caddy fmt command to clean up the indentation in your config. It’s a bit hard to read because the indentation isn’t right.

You can also make those @no_index matchers shorter, like this:

@no_index not file {path}.html {path} {path}/index.html

This uses the single-line named matcher syntax, plus the short file matcher syntax.

You have a lot of repetition in your mlaparie.fr site, I think. Ultimately the only thing your handle blocks are doing is doing some rewrites, since you already have php_fastcgi and file_server at the end. Something like this might work the same:

mlaparie.fr, www.mlaparie.fr {
    tls ma@email.com

    root * /var/www/mlaparie.fr/wordpress

    # Prevent malicious PHP uploads from running
    @uploads path_regexp path /uploads\/(.*)\.php
    rewrite @uploads /

    encode gzip

    handle /work/_h5ai/private/* {
        respond 404
    }
    handle /work/* {
        @no_index not file {path}.html {path} {path}/index.html
        rewrite @no_index /work/_h5ai/public/index.php
    }
    handle /misc/_h5ai/private/* {
        respond 404
    }
    handle /misc/* {
        @no_index not file {path}.html {path} {path}/index.html
        rewrite @no_index /misc/_h5ai/public/index.php
    }

    php_fastcgi unix//run/php/php7.3-fpm.sock   
    file_server
}
1 Like

Thanks a lot for your detailed answer, much appreciated!

So if I understand correctly, you would recommend something like that?

    handle /misc/* {
        @no_index not file {path}.html {path} {path}/index.html
        rewrite @no_index /misc/_h5ai/public/index.php
        @fileNotExists not file
        basicauth @fileNotExists {
	        user base64pass
        }
    }

And same without @fileNotExists if I want restricted access even when the visitor has a full URL to an existing file? I am not sure how to use the route block you suggested.

Additional question: friends and I are having SSL issues with the domains or subdomains I serve with Caddy. The certificates exist and are valid, but I’m wondering if this is because the TTL duration is longer and makes new certificates issued when I caddy reload not be fetched. Is there a way to keep caddy reload from renewing certificates? Or is it another issue?

Regarding SSL errors, this might be the same issue detailed here: Intermittent SSL handshake errors

Time will tell if this is actually a solution, but it seems restarting the Caddy service instead of using caddy reload might solve the problem with my websites too.

Yeah - maybe like this:

    route /misc/* {
        @fileNotExists not file
        basicauth @fileNotExists {
	        user base64pass
        }
        @no_index not file {path}.html {path} {path}/index.html
        rewrite @no_index /misc/_h5ai/public/index.php
    }

route makes sure that they run in that specific order (basicauth before rewrite). route blocks get ordered after handle blocks according to the directive order, but this should still do the right thing for you here.

That’s a bit vague. What are the symptoms?

Caddy only renews certificates when it actually needs to, i.e. when they’re close to being expired. Reloading does run the certificate maintenance routine, but that routine will do nothing if the certificates are still fresh enough.

Unfortunately I’m not prompted for authentication with this: h5ai browse mode is visible to all users. It seems basicauth is ignored. I added the block right after the following:

…
    handle /misc/_h5ai/private/* {
        respond 404
    }

I also tried the code I had posted before your answer, and there I was asked for a password, but it was giving me access for both /work/ and /misc/.

The SSL errors were handshake issues. They seem to happen very frequently and from several machines when using caddy reload in the folder where the Caddyfile is, but all those issues appear to go away when using systemctl restart caddy instead.