dyndnshelper/README.md
2023-07-09 18:52:12 +02:00

121 lines
4.0 KiB
Markdown

DynDNS Helper
=============
Self-hosted python web application based on [FastAPI](https://github.com/tiangolo/fastapi) to update DNS records via API.
Vendor backends are easily extensible and include currently:
- [Hetzner DNS API](https://dns.hetzner.com/api-docs/)
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:
```json
{
"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.:
```json
{
"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 `ipv6lanprefix` of `2001:db8:85a3:1234::/64` with an IID `::9876:2a0:00ff:111c:1234` will result in an IPv6 address `2001:db8:85a3:1234:2a0:00ff:111c:1234`
# Vendors
All vendor config is defined under a key `vendors` and the lowercase name of the vendor, e.g.:
```json
{
"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' |