---
date: 2025-01-07
title: Cloudflare DNS
tags: 
  - homelab
  - opnsense
  - hosting
---

Since I registered this domain, I have been using Namecheap for DNS mostly out of convenience. Most of the domains I manage for work use
DigitalOcean which is a little different, but not necessarily better in my opinion. I went into this project with fairly minimal knowledge about different DNS providers and I did not do a thorough comparison of the various providers out there. I settled on Cloudflare as a service
that I trust (I use their 1.1.1.1 DNS) and that is free; I skipped DigitalOcean because the OPNSense integration does not show updates in
DDNS and I recall it being a bit of a pain getting resource IDs that are used as usernames for authentication.


## Motivation
I was configuring a new domain at work and it reminded me how inconvenient it is to use HTTP challenges for my personal domain because 
Namecheap [requires a static IP for DNS challenges](https://www.namecheap.com/support/api/intro/). Some brief searching indicated other
users have had success using Cloudflare; 
[this Reddit post](https://www.reddit.com/r/selfhosted/comments/184fhrv/a_warning_about_namecheap_when_using_dynamic_dns/) in particular
described my exact situation with Cloudflare DNS as a suggested solution.

## Cloudflare Configuration
Creating a free account with Cloudflare is easy. After account creation, I waited to change my domain DNS settings until after I created
the necessary records on Cloudflare to avoid any downtime. I have a `CNAME` record to point `mcknight.tech` to `www.mcknight.tech` and 
then a single wildcard `A` record that DDNS updates to point at my home network.

I also have email through Namecheap; I followed their 
[configuration guide](https://www.namecheap.com/support/knowledgebase/article.aspx/9967/31/how-to-set-up-dns-records-for-namecheap-email-service-with-Cloudflare-cpanel-and-private-email/#pe)
to get those records in place.

## OPNSense Updates
I have an OPNSense router handling DDNS updates and LetsEncrypt certificate renewal. It isn't possible to start issuing certificates
until the DNS servers are updated (and the update propagates), but this can be configured in OPNSense so everything is ready to go.

### Dynamic DNS
Under `Services` -> `Dynamic DNS` -> `Settings`, I created a new entry; Cloudflare uses the username `token` and an API key for the
password. I set `zone` to `mcknight.tech` and `Hostname(s)` to `*.mcknight.tech` (the one `A` record configured earlier). I use
`Interface` for the Check IP Method since it is the most straight-forward method for getting my public IP address. After applying the
changes and waiting a few minutes, the `Current IP` and `Updated` fields should show something after refreshing the page; the `Log File`
menu option can be used to check for any errors.

### ACME Client
I already have HTTP-based certificates configured, so I am re-using an existing Account. 
Under `Services` -> `ACME Client` -> `Challenge Types`, I created a new DNS-01 challenge; the `Global API Key` section may be left empty,
`CF Account ID` is most easily found as the first part of the URL slug when logged in at dash.Cloudflare.com. The API key could use the
same key as Dynamic DNS, though I prefer to generate separate ones in case I have to re-issue a key to change some service configuration
in the future. I left `CF Zone ID` empty.

Next under the `Certificates` menu, I created a new certificate with Common Name `*.mcknight.tech`, using my existing Account and newly-
defined Challenge. At this point, the OPNSense configuration is complete but a certificate cannot be issued until DNS records are updated
with Namecheap.

## Update Namecheap DNS
With all of the above configuration done, updating Namecheap DNS shouldn't cause any service interruption; when the name servers update,
Cloudflare should keep all of the routing working. In the Namecheap `Domain` menu, I changed `Nameservers` to `Custom DNS` and entered the 
nameservers listed in Cloudflare. 

At this point, it will take some time for DNS changes to propagate (this time it took less than an hour, but I've waited up to 12 in the past).
Cloudflare shows a warning when it is not managing DNS, so I waited for this warning to go away as an indication that routing moved over.

## Test Changes
I have TrueNAS (among other things) set up to send email alerts, so I sent a test email there to check that my DNS records for emails are all
valid. I suppose it would have been just as easy to send an email to myself, but I had the TrueNAS dashboard open already.

I also did some quick checks for external access to my domain from my phone since my 
[Uptime Kuma monitoring](https://github.com/louislam/uptime-kuma) runs on the same subnet as everything else on my domain. In the future, I
might get that running remotely for a more complete test.

## Issue DNS Certificate
With routing all updated, that [configured certificate](#acme-client) can now be issued. After watching LetsEncrypt issue the certificate,
I am confident that all of my changes were successful.

With the DNS Certificate issued, I updated nginx to use the new certificate and then restarted that service in OPNSense. I usually wait
a few minutes and then open a page in a private browser to check for the new certificate without worrying about the old one being cached.

## Conclusion
This was a quick change that I am very glad to have made. Now, I can add services/subdomains simply by updating Nginx and they will
automatically have working SSL with a valid certificate. I am also interested in checking out all the analytics Cloudflare exposes;
I see there is more web scraping traffic than I expected, that or there are a lot more people reading this than I thought.
