From ae79cd131e6dfe6866c744777837e1a5763e9276 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Thu, 19 Feb 2026 10:18:25 +0100 Subject: [PATCH] add README --- README.md | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..cf23e27 --- /dev/null +++ b/README.md @@ -0,0 +1,103 @@ +# 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`. +