DynDNS Helper
Self-hosted python web application based on FastAPI to update DNS records via API.
Vendor backends are easily extensible and include currently:
Current use-cases for this application:
- Updating DNS records based on data received via DynDNS compatible requests from e.g. routers such as AVM Fritzbox
- Support for IPv4, IPv6 and IPv6 LAN Prefix
- IPv4 will result in updated A record
- IPv6 will result in updated AAAA record
- IPv6 LAN Prefix will update all AAAA records defined in an config mapping of FQDN to IPv6 Interface IDs
Limitations:
- No support for DNS round robin or the like
- No updating a single FQDN across multiple vendors
- No cleanup of DNS records
- No updating data other than values of DNS records
TODO
- docs
- tests
Router DynDNS Examples
AVM Fritzbox
Fritzbox DynDNS Settings:
Update-URL: https://192.168.178.10/fqdns/<domain>/dyndns?ip=<ipaddr>&ip=<ip6addr>&ipv6lanprefix=<ip6lanprefix>&dualstack=<dualstack>
Domainname: test1.domain.tld
Username: testuser
Password: testpassword
App config:
{
"fqdns": {
"test1.domain.tld": {
"vendor": "...",
"dyndns_credentials": {
"testuser": "9f735e0df9a1ddc702bf0a1a7b83033f9f7153a00c29de82cedadc9957289b05"
}
}
}
}
IPv6 LAN Prefix & Interface ID (IID)
Providers will assign an publicly routed IPv6 Prefix for a client. Normally a /48 or /64.
Depending on the clients router configuration, devices behind it will use this prefix to assign themselves a public IPv6.
These devices append an Interface ID (or: host part) to the prefix. How this IID is generated depends on the device configuration.
It may be generated by using its MAC Address, it may be generated randomly for privacy reasons.
This helper supports updating DNS records for IIDs when the IPv6 LAN Prefix changes:
If a DynDNS API call contains an ipv6lanprefix, the FQDN settings of the given fqdn will be used to find other FQDNs to update, e.g.:
{
"fqdns": {
"test1.domain.tld": {
"vendor": "...",
"dyndns_credentials": {
"testuser": "9f735e0df9a1ddc702bf0a1a7b83033f9f7153a00c29de82cedadc9957289b05"
},
"ipv6_lan_prefix_iid_map": {
"test2.domain.tld": "::2a0:00ff:111c:1234"
}
},
"test2.domain.tld": {
"vendor": "..."
}
}
}
If for this configuration a DynDNS API call for test1.domain.tld is received, that contains ipv6lanprefix, an AAAA DNS record for test2.domain.tld is ensured.
For the above example: An ipv6lanprefix of 2001:db8:85a3::/48 will result in:
test2.domaintld AAAA 2001:db8:85a3::2a0:00ff:111c:1234
Caveats
- Larger IIDs than a prefix allows will be shortened
- e.g.: An
ipv6lanprefixof2001:db8:85a3:1234::/64with an IID::9876:2a0:00ff:111c:1234will result in an IPv6 address2001:db8:85a3:1234:2a0:00ff:111c:1234
- e.g.: An
Vendors
All vendor config is defined under a key vendors and the lowercase name of the vendor, e.g.:
{
"vendors": {
"hetzner": {
"enabled": true,
...
}
}
}
The following common options are available for every vendor:
| Option | Default | Required | Description | Example |
|---|---|---|---|---|
| enabled | false | false | if this vendor is enabled | true |
| create_zone_if_missing | false | false | if a zone is created for a FQDN if its missing - otherwise raises an error | true |
| default_zone_ttl | 86400 | false | default TTL to set for created zones | 7200 |
| default_record_ttl | 600 | false | default TTL to set for created records - if not defined in individual FQDN settings | 300 |
Hetzner
Additional options:
| Option | Default | Required | Description | Example |
|---|---|---|---|---|
| api_url | 'https://dns.hetzner.com/api/v1' | false | Hetzner DNS API URL | |
| api_token | true | default TTL to set for created records - if not defined in individual FQDN settings | 'secretapitoken' |