# Caddy #homelab #Caddy I use [Caddy](https://caddyserver.com/) as a reverse proxy for the services that need to be reachable from the Internet. So far my takeaway from Caddy is that it flawlessly and magically hosts its own splash page, but anything else is poorly documented. It's like Caddy is made to be so simple and easy, but it relies on some kind of systemic knowledge that is not at all apparent from the docs. Ah, this is what I mean: the docs (which are many, I'll give them that) are all guides. There is very little reference or tutorial material (at least of what I've found so far). ## certbot I'm not sure if I need eft to have certs on it. I'm installing a wildcard just to be sure? I dunno. Following [these steps](https://certbot.eff.org/instructions?ws=other&os=ubuntufocal&tab=wildcard): ```sh sudo apt-get remove certbot sudo snap install --classic certbot sudo ln -s /snap/bin/certbot /usr/bin/certbot sudo snap set certbot trust-plugin-with-root=ok sudo snap install certbot-dns-cloudflare ``` a little pause to [get an api key](https://certbot-dns-cloudflare.readthedocs.io/en/stable/#credentials), then ```sh sudo certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials ~/.certbot/spencerenglish.net/cloudflare.ini \ -d spencerenglish.net Certificate is saved at: /etc/letsencrypt/live/spencerenglish.net/fullchain.pem Key is saved at:         /etc/letsencrypt/live/spencerenglish.net/privkey.pem This certificate expires on 2024-05-20. ``` woohoo! Now, to tell caddy to use this certificate. There's gotta be something in the caddyfile spec, right? train of docs: 1. [automatic https > wildcard certificates](https://caddyserver.com/docs/automatic-https#wildcard-certificates) 2. "Note: Let's Encrypt requires the DNS challenge to obtain wildcard certificates." 3. [automatic https > dns challenge](https://caddyserver.com/docs/automatic-https#dns-challenge) 4. "Learn how to enable the DNS challenge for your provider at our wiki." 5. caddy wiki "[How to use DNS provider modules in Caddy 2](https://caddy.community/t/how-to-use-dns-provider-modules-in-caddy-2/8148/1)" 6. "Go to the [Caddy download page](https://caddyserver.com/download)." 7. "Find your DNS provider in the list of modules (`dns.providers.*`) and select it." (do not click on the github link. do not click on the `dns.provicers...` thing. click on the box itself) 8. "Download your custom Caddy build." (you will need to know your OS and architecture. run `uname -m`. In my case today, eft is an `aarch64`, which is ARM 64) 9. I downloaded it to my laptop, then `scp`d it to eft, then `mv`d it to `/etc/caddy`. 10. then I modify the caddyfile with the below at the top of the file? ``` { acme_dns cloudflare API_TOKEN_HERE } ``` this does not agree with the module's config (if you had clicked on the `dns.providers...` link on the modules listing page, you'd be directed [here](https://caddyserver.com/docs/modules/dns.providers.cloudflare)) ``` { "api_token": "" } ``` also, what was the custom build for? is it an executable I'm supposed to use instead of `caddy`? worth a try, but I don't know how `systemctl` is invoking `caddy`. Gotta track down that recipe (see [[systemctl]]). --- I have swapped out my "vanilla" executable for the custom build I downloaded (I noticed they are both around the same size. so that gave me a little faith). I also did put the `{ acme_dns cloudflare ... }` at the beginning of the Caddyfile and `systemctl restart caddy` worked, and `systemctl status caddy` showed it was running. --- - [x] #project #homelab get leuco.net ssl handshake from cloudflare to eft [completion:: 2025-03-30] - [x] #project #homelab get leuco.ink ssl handshake from cloudflare to eft [completion:: 2025-03-30] I generated new API tokens in the cloudflare dashboard (using the Edit Zone DNS template). Each token is only able to affect 1 zone. I saved these in zone-specific folders in `eft:~/.certbot/ZONE_NAME/cloudflare.ini`. Then I could run ```shell sudo certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials ~/.certbot/ZONE_NAME/cloudflare.ini \ -d ZONE_NAME ``` I had to switch my `/etc/caddy/Caddyfile` configuration from ```Caddyfile { acme_dns cloudflare API_TOKEN } ``` to ```Caddyfile SITE { tls { dns cloudflare API_TOKEN } } ``` and finally a `sudo systemctl restart caddy` maybe now I can: - [ ] #project #homelab get rid of `spencerenglish.net` ## reverse-proxying https Still getting a 502 Bad Gateway in the browser, but at least I now have `journalctl -fu caddy.service` to show me logs as they come in. I have proof that my web request to `vtt.` _is_ hitting eft! It's logging an error though, which traces to [this line of code](https://github.com/caddyserver/caddy/blob/v2.7.6/modules/caddyhttp/reverseproxy/reverseproxy.go#L1267) (the log lists its code line!). It doesn't give me any more trace than that currently, but the rest of the log line does show me that my router is requesting port 80: ``` dial tcp 192.168.0.104:80: connect: connection refused ``` Maybe caddy is reverse-proxying port 80 by default? Maybe if I'm terminating HTTPS at eft I can host my FoundryVTT server on port 80? (It's not like we use the AV features anyway). - [-] #project #homelab #caddy Or maybe I should learn how to get Caddy to forward 443... [This forum post](https://caddy.community/t/best-way-to-reverse-proxy-to-self-signed-https-server/8742) seems relevant, and notably it says: [cancelled:: 2025-03-30] > If you’re talking about TLS passthrough (i.e. having Caddy _not_ terminate TLS and instead pass the connection through entirely to the upstream server so the client negotiates directly with the upstream for HTTPS), that’s not something that Caddy’s HTTP server can handle. HTTP is layer 7, passing through a TCP stream needs to be done by a TCP server (layer 4). Matt Holt’s project Conncept can do this, though: [GitHub - mholt/conncept: Project Conncept: A layer 4 app for Caddy that multiplexes raw TCP/UDP streams](https://github.com/mholt/conncept) But the original poster does present an idea I can try: ```Caddyfile https://example.com { reverse_proxy https://192.168.x.x:port { transport http { tls_insecure_skip_verify } } } ``` HOORAYYY that worked. Now I need to log into panda to regenerate that cert (I think?) and also I should remove the CNAME for `vtt.spencerenglish.com` (done). ## dynamic dns?? coming soon...