I’ve been in the process of setting up Home Labs for both myself and my parents. One surprisingly annoying issue has been accessing these servers externally (for VPN access and enabling webhooks for things like Home Assistant). I am documenting the steps I took mostly for myself, but hopefully it helps a few folks as well.
Note: for folks using just Home Assistant standalone, I would use the DuckDNS integration. I am doing this because I have multiple containers that need reverse proxy access.
Why?
When you have a Home Lab behind a consumer internet connection, your public IP changes, which makes it hard for other services like a VPN client or 3rd party webhook to ping your server.
What?
We’re going to dynamically update DNS entries on Cloudflare so sub.yourdomain.com
will always point to your public IP address.
How?
Domain on Cloudfront
You will need to have a domain on Cloudfront (or any other service that ddclient
can update). I’m assuming you have one already.
Then you need to get an API Token before you set up ddclient
. You can do that on Cloudflare by:
- In the top right, click on My Profile
- On the side navigation, click on API Tokens
- Click on Create Token and use the Edit Zone Template
- Under Zone Resources make sure you update it to the domain you purchased.
You then need to create the subdomain that will point to your homelab. You can do that by going to your domain and clicking on DNS on the side navigation and clicking on Add Record. You can set the IPv4 address to whatever, since it’ll be updated later.
⚠MAKE SURE YOU UNCHECK PROXY STATUS otherwise you will have issues with configuring things like VPNs later.
Setting up ddclient
I have an existing debian instance running a few cron jobs already, so I’m re-using that.
I highly suggest using the latest version of Debian (I’m using 12.2). I’ve run into issues with Debian 10 and Ubuntu 22 installing old versions of ddclient
that end up not working.
You can start by install ddclient
by running the following command:
apt-get install ddclient
This will start the setup process:
- For Dynamic DNS Provider, select Cloudflare
- For username enter in the word
token
- For password enter the token you created above
- For the comma-separated FQDN enter the full domain (including subdomain) you created
- For method select Web-based IP discovery service
Now we need to edit /etc/ddclient.conf
and add zone=
. The file should look something like this:
# Configuration file for ddclient generated by debconf
#
# /etc/ddclient.conf
protocol=cloudflare \
use=web, web=https://api.ipify.org/ \
login=token \
password='xxxxxxxxxxxxxxxxxxxxxxx' \
zone=yourdomain.com
sub.yourdomain.com
You can now test with:
ddclient -query
And then see if it worked:
ddclient status
Which should say something like:
SUCCESS: updating sub.domain.com: IPv4 address set to xx.xxx.xx.xxx
Great success!
Make it a service
Update /etc/default/ddclient
so the file looks like this:
# generated from debconf on Mon Jan 15 05:32:36 UTC 2024
#
# /etc/default/ddclient
# Set to "true" if ddclient should be run every time DHCP client ('dhclient'
# from package isc-dhcp-client) updates the systems IP address.
run_dhclient="false"
# Set to "true" if ddclient should be run every time a new ppp connection is
# established. This might be useful, if you are using dial-on-demand.
run_ipup="false"
# Set the time interval between the updates of the dynamic DNS name in seconds.
# This option only takes effect if the ddclient runs in daemon mode.
daemon_interval="5m"
run_daemon="true"
And then you need to run the following commands:
systemctl start ddclient.service
update-rc.d ddclient enable
And now this should run every 5 minutes to update your domain to point to your public IP address. You can now set up port forwarding on your router, and have this sort of mapping:
http://subdomain.domain.com:<external-port> -> 192.168.xxx.xxx:<internal-port>