- Notifications
You must be signed in to change notification settings - Fork199
Container to update DNS records periodically with WebUI for many DNS providers
License
qdm12/ddns-updater
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Program to keep DNS A and/or AAAA records updated for multiple DNS providers
This readme and thedocs/ directory areversioned to match the program version:
Version | Readme link | Docs link |
---|---|---|
Latest | README | docs/ |
v2.8 | README | docs/ |
v2.7 | README | docs/ |
v2.6 | README | docs/ |
v2.5 | README | docs/ |
Available as a Docker image
qmcgaw/ddns-updater
andghcr.io/qdm12/ddns-updater
Available aszero-dependency binaries for Linux, Windows and MacOS
🆕 Available in the AUR as
ddns-updater
- see#808Updates periodically A records for different DNS providers:
- Aliyun
- AllInkl
- Changeip
- Cloudflare
- DD24
- DDNSS.de
- deSEC
- DigitalOcean
- Domeneshop
- DonDominio
- DNSOMatic
- DNSPod
- Dreamhost
- DuckDNS
- DynDNS
- Dynu
- EasyDNS
- FreeDNS
- Gandi
- GCP
- GoDaddy
- GoIP.de
- He.net
- Hetzner
- Infomaniak
- INWX
- Ionos
- Linode
- Loopia
- LuaDNS
- Myaddr
- Name.com
- Namecheap
- NameSilo
- Netcup
- NoIP
- Now-DNS
- Njalla
- OpenDNS
- OVH
- Porkbun
- Route53
- Selfhost.de
- Servercow.de
- Spdyn
- Strato.de
- Variomedia.de
- Vultr
- Zoneedit
- Want more?Create an issue for it!
Web user interface (Desktop)
Web user interface (Mobile)
Send notifications withShoutrrr using
SHOUTRRR_ADDRESSES
Container (Docker/K8s) specific features:
- Lightweight 12MB Docker image based on the Scratch Docker image
- Docker healthcheck verifying the DNS resolution of your domains
- Images compatible with
amd64
,386
,arm64
,armv7
,armv6
,s390x
,ppc64le
,riscv64
CPU architectures
Persistence with a JSON fileupdates.json to store old IP addresses with change times for each record
Download the pre-built program for your platform from the assets of a release in thereleases page. You can alternatively download, build and install the latest version of the program by installingGo and then run
go install github.com/qdm12/ddns-updater/cmd/ddns-updater@latest
.For Linux and MacOS, make the program executable with
chmod +x ddns-updater
.In the directory where the program is saved, create a directory
data
.Write a JSON configuration in
data/config.json
, for example:{"settings": [ {"provider":"namecheap","domain":"sub.example.com","password":"e5322165c1d74692bfa6d807100c0310" } ]}
You can find more information in theconfiguration section to customize it.
Run the program with
./ddns-updater
(./ddns-updater.exe
on Windows) or by double-clicking on it.The following isoptional.
- You can customize the program behavior using eitherenvironment variables or flags. For flags, there is a flag corresponding to each environment variable, where it's all lowercase and underscores are replaced with dashes. For example the environment variable
LOG_LEVEL
translates into--log-level
.
- You can customize the program behavior using eitherenvironment variables or flags. For flags, there is a flag corresponding to each environment variable, where it's all lowercase and underscores are replaced with dashes. For example the environment variable
Create a directory, for example,data which is:
- owned by user id
1000
, which is the built-in user ID of the ddns-updater container - has user read+write+execute permissions
mkdir datachown 1000 datachmod u+r+w+x data
If you want to use another user ID,build the image yourself with
--build-arg UID=<your-uid>
. You could also just run the container as root with--user="0"
but this is not advised security wise.- owned by user id
Similarly, create adata/config.json file which is:
- owned by user id
1000
- has user read permissions
touch data/config.jsonchmod u+r data/config.json
- owned by user id
Editdata/config.json, for example:
{"settings": [ {"provider":"namecheap","domain":"sub.example.com","password":"e5322165c1d74692bfa6d807100c0310" } ]}
You can find more information in theconfiguration section to customize it.
Run the container with
docker run -d -p 8000:8000/tcp -v"$(pwd)"/data:/updater/data qmcgaw/ddns-updater
The following isoptional.
- You can customize the program behavior usingenvironment variables
- You can usedocker-compose.yml with
docker-compose up -d
- Kubernetes: check out thek8s directory for an installation guide and examples.
- OtherDocker image tags are available
- You can update the image with
docker pull qmcgaw/ddns-updater
- You can set your JSON configuration as a single environment variable line (i.e.
{"settings": [{"provider": "namecheap", ...}]}
), which takes precedence over config.json. Note however that if you don't bind mount the/updater/data
directory, there won't be a persistent database file/updater/updates.json
but it will still work.
Start by having the following content inconfig.json, or in yourCONFIG
environment variable:
{"settings": [ {"provider":"", }, {"provider":"", } ]}
For each setting, you need to fill in parameters.Check the documentation for your DNS provider:
- Aliyun
- Allinkl
- ChangeIP
- Cloudflare
- Custom
- DDNSS.de
- deSEC
- DigitalOcean
- DD24
- Domeneshop
- DonDominio
- DNSOMatic
- DNSPod
- Dreamhost
- DuckDNS
- DynDNS
- Dynu
- DynV6
- EasyDNS
- FreeDNS
- Gandi
- GCP
- GoDaddy
- GoIP.de
- He.net
- Infomaniak
- INWX
- Ionos
- Linode
- Loopia
- LuaDNS
- Myaddr
- Name.com
- Namecheap
- NameSilo
- Netcup
- NoIP
- Now-DNS
- Njalla
- OpenDNS
- OVH
- Porkbun
- Selfhost.de
- Servercow.de
- Spdyn
- Strato.de
- Variomedia.de
- Vultr
- Zoneedit
Note that:
- you can specify multiple owners/hosts for the same domain using a comma separated list. For example with
"domain": "example.com,sub.example.com,sub2.example.com",
.⚠️ this is a bit different for DuckDNS and GoIP, see their respective documentation.
🆕 There are now flags equivalent for each variable below, for example--log-level
.
Environment variable | Default | Description |
---|---|---|
CONFIG | One line JSON object containing the entire config (takes precedence over config.json file) if specified | |
PERIOD | 5m | Default period of IP address check, followingthis format |
PUBLICIP_FETCHERS | all | Comma separated fetcher types to obtain the public IP address fromhttp anddns |
PUBLICIP_HTTP_PROVIDERS | all | Comma separated providers to obtain the public IP address (ipv4 or ipv6). See thePublic IP section |
PUBLICIPV4_HTTP_PROVIDERS | all | Comma separated providers to obtain the public IPv4 address only. See thePublic IP section |
PUBLICIPV6_HTTP_PROVIDERS | all | Comma separated providers to obtain the public IPv6 address only. See thePublic IP section |
PUBLICIP_DNS_PROVIDERS | all | Comma separated providers to obtain the public IP address (IPv4 and/or IPv6). See thePublic IP section |
PUBLICIP_DNS_TIMEOUT | 3s | Public IP DNS query timeout |
UPDATE_COOLDOWN_PERIOD | 5m | Duration to cooldown between updates for each record. This is useful to avoid being rate limited or banned. |
HTTP_TIMEOUT | 10s | Timeout for all HTTP requests |
SERVER_ENABLED | yes | Enable the web server and web UI |
LISTENING_ADDRESS | :8000 | Internal TCP listening port for the web UI |
ROOT_URL | / | URL path to append to all paths to the webUI (i.e./ddns for accessinghttps://example.com/ddns through a proxy) |
HEALTH_SERVER_ADDRESS | 127.0.0.1:9999 | Health server listening address |
HEALTH_HEALTHCHECKSIO_BASE_URL | https://hc-ping.com | Base URL for thehealthchecks.io server |
HEALTH_HEALTHCHECKSIO_UUID | UUID to idenfity with thehealthchecks.io server | |
DATADIR | /updater/data | Directory to read and write data files from internally |
CONFIG_FILEPATH | /updater/data/config.json | Path to the JSON configuration file |
BACKUP_PERIOD | 0 | Set to a period (i.e.72h15m ) to enable zip backups of data/config.json and data/updates.json in a zip file |
BACKUP_DIRECTORY | /updater/data | Directory to write backup zip files to ifBACKUP_PERIOD is not0 . |
RESOLVER_ADDRESS | Your network DNS | A plaintext DNS address to use to resolve your domain names defined in your settings only. For example it can be1.1.1.1:53 . This is useful for split dns, see#389 |
LOG_LEVEL | info | Level of logging,debug ,info ,warning orerror |
LOG_CALLER | hidden | Show caller per log line,hidden orshort |
SHOUTRRR_ADDRESSES | (optional) Comma separated list ofShoutrrr addresses (notification services) | |
SHOUTRRR_DEFAULT_TITLE | DDNS Updater | Default title for Shoutrrr notifications |
TZ | Timezone to have accurate times, i.e.America/Montreal | |
UMASK | System current umask | Umask to set for the program in octal, i.e.0022 |
By default, all public IP fetching types are used and cycled (over DNS and over HTTPs).
On top of that, for each fetching method, all echo services available are cycled on each request.
This allows you not to be blocked for making too many requests.
You can otherwise customize it with the following:
PUBLICIP_HTTP_PROVIDERS
gets your public IPv4 or IPv6 address. It can be one or more of the following:ipify
usinghttps://api64.ipify.orgifconfig
usinghttps://ifconfig.io/ipipinfo
usinghttps://ipinfo.io/ipspdyn
usinghttps://checkip.spdyn.deipleak
usinghttps://ipleak.net/jsonicanhazip
usinghttps://icanhazip.comident
usinghttps://ident.mennev
usinghttps://ip.nnev.dewtfismyip
usinghttps://wtfismyip.com/textseeip
usinghttps://api.seeip.orgchangeip
usinghttps://ip.changeip.com- You can also specify an HTTPS URL with prefix
url:
for exampleurl:https://ipinfo.io/ip
PUBLICIPV4_HTTP_PROVIDERS
gets your public IPv4 address only. It can be one or more of the following:ipleak
usinghttps://ipv4.ipleak.net/jsonipify
usinghttps://api.ipify.orgicanhazip
usinghttps://ipv4.icanhazip.comident
usinghttps://v4.ident.mennev
usinghttps://ip4.nnev.dewtfismyip
usinghttps://ipv4.wtfismyip.com/textseeip
usinghttps://ipv4.seeip.org- You can also specify an HTTPS URL with prefix
url:
for exampleurl:https://ipinfo.io/ip
PUBLICIPV6_HTTP_PROVIDERS
gets your public IPv6 address only. It can be one or more of the following:ipleak
usinghttps://ipv6.ipleak.net/jsonipify
usinghttps://api6.ipify.orgicanhazip
usinghttps://ipv6.icanhazip.comident
usinghttps://v6.ident.mennev
usinghttps://ip6.nnev.dewtfismyip
usinghttps://ipv6.wtfismyip.com/textseeip
usinghttps://ipv6.seeip.org- You can also specify an HTTPS URL with prefix
url:
for exampleurl:https://ipinfo.io/ip
PUBLICIP_DNS_PROVIDERS
gets your public IPv4 address only or IPv6 address only or one of them (see #136). It can be one or more of the following:cloudflare
opendns
If you have a host firewall in place, this container needs the following ports:
- TCP 443 outbound for outbound HTTPS
- UDP 53 outbound for outbound DNS resolution
- TCP 8000 inbound (or other) for the WebUI
At program start and every period (5 minutes by default):
- Fetch your public IP address
- For each record:
- DNS resolve it to obtain its current IP address(es)
- If the resolution fails, update the record with your public IP address by calling the DNS provider API and finish
- Check if your public IP address is within the resolved IP addresses
- Yes: skip the update
- No: update the record with your public IP address by calling the DNS provider API
- DNS resolve it to obtain its current IP address(es)
💡 We do DNS resolution every period so it detects a change made to the record manually, for example on the DNS provider web UI💡 As DNS resolutions are essentially free and without rate limiting, these are great to avoid getting banned for too many requests.
For Cloudflare records with theproxied
option, the following is done.
At program start and every period (5 minutes by default), for each record:
- Fetch your public IP address
- For each record:
- Check the last IP address (persisted in
updates.json
) for that record- If it doesn't exist, update the record with your public IP address by calling the DNS provider API and finish
- Check if your public IP address matches the last IP address you updated the record with
- Yes: skip the update
- No: update the record with your public IP address by calling the DNS provider API
- Check the last IP address (persisted in
This is the only way as doing a DNS resolution on the record will give the IP address of a Cloudflare server instead of your server.
- The automated healthcheck verifies all your records are up to dateusing DNS lookups
- You can also manually check, by:
- Going to your DNS management webpage
- Setting your record to
127.0.0.1
- Run the container
- Refresh the DNS management webpage and verify the update happened
You can build the image yourself with:
docker build -t qmcgaw/ddns-updater https://github.com/qdm12/ddns-updater.git
You can use optional build arguments with--build-arg KEY=VALUE
from the table below:
Build argument | Default | Description |
---|---|---|
UID | 1000 | User ID running the container |
GID | 1000 | User group ID running the container |
VERSION | unknown | Version of the program and Docker image |
CREATED | an unknown date | Build date of the program and Docker image |
COMMIT | unknown | Commit hash of the program and Docker image |
This repository is under anMIT license
Sponsor me onGithub or donate topaypal.me/qmcgaw
Many thanks to J. Famiglietti for supporting me financially 🥇👍
About
Container to update DNS records periodically with WebUI for many DNS providers