This is a self-hosted DDNS service for receiving public IP updates from a router or other local source and updating a DNS record in Cloudflare.
Container images are based on Alpine Linux and are available for these platforms:
- linux/amd64
- linux/arm64
- linux/arm/v6
- linux/arm/v7
The primary purposes for building yet another DDNS tool for updating Cloudflare records:
- Many other solutions depend upon using a Global API token which is unacceptable for this singular purpose. This solution allows the use of a API token scoped with privileges to edit a single DNS zone.
- Unfortunately Cloudflare does not allow limiting the edit privileges to a single DNS record in a zone at this point.
- Self-hosted option for receiving DDNS updates from a router or other local source rather than depending on an external service for detecting public IP address changes
Valid response codes were gathered from here:
https://help.dyn.com/remote-access-api
https://github.com/troglobit/inadyn/blob/master/plugins/common.c
Example information that will be used below:
- Cloudflare Record to Update:
home.example.com
- Cloudflare API token (scoped to a single DNS Zone!):
supersecretapitoken
- Username for the ddns-cloudflare service:
ddns-user
- Password for the ddns-cloudflare service:
ddns-password
- Server running the ddns-cloudflare service:
ddns.example.com:8080
- Port 8080 can be dropped by running the application behind a reverse proxy
- Service:
dyndns
- Hostname:
home.example.com
- Username:
ddns-user
- Password:
ddns-password
- Server:
ddns.example.com:8080/nic/update?hostname=%h&myip=%i
curl "http://ddns-user:ddns-password@ddns.example.com:8080/nic/update?hostname=home.example.com&myip=0.0.0.0"
Note: The application requires authentication to be configure via the AUTH_USER and AUTH_PASS environment variables. Without those set, the app will fail to start successfully which is intentional.
services:
ddns-cloudflare:
container_name: ddns-cloudflare
# Using 'latest' as an example. specifying a specific version is preferred
image: ghcr.io/clayoster/ddns-cloudflare:latest
restart: always
environment:
# Username for authenticating to the ddns service
- AUTH_USER=ddns-user
# Password for authenticating to the ddns service
- AUTH_PASS=ddns-password
# Your CloudFlare API token with access to the necessary DNS Zone
- API_TOKEN=supersecretapitoken
ports:
- "8080:8080"
Additional recommendations:
- Only run this container on an internal network and not exposed to the internet
- Run this behind a reverse proxy with HTTPS configured to keep requests encrypted
- Make "hostname" compatible with accepting up to 20 comma-delimited domain names
- Upgrade python-cloudflare dependency to version 3 and complete corresponding rewrite