6.3 KiB
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>
Domainname: test1.domain.tld
Username: testuser
Password: testpassword
App config:
{
"fqdns": {
"test1.domain.tld": {
"vendor": "hetzner",
"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": "hetzner",
"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
Configuration
All configuration options should be supplied as JSON files in /etc/dyndnshelper/.
Files are merged by their top level key. With multiple files with the same top level key (e.g. server) only the last read will be used.
Example structure:
/etc/dyndnshelper/
fqdns.json
server.json
vendors.json
Server
All server config is defined under a key server, e.g.:
{
"server": {
"host": "0.0.0.0"
}
}
The following options are available:
| Option | Default | Required | Description | Example |
|---|---|---|---|---|
| host | '127.0.0.1' | false | host to listen on | '0.0.0.0' |
| port | 8000 | false | port to listen on | 8080 |
| app_log_level | 'INFO' | false | log level for the application | 'DEBUG' |
| root_log_level | 'WARNING' | false | log level for all other applications | 'INFO' |
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 for Hetzner:
| 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' |
FQDNs
All FQDN config is defined under a key fqdns and the FQDN as a key, e.g.:
{
"fqdns": {
"test1.domain.tld": {
"vendor": "hetzner",
...
}
}
}
The following options are available for each FQDN:
| Option | Default | Required | Description | Example |
|---|---|---|---|---|
| vendor | true | vendor to use for the FQDN | 'hetzner' | |
| zone | the root zone of the FQDN | false | DNS zone to handle DNS records in | 'myservers.domain.tld' |
| record_ttl | false | DNS record TTL to use, when creating records. Overrides vendor default_record_ttl |
600 | |
| dyndns_credentials | false | Users and their SHA256 hashed passwords that are allowed to send DynDNS updates for this FQDN | {"testuser": "9f735e0df9a1ddc702bf0a1a7b83033f9f7153a00c29de82cedadc9957289b05"} | |
| ipv6_lan_prefix_iid_map | false | FQDNs and their IIDs to be updates if a DynDNS update for this FQDN contains an IPv6 LAN Prefix | {"test2.domain.tld": "::2a0:00ff:111c:1234"} |