Well, that was easy. I’ve been thinking about setting up WireGuard on my firewall. That will give me ad blocking by default as well as a way into my system when I want to do something. But… that means I need a way to know what my external IP is. Dynamic DNS to the rescue!
I looked around at the providers, and DuckDNS appears to be the one whose ideology aligns most closely to mine. I went to their “Install” page and they don’t have OpenBSD. But they have something close — linux bsd cron. So I adapted their script to use OpenBSD’s ftp (which, despite its name, does https as well) instead of curl, which isn’t in the base OpenBSD distribution.
#!/bin/sh -
# Update the DNS at duckdns.org with my IP
DOMAINS="mydnshost" # comma-separated, just the hostnames, not the FQDNs
TOKEN="badcafe-dead-beef-b001-fa11ca2eba3e" # from DuckDNS
tmpfile=`/usr/bin/mktemp /tmp/duckdns.XXXXXXXXXX`
if [ $? -ne 0 ]; then
/usr/bin/logger -i -p daemon.err "duckdns update failed, couldn't create temp file"
exit 1
fi
/usr/bin/ftp -d -o $tmpfile "https://www.duckdns.org/update?domains=${DOMAINS}&token=${TOKEN}"
return_val=$?
url_out=`/bin/cat $tmpfile`
/bin/rm $tmpfile
if [ $return_val -eq 0 ]; then
if [ $url_out == "OK" ]; then
/usr/bin/logger -i -p daemon.info "duckdns update ok"
else
/usr/bin/logger -i -p daemon.info "duckdns update failed: $url_out"
fi
else
/usr/bin/logger -i -p daemon.err "duckdns update failed, returned: $return_val"
fi
Note that this doesn’t account for multiple external WANs, something I want to do in the future. It also requires IPv4. There are ip= and ipv6= parameters if you want IPv6 or a different address for different WANs.
Then all I had to do was chmod 700 and stick it in a cron file:
crontab -e
~/15 * * * * ~/duckdns/duckdns >/dev/null 2>&1
Now I can get my IP anywhere. (I’m using ~/15 instead of */15 so I don’t get 503s when everyone else decides it’s time to update.)