ddns + curl + launchd = ❤️

as someone who opts for home hosting services and websites, having a dynamic ip assigned from my isp is quite troublesome. dynamic dns helps solve the headache of a non-static (frequently changing) ip address by allowing immediate updating of dns records. fortunately, many services like dyndns and no-ip have software integrated into routers to perform these updates as the ip address changes. unfortunately, i use google domains as my registrar, and their dynamic dns service is not available as an endpoint for my router. however, dynamic dns is super simple, and we don't need any specialized software to perform these updates.

google domains has a simple http api that lets you update the ip address for dns records. the format is as follows: https://username:password@domains.google.com/nic/update?hostname=subdomain.yourdomain.com&myip=1.2.3.4

this is where launchd comes in. if i can easily update my dns records with a simple curl, i can replace the recommended programs (ddclient and inadyn) with building blocks my operating system comes with.

launchd manifest
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
        <key>Label</key>
        <string>update-dyndns</string>
        <key>ProgramArguments</key>
        <array>
          <string>/usr/bin/env</string>
          <string>/Users/haze/dyndns/update.sh</string>
        </array>
        <key>StartInterval</key>
        <integer>600</integer>
  </dict>
</plist>
dynamic dns update script
#!/bin/sh
IP=`curl -s ifconfig.me`
curl -v "https://username:password@domains.google.com/nic/update?hostname=@.worldpeace.social&myip=$IP"
curl -v "https://username:password@domains.google.com/nic/update?hostname=dynamic.haze.cool&myip=$IP"
curl -v "https://username:password@domains.google.com/nic/update?hostname=server.haze.cool&myip=$IP"
curl -v "https://username:password@domains.google.com/nic/update?hostname=music.haze.cool&myip=$IP"

Emacs 31.0.50 (Org mode 9.7.9)