ddns-a
A lightweight Dynamic DNS client for Windows that monitors IP address changes and notifies external services via webhooks.
Features
- Real-time monitoring – Uses Windows API events with polling fallback
- State persistence – Detects IP changes that occurred during program downtime
- Flexible filtering – Include/exclude adapters by regex, skip virtual adapters
- Customizable webhooks – Any HTTP method, headers, bearer auth, Handlebars templates
- Robust retry – Exponential backoff with configurable limits
- Graceful shutdown – Handles Ctrl+C cleanly
Installation
Quick Start
# Monitor IPv6 changes and send to webhook
# Monitor both IPv4 and IPv6
# With bearer token and custom template
# Test mode - log changes without sending webhooks
# With state persistence (detect changes across restarts)
# Generate config file
CLI Options
ddns-a [OPTIONS] --url <URL> --ip-version <VERSION>
ddns-a init [--output <FILE>]
Required:
--url <URL> Webhook URL
--ip-version <VERSION> ipv4 | ipv6 | both
Request:
--method <METHOD> HTTP method (default: POST)
--header <K=V> HTTP header (repeatable)
--bearer <TOKEN> Bearer token
--body-template <TEMPLATE> Handlebars template
Filter:
--include-adapter <PATTERN> Include adapters matching regex
--exclude-adapter <PATTERN> Exclude adapters matching regex
--exclude-virtual Exclude virtual adapters
Monitor:
--poll-interval <SEC> Polling interval (default: 60)
--poll-only Disable API events, polling only
--state-file <PATH> State file for detecting changes across restarts
Retry:
--retry-max <N> Max attempts (default: 3)
--retry-delay <SEC> Initial delay (default: 5)
Other:
--config <FILE> Config file path
--dry-run Log changes without sending webhooks
--verbose Enable debug logging
Default Filtering Behavior
By default (without any filter options):
| Adapter Type | Monitored |
|---|---|
| Ethernet | ✅ Yes |
| Wi-Fi | ✅ Yes |
| VMware / VirtualBox / Hyper-V | ✅ Yes |
| Loopback (127.0.0.1 / ::1) | ❌ No (always excluded) |
Recommendation: Use --exclude-virtual to skip virtual adapters in most cases.
Filter Examples
# Exclude virtual adapters (recommended)
# Monitor only Ethernet adapter
# Monitor Ethernet and Wi-Fi, exclude Docker
Configuration File
Generate a template:
Example ddns-a.toml:
[]
= "https://api.example.com/ddns"
= "ipv6"
= "POST"
= '{"ip": "{{address}}", "adapter": "{{adapter}}", "event": "{{kind}}"}'
# Optional: bearer token or custom headers
# bearer = "your-token"
# [webhook.headers]
# X-Custom-Header = "value"
[]
# include = ["^Ethernet", "^Wi-Fi"]
# exclude = ["^Docker"]
= true
[]
= 60
= false
# state_file = "ddns-a-state.json"
[]
= 3
= 5
= 60
= 2.0
Priority: CLI arguments > Config file > Built-in defaults
Body Template Variables
Use Handlebars syntax:
| Variable | Description |
|---|---|
{{adapter}} |
Adapter name |
{{address}} |
IP address |
{{kind}} |
added or removed |
{{timestamp}} |
Unix timestamp |
Example:
How It Works
- On startup, fetches current IP addresses from all (filtered) adapters
- If
--state-fileis set, compares with saved state and triggers webhooks for changes during downtime - Listens for Windows network change events via
NotifyIpInterfaceChangeAPI - Falls back to pure polling if API events fail
- On IP change, sends webhook with retry on failure
- Uses debouncing to merge rapid changes (2s window)
Platform Support
Currently Windows-only. The architecture supports adding Linux/macOS via platform-specific AddressFetcher and ApiListener implementations.
License
Apache License 2.0