This Ansible repo sets up a Caddy reverse proxy for my homelab services. It integrates with the Crowdsec plugin that runs on my OPNsense box.
- OPNsense: Protectli FW4C, Intel Pentium J3710, 4GB RAM
- VM on Proxmox host, 2GB RAM, 4 CPU of Intel Celeron N5105
Dustin Casto wrote an outstanding guide on this setup on his website. I automated it with Ansible.
Caddy runs on a VM in Proxmox on a DMZ network. I access it via Tailscale, and it redirects me to the desired service.
Every service runs with a valid HTTPS certificate. I use a wildcard certificate because it's easier to manage. I also found that retrieving certificates for each subdomain is very unreliable on my network and might take hours.
I also do some SSH hardening and set up a UFW firewall.
- Cloudflare account with an API key with permissions:
Zone.Zone Read
andZone.DNS Edit
. You need to set up this keyroles/reverse_proxy/files/caddy_override.conf
file. - I use OPNsense as my firewall. However, it should be possible to modify this playbook to just install and set up Caddy.
- A domain name, since we want valid HTTPS certificates.
- Ubuntu. This setup has been tested on Ubuntu 24.04, but should work on any Debian-based system.
- Public key for SSH authentication is set in the root of the repository in the
files/ansible.pub
file. - The Ansible user is called
hedgehog
🦔. You are free to change it.
This repo assumes that you have set up Crowdsec on OPNsense according to Dustin's guide. During the playbook's run, it will pause and ask you to validate the Caddy machine in OPNsense. Make sure you do it as described in the guide.
This repo builds Caddy with the Cloudflare plugin to perform the DNS-01 challenge to validate that you own a domain. This guide might be helpful
- Create the inventory. The repo assumes the file is called
inventory
. - Define host variables in
host_vars/caddyDMZ.yml
. The comments in the example file should be helpful. - Set up your Caddyfile in
roles/reverse_proxy/files
. See the provided example for ideas. I am using Authentik for some of the apps that do not provide built-in authentication. - Set up
caddy_override.conf
. It only contains the Cloudflare API token. Keep it safe! - In root directory create the
files/public_keys/ansible.pub
key, containing your public key thebase
role will transfer to the Caddy machine.
Remove the .example
extension from the provided files.
- Provided you have Ansible installed and
inventory
andansible.cfg
files created, you need to runansible-playbook bootsrap.yml
. It will create a specified Ansible user and give itsudo
rights. From now on, you can run any Ansible playbook as this user. - Run
ansible-playbook caddy.yml
.
- I use
unattended-upgrades
to upgrade the system. It also might reboot if it's necessary after the update. That's not ideal if you want 100% availability and stability because things can break after an update. Ubuntu is a rather stable system, and I only automatically install security updates; it should not break after a reboot. - I took steps to harden SSH and set up a firewall, but it is not a super-protected system. I do not expose any ports on my home network and use public key authentication for SSH, so this security level works for me.
- If you are inside your home network, you can set up OPNsense to override IP address that are returned by DNS. Now, if you request
service.example.com
, you will not query a remote DNS server, and the domain will resolve immediately to your local IP. See Unbound DNS Override Aliases in OPNsense for more information.
This is still work-in-progress. I use Tailscale to access my network. Currently, I install and set up Tailscale manually.
- Dustin Casto for the amazing guide, Set Up a Caddy Reverse Proxy with Let's Encrypt and CrowdSec Using OPNsense LAPI, this repo is based.
- Jay LaCroix's excellent Ansible video series.
- Jim's Garage for changing the way I create new VMs.
- Software developers whose work made this repo possible.
The repo is available on: