Split DNS with Cloudflare, Unifi, and Caddy
As homelabbers do, I have many services running on devices within my home network. Some I want accessible internally only, and others I want to be able to access externally. Therefore it was time to setup a split DNS configuration.
This domain name, millwoodonline.co.uk is managed on Cloudflare, and my home network utilizes Ubiquiti Unifi, which also manages the DNS, although a similar setup could probably be possible with PiHole or similar.
One could argue, my home is run by Home Assistant. Therefore when looking at setting up a Cloudflare Tunnel and Caddy, I turned to the Home Assistant add-ons rather than manually running them in Docker. The only slight complexity was having to build my own Caddy version to have the Cloudflare plugin.
Here's my Caddyfile:
{
email <email-address>
acme_ca https://acme-v02.api.letsencrypt.org/directory
log {
format json {
time_key time
time_format rfc3339
}
}
}
# Redirect all HTTP requests to HTTPS
http://* {
redir https://{host}{uri} permanent
}
# Wildcard certificate for all subdomains
*.millwoodonline.co.uk {
tls <email-address> {
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
log
header {
Strict-Transport-Security "max-age=31536000;"
X-XSS-Protection "1; mode=block"
X-Frame-Options "DENY"
X-Robots-Tag "none"
-Server
}
# Pi-hole
@pihole {
host pihole.millwoodonline.co.uk
}
reverse_proxy @pihole 192.168.10.12:8053
}
This forces Caddy to validate the ownership of the domain via Cloudflare, and generate a wildcard cert for *.millwoodonline.co.uk, I removed many of the hostnames, but left pihole in as an example.
I could then setup each of these domains in Unfi as custom A records pointing at the Caddy instance.
As for the Cloudflared Home Assistant Add-on, I could define any public domains, and which internal IPs I want those pointing to, then Cloudflare would generate publicly facing records.