1. The problem I’m having:
Suppose I’m running Caddy on a server; one Caddy instance serving multiple domains with different static websites and applications.
I’d like to keep the Caddy configs to each website in that website’s Git repository. That way, it’s easy to set up a local development server. Also, the config is right where the code is, ensuring that they don’t diverge.
In the most simple setup, I’d clone the Git repo to the web server and have it import the Caddyfile from the repo.
However, if a malicious actor gets access to one of the repositories, they can basically mess around with the whole server’s config, introduce new domains, serve every directory the Caddy user has access to (including the data directory with certificate keys) etc.
Since import is basically string replacement, even if I try to lock a website into a block like this
example.com {
import /srv/example.com/Caddyfile
}
the imported Caddyfile can still break out of this by containing something like
}
example.org {
root * /var/lib/caddy/.local/share/caddy/certificates
file_server browse
- What would be a good way to prevent this?
- Does Caddy have any safety measures that allow restricting the directories it’s serving requests from, e.g. by defining some restrictions in the global options?
I recognize that I might have bigger problems when someone compromises the repository of any of the websites; this question is about damage control by utilizing multiple layers of security.
One thing I could do would be to:
- have a top-level Caddy instance with a fixed config, that terminates TLS and reverse-proxies each of the websites
- which are in turn running on a separate Caddy instance each and are “jailed” using the namespacing/chroot capabilities of my OS.
This would prevent the individual websites to access the rest of the system (including certificate keys), and also limit the amount of damage they could do with a maliciously modified configuration. For example, if they define additional domains, they would not be routed to them via the top-level instance.
Do you see other possibilities?
2. Error messages and/or full log output:
(Irrelevant, this is a conceptual/architectural question.)
3. Caddy version:
2.6.2
4. How I installed and ran Caddy:
Debian package.
a. System environment:
Debian 12 amd64 with systemd.
[removed the rest of the template questions since they’re not relevant here]