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 name regex or kind (ethernet, wireless, virtual, loopback)
- 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, exclude virtual adapters
# 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
--include-kind <KIND> Include adapters by kind (ethernet, wireless, virtual, loopback)
--exclude-kind <KIND> Exclude adapters by kind
--change-kind <KIND> Filter by change type: added | removed | both (default: both)
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 |
| Virtual (VMware, VirtualBox, Hyper-V, etc.) | ✅ Yes |
| Loopback (127.0.0.1 / ::1) | ❌ No (excluded by default) |
Note: Loopback is excluded by default. Use --include-kind loopback to monitor it.
Recommendation: Use --include-kind ethernet,wireless to monitor only physical adapters. Virtual adapters (Hyper-V, VMware, Mobile Hotspot) are automatically detected via Windows HardwareInterface flag.
Filter Examples
# Exclude virtual adapters
# Monitor only physical Ethernet and Wireless adapters (auto-excludes Hyper-V, VMware, etc.)
# Monitor only adapters matching regex
# Combine kind and name filters
# Only report newly added IPs (ignore removals)
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_kinds = ["ethernet", "wireless"]
= ["virtual"]
# include = ["^Ethernet", "^Wi-Fi"]
# exclude = ["^Docker"]
[]
= 60
= false
# state_file = "ddns-a-state.json"
# change_kind = "both" # added | removed | both
[]
= 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