A simple DynDNS client for deSEC.io
Project description
deSEC DNS Updater
A dynamic DNS client for deSEC.io domains that updates A and AAAA records based on your current public IP addresses.
Features
- Updates both A (IPv4) and AAAA (IPv6) records
- Supports multiple subdomains in a single run
- Dry run mode to preview changes without modifying DNS
- Customizable verbosity levels
- Can run as a one-time update (e.g. via cron) or in continuous mode (e.g. via a systemd unit)
- Respects API rate limits
- Configurable via command line or environment variables
- IPv6 detection from specific network interfaces
- Robust error handling and logging
Installation
Using pip
pip install desec-dnsupdater
From source
git clone https://github.com/yourusername/desec-dnsupdater.git
cd desec-dnsupdater
pip install .
# OR using Poetry
poetry install
Usage
Basic usage
desec-dyndns --domain example.com --subdomain www --token YOUR_DESEC_TOKEN
Updating multiple subdomains
desec-dyndns --domain example.com --subdomain www --subdomain api --token YOUR_DESEC_TOKEN
Specifying a network interface for IPv6 detection
desec-dyndns --domain example.com --subdomain www --token YOUR_DESEC_TOKEN --interface eth0
Dry run (preview changes without applying)
desec-dyndns --domain example.com --subdomain www --token YOUR_DESEC_TOKEN --dry-run
Continuous mode (run as a daemon)
desec-dyndns --domain example.com --subdomain www --token YOUR_DESEC_TOKEN --continuous
Increase verbosity
# Show only errors
desec-dyndns --domain example.com --subdomain www --token YOUR_DESEC_TOKEN
# Show warnings and errors
desec-dyndns --domain example.com --subdomain www --token YOUR_DESEC_TOKEN -v
# Show info, warnings, and errors
desec-dyndns --domain example.com --subdomain www --token YOUR_DESEC_TOKEN -vv
# Show debug messages, info, warnings, and errors
desec-dyndns --domain example.com --subdomain www --token YOUR_DESEC_TOKEN -vvv
Command Reference
Usage: desec-dyndns [OPTIONS]
Update DNS settings for a deSEC domain.
Options:
-d, --domain TEXT The domain to update in. [required]
-s, --subdomain TEXT The subdomain(s) to update. [required]
-t, --token TEXT The token to use for authentication.
[required]
-i, --interface TEXT The network interface to use for determining
the IPv6 address. If not set, IPv6 is not
updated.
-l, --log-file FILENAME The file to write logs to. Defaults to
stdout. [default: -]
-v, --verbose Increase verbosity of output (can be used
multiple times for more verbosity, e.g.
`-vvv`). Default is errors only. Once for
warnings, twice for info, three times for
debug.
--dry-run Don't actually update the DNS records, just
print what would be done. [default: False]
-c, --continuous Run the update in a loop, waiting for the
specified wait time between updates.
[default: False]
--wait-time-between-checks INTEGER
The wait time between checks for updates in
seconds (for continuous updates, see
--continuous/-c). [default: 60]
--wait-time-between-api-calls INTEGER
The wait time between domain update API calls
in seconds (for respecting rate limits).
[default: 5]
-h, --help Show this message and exit.
Environment Variables
All command-line options can also be specified via environment variables with the prefix DESEC_DYNDNS_:
DESEC_DYNDNS_DOMAIN- The domain to updateDESEC_DYNDNS_SUBDOMAIN- The subdomain(s) to updateDESEC_DYNDNS_TOKEN- Your deSEC API tokenDESEC_DYNDNS_INTERFACE- Network interface for IPv6DESEC_DYNDNS_LOG_FILE- Log file pathDESEC_DYNDNS_VERBOSE- Verbosity level (set to number 1-3)DESEC_DYNDNS_DRY_RUN- Set to any value to enableDESEC_DYNDNS_CONTINUOUS- Set to any value to enableDESEC_DYNDNS_WAIT_TIME_BETWEEN_CHECKS- Time between checks in continuous modeDESEC_DYNDNS_WAIT_TIME_BETWEEN_API_CALLS- Time between API calls
Example:
export DESEC_DYNDNS_DOMAIN=example.com
export DESEC_DYNDNS_SUBDOMAIN=www
export DESEC_DYNDNS_TOKEN=your_token_here
desec-dyndns # Uses values from environment
How It Works
- The tool retrieves your current public IPv4 address from ipify.org
- If specified, it detects your public IPv6 address from the given network interface
- It compares these with the current DNS records for your domain
- If different, it updates the records using the deSEC API via the
desec-dnspython client
Assumptions
- You have created an API token with permission to modify your domain's DNS records
- For IPv6 updates, you need a globally routable IPv6 address on the specified interface which is derived from your MAC address (no privacy extensions)
- You have properly set up your domain with deSEC.io
IPv6 Address Detection Details
The IPv6 address detection in this tool specifically relies on EUI-64 formatted IPv6 addresses that are directly derived from the MAC address of the specified network interface. The reason for this is that my AVM FritzBox seems to require it for working IPv6 port forwarding. Here's how it works:
- The tool retrieves the MAC address of the specified interface
- It converts this MAC address to an EUI-64 identifier by:
- Splitting the 48-bit MAC address into two 24-bit halves
- Inserting the fixed value
FF:FEbetween these halves - Inverting the 7th bit of the first byte (the "Universal/Local" bit)
- It then looks for a public IPv6 address on the interface that ends with this EUI-64 identifier
- Only if such an address is found, it will be used for updating AAAA records
Important Notes on IPv6 Address Types
This tool will not work with:
- IPv6 addresses generated with privacy extensions (RFC 4941)
- Randomly generated IPv6 addresses
- Manually configured IPv6 addresses that don't follow the EUI-64 format
It will only work with:
- Stateless Address Autoconfiguration (SLAAC) addresses using the EUI-64 format
- Statically configured addresses that follow the EUI-64 format derived from the MAC address
Setting Up EUI-64 IPv6 Addressing with systemd-networkd
To ensure your system generates the right type of IPv6 address, you can use systemd-networkd with the following configuration:
- Create a network configuration file in
/etc/systemd/network/(e.g.,20-wired.network):
[Match]
Name=eth0 # Replace with your actual interface name
[Network]
DHCP=yes
IPv6AcceptRA=yes
[IPv6AcceptRA]
UseAutonomous=yes
UseDNS=yes
# This is critical - disable privacy extensions
UsePrivacy=no
- Enable and restart systemd-networkd:
sudo systemctl enable systemd-networkd
sudo systemctl restart systemd-networkd
- Verify your IPv6 address is derived from your MAC address:
# Show your MAC address
ip link show eth0 | grep link/ether
# Show your IPv6 addresses
ip -6 addr show dev eth0 | grep 'scope global'
The IPv6 address should have its last 64 bits derived from your MAC address, with the 7th bit inverted and FF:FE inserted in the middle.
Running as a Service
Systemd
Create a file at /etc/systemd/system/desec-dyndns.service:
[Unit]
Description=deSEC Dynamic DNS Updater
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/path/to/desec-dyndns --domain example.com --subdomain www --token YOUR_TOKEN --interface eth0 --continuous
Restart=on-failure
RestartSec=60s
[Install]
WantedBy=multi-user.target
Then enable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable desec-dyndns
sudo systemctl start desec-dyndns
Troubleshooting
- If you get authentication errors, check your token
- For IPv6 issues, make sure your interface has a public IPv6 address
- Increase verbosity up to
-vvvto see detailed debug information - Use
--dry-runto test without making changes
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file desec_dnsupdater-0.1.4.tar.gz.
File metadata
- Download URL: desec_dnsupdater-0.1.4.tar.gz
- Upload date:
- Size: 8.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.3 CPython/3.12.6 Linux/6.12.22+bpo-amd64
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c563b2fe9ec297b565747286223fae2551dcf124e1ecfcb47cb271639326ea07
|
|
| MD5 |
d334db7014fcbc0f106b8155b244a591
|
|
| BLAKE2b-256 |
587aa4d0d64d3935f87d53c5119c02917f8d266981857c5c05ed97cc6dcf4630
|
File details
Details for the file desec_dnsupdater-0.1.4-py3-none-any.whl.
File metadata
- Download URL: desec_dnsupdater-0.1.4-py3-none-any.whl
- Upload date:
- Size: 9.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.3 CPython/3.12.6 Linux/6.12.22+bpo-amd64
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f16a5b5e39401744c49911c829895d1f3cc3df8437b462801e988625861e181
|
|
| MD5 |
cf903e417226934bcc3e45d2680432cf
|
|
| BLAKE2b-256 |
679fb24afaae44762f03d4394379335593eadac9d16d5d5639e59fbd9f9285a3
|