# DNS Updater A small CLI that updates existing A records on supported DNS providers to match the current IP of your machine (either its public “WAN” IP or the IP of a local network interface). Runs once and exits — ideal to schedule with cron or a systemd timer. ## Features - Update existing A records on multiple providers in one run - Providers: DigitalOcean, Vultr - Public IP lookup via pluggable services (ipecho, jsonip, etc.) - Resolve IP from a local interface (e.g., `eth0`) - Skips updates when the record is already up-to-date - Structured, human-readable logging ## How It Works - Loads the YAML config and registers DNS providers. - Selects the configured public IP lookup service. - Iterates `updates` and, for each record: - Resolves the target IP from `wan` (public IP) or a local interface name. - Looks up the existing record by name on the provider. - Updates the record only if the IP changed. Only A records are listed/updated; records must already exist. ## Install - Requirements: Go 1.23+ (module toolchain sets `go1.24.1`). Build with Makefile: ``` make build ``` Or directly with Go: ``` go build -v -o build/dnsupdater cmd/dnsupdater/main.go ``` ## Configuration See `config.example.yml` for a full example. Create your own `config.yml` alongside the binary (or pass `-config`): ```yaml services: IPLookup: ipecho # one of: ipecho, jsonip, ifconfig.me, ip.me, icanhazip providers: digitalocean: token: vultr: token: updates: digitalocean: domain1.com: www: wan # use public IP app: eth0 # use IP from local interface domain2.com: www: wan vultr: example.com: www: wan ``` - `services.IPLookup`: public IP lookup backend. Supported values: `ipecho`, `jsonip`, `ifconfig.me`, `ip.me`, `icanhazip`. - `providers`: map of provider name to credentials. Current providers: `digitalocean`, `vultr`. - `updates`: which domains/records to update per provider. - Value must be either `wan` (public IP) or a local interface name (e.g., `eth0`). Known limitation: literal IPv4 strings in `updates` (e.g., `84.24.254.21`) are not interpreted as IPs and will fail; use `wan` or an interface name instead. ## Usage ``` ./build/dnsupdater -config ./config.yml # run once ./build/dnsupdater -v # print version ``` Logs are written to stderr in a readable format. ### Scheduling - Cron: `*/5 * * * * /path/to/dnsupdater -config /path/to/config.yml >/dev/null 2>&1` - systemd (example): create a service and timer that invoke the binary every few minutes. ## Testing ``` make test ``` ## Provider Notes - DigitalOcean: updates existing A records via the Domains API. - Vultr: updates existing A records via the DNS API. - Records must already exist; creation is not implemented. ## Troubleshooting - “Invalid DNS service”: the name under `updates:` doesn’t match a configured provider. - “Failed to fetch ip”: `wan` lookup failed or the local interface name is wrong. - No change: when the on-file IP matches the resolved IP, the tool logs success without making an API call. ## License AGPL-3.0-only. See `LICENSE`.