:INFO Why Let's Encrypt Cannot Help With Local Hostnames Let's Encrypt validates domain ownership by making an HTTP request to your domain (HTTP-01 challenge) or by checking a DNS record you control (DNS-01 challenge). Both require a publicly reachable hostname. Your internal services — nextcloud.home.example.com resolving to 192.168.1.50 — are not reachable from the public internet, so Let's Encrypt cannot issue certificates for them. Without a trusted certificate, every browser on every device shows a warning every time anyone visits an internal service. Running step-ca as your own private CA eliminates that permanently. :PATH Install step-ca and Initialize the CA Download the step CLI tool and step-ca server from Smallstep's releases page for your architecture (arm64 for Raspberry Pi 5, armv7 for older models). Install the binaries to /usr/local/bin. Run step ca init to start an interactive setup: choose a name fo :PATH Add the Root Certificate to Your Trust Stores The root certificate file is at $(step path)/certs/root_ca.crt. On Linux, copy it to /usr/local/share/ca-certificates/ with a .crt extension and run sudo update-ca-certificates. On macOS, open Keychain Access, drag in the certificate, double-click it, and :PATH Issue a Certificate for a Local Service With step-ca running, use the step CLI to request a certificate for your service. Run step ca certificate nextcloud.home.example.com nextcloud.crt nextcloud.key — step will contact the CA, authenticate via the provisioner password, and write the signed ce :PATH Configure the ACME Endpoint for Automatic Renewal step-ca can serve an ACME endpoint so that Caddy uses the same ACME protocol it uses with Let's Encrypt, but against your local CA instead. In your CA configuration file (~/.step/config/ca.json), add an ACME provisioner. In the Caddyfile, add a tls block :PATH Understand Mutual TLS for Internal Services Mutual TLS (mTLS) means both sides of a connection present certificates — the server proves its identity to the client, and the client proves its identity to the server. This is more powerful than password authentication for service-to-service communicati :CHECKLIST Steps to Trust the CA on All Devices [ ] Linux: copy root_ca.crt to /usr/local/share/ca-certificates and run update-ca-certificates [ ] macOS: import into Keychain and set to Always Trust [ ] Windows: import into Trusted Root Certification Authorities via certmgr.msc [ ] iOS: install profile via Safari, then enable full trust in Settings under Certificate Trust Settings [ ] Android: install via Settings > Security > Install from storage :NOTE If you ever need to rotate the root CA — because the key was compromised or the cert is expiring — you must redistribute the new root certificate to every device's trust store before the old one expires. Plan for this from the start. Keep a list of every device you trusted the CA on. Treat the root CA private key with the same care as a master password — it can sign any certificate your devices will trust without question. :INFO What Comes Next Your CA issues certificates using public-key cryptography — a root key signs an intermediate key, which signs your service keys. Those signatures are the building blocks you have been taking on faith until now. A password manager holds the secrets that protect those keys, and it turns out that self-hosting your password vault on your own infrastructure is a satisfying next step in this chain. :SLATE 996 :LINK https://smallstep.com/docs/step-ca/ step-ca documentation