Think I’ve gone down the rabbit hole on this one.
I have more than one Debian machine that I host apps on. I want to serve them with https, so I decided it was best to centrally get the domain cert/key (I’ve used certwarden) and use a script/cron job on each server to get the certs. Then use caddy to reverse-proxy.
So, after some research I decided that certs should be placed in /etc/SSL/certs (keys in /etc/SSL/private). Problem is caddy can’t get to them. I’ve tried messing around with permissions etc but I suspect I’m running into issues because I’m not doing this the proper way.
What is the proper way of doing it? Or is there a much easier solution?
I could never get certs working over locally served stuff, but Nginx Proxy Manager made the few things I publish to web fairly easy to get https working. I’m just commenting to come back later and read the answers myself… Let me know if you get it working over Lan!
I always recommended people new to reverse proxies start with Npm. Reverse proxies are designed to do exactly what you’re trying to do, although I’m not sure why you’ve brought in certwarden. In npm just put in the IP:Port of the host (local or remote) same goes for caddy, but in my experience its not as easy to configure as npm
Acronyms, initialisms, abbreviations, contractions, and other phrases which expand to something larger, that I’ve seen in this thread:
Fewer Letters More Letters DNS Domain Name Service/System IP Internet Protocol SSL Secure Sockets Layer, for transparent encryption
3 acronyms in this thread; the most compressed thread commented on today has 15 acronyms.
[Thread #53 for this comm, first seen 1st Feb 2026, 15:40] [FAQ] [Full list] [Contact] [Source code]
The easiest way would be to set up caddy to use acme on the servers, and never care about certificates again. See https://caddyserver.com/docs/automatic-https.
If you insist on your centralized solution, which is perfectly fine imo, just place the certificates to a directory properly accessible to caddy, and make sure to keep the permissions minimal, so that the keys are only accessible by authorized users.
If the certificates are only for caddy, there’s no reason to mess around in system folders.
You mean you have a script that pulls in the cert from a central source (where certwarden renews it), and then caddy can’t access it locally?
Exactly what error is Caddy giving? What permissions have you tried and what was the result? How are you restarting Caddy after renewal? Why do you have multiple reverse proxies?
how about making symlinks to the dir where caddy expects them
I do not understand why you are using certwarden when Caddy can generate SSL certificates by itself.
Because I have more than one server. It made sense to manage the cert in one place then distribute it to the places it needs to be.
Caddy because its easy to use.
But you’re still using Caddy as the sole reverse proxy, don’t you? Do you have multiple Caddy instances that require access to a single certificate?
If you switch to the dns-01 challenge you can just generate the certs on multiple servers hasselfree. And as a bonus you can get wildcard certs for subdomains.
The docs on DNS challenge are here, and a bit further down you can find the ones on wildcard certificates
If you’re solely talking about Caddy using self-signed, just use the caddy directory created for this. Should be simple.
The global /etc/SSL dir is locked down for a reason, and you shouldn’t relax permissions there just so Caddy can get to subdirs.
Look into let’s encrypt and acme. Requires a publicly registered domain though.
Certwarden does that bit. Its making the certs available to caddy that I can’t work out
Does the caddy user have the permissions to read the files ? I ran into that problem as well. If only caddy needs the cert I moved them into /etc/caddy, chowned the dir again, make sure you use the full path of the cert so /etc/caddy/domain.crt not ./domain.crt
Probably need a bit more detail for this like
caddylogs and your caddy config. I did a similar thing on NixOS with services.acme getting the certs and then configuring the cert files to includecaddygroup access (I didn’t use caddy directly either for those reading as the DNS challenge approach requires third party plugins which is a bit annoying on NixOS).Oh certificates are so much fun and you have so many options. From fairly easy to mindboggling complex.
Your current solution is OK if you keep in mind security implications of distributing certs using scripts.
It is not entirely clear where you do your tls-termination but it sounds like that is the Caddy reverse proxy so that is where your certs should be.
Placing them in a location like
/etc/ssl/example_com/asfullchain.pemandprivkey.pemis probably easiest. Make sure access rights are appropriate. Then point Caddy at them and it should work. I have no experience with Caddy itself though. If Caddy runs in Docker be sure to map the certificates into the container.Mind that in this scenario the certificates are only on the Caddy server, connections from the reverse proxy to the services is unencrypted over http. You can’t easily use the LE certificates on the services itself without some ugly split-horizon DNS shenanigans.
Alternatively you can set up a PKI with certificates for your services behind the reverse-proxy for internal encryption and do public tls termination in the proxy with Let’s Encrypt.
You could try to debug the permission issue… Like take a note of the current permissions, chmod the certificates to 666 and the parent directories to 777 and see if that works. Then progressively cut them down again and see when it fails. And/or give caddy all the group permissions ssl, acme, certwarden… and then check which one makes it fail or work.




