Small crontab friendly bash script collection to update the DDNS registry in different vendors
  • Shell 94.9%
  • Just 5.1%
Find a file
2026-03-16 19:28:05 +01:00
cdmon Consolidate to single root .env; implement Cloudflare and DuckDNS updaters 2026-03-16 19:26:45 +01:00
cloudflare Consolidate to single root .env; implement Cloudflare and DuckDNS updaters 2026-03-16 19:26:45 +01:00
duckdns Consolidate to single root .env; implement Cloudflare and DuckDNS updaters 2026-03-16 19:26:45 +01:00
.env.example Consolidate to single root .env; implement Cloudflare and DuckDNS updaters 2026-03-16 19:26:45 +01:00
.gitignore Initial ddns-updater project 2026-03-16 17:55:33 +01:00
justfile Initial ddns-updater project 2026-03-16 17:55:33 +01:00
README.md Update README: single root .env, all providers implemented, logging 2026-03-16 19:28:05 +01:00

ddns-updater

Multi-provider Dynamic DNS updater. One folder per DNS provider, each with a self-contained update.sh. All configuration lives in a single root .env.

Providers

Provider Status
cdmon Implemented
cloudflare Implemented
duckdns Implemented

Setup

  1. Copy .env.example to .env and fill in the relevant sections:

    cp .env.example .env
    $EDITOR .env
    
  2. Test manually:

    bash cdmon/update.sh
    bash cloudflare/update.sh
    bash duckdns/update.sh
    # or via just:
    just run-cdmon
    
  3. Add to crontab (hourly, with logging):

    0 * * * * /home/dvitto/projects/ddns-updater/cdmon/update.sh >> /mnt/services/ddns-updater/logs/cdmon.log 2>&1
    

Configuration

All settings are in the root .env (see .env.example). Notification credentials are shared; provider credentials are in separate sections.

CDMON

CDMON_USER=<cdmon-ddns-user>
CDMON_PASS=<cdmon-ddns-password>
CDMON_DOMAINS=example.com,other.com
CDMON_SLEEP=15   # seconds between requests — CDMON rate-limits at ~10s

Credentials come from the CDMON panel → Dynamic DNS section. The same user/password applies to all listed domains.

API: GET https://dinamico.cdmon.org/onlineService.php?enctype=MD5&n=USER&p=MD5PASS&cip=IP — success response contains customok.

Cloudflare

CF_API_TOKEN=<api-token-with-Zone:DNS:Edit>
CF_ZONE_ID=<zone-id-from-cloudflare-dashboard>
CF_DOMAINS=example.com,sub.example.com

All domains must belong to the same zone. The script skips records already set to the current IP.

DuckDNS

DUCKDNS_TOKEN=<token-from-duckdns.org>
DUCKDNS_DOMAINS=myhost1,myhost2   # subdomain names only, no .duckdns.org

DuckDNS accepts all domains in a single API call.

Notifications

Set TELEGRAM_TOKEN + TELEGRAM_CHAT_ID and/or NTFY_URL + NTFY_TOKEN + NTFY_TOPIC in .env to receive failure alerts. Leave empty to disable.

Logs

Cron output goes to /mnt/services/ddns-updater/logs/cdmon.log, rotated via /etc/logrotate.d/backup-logs.