4.8 KiB
4.8 KiB
DDNS Updater
A lightweight dynamic DNS updater for Cloudflare written in Go. Automatically detects your public IP changes and updates specified DNS A records.
Features
- Automatic public IP detection with fallback services
- Multiple subdomain support
- Cloudflare API v4 integration
- Configurable check intervals
- Retry logic with exponential backoff
- Structured JSON logging
- Graceful shutdown handling
- Cross-platform (Linux, macOS)
Quick Start
1. Generate configuration template
make init-config
This creates config.yaml with default settings.
2. Get Cloudflare credentials
Generate API Token
- Log in to Cloudflare Dashboard
- Go to Profile → API Tokens
- Click Create Token
- Use the Edit zone DNS template or create a custom token with:
- Permissions: Zone → DNS → Edit, Zone → Zone → Read
- Zone Resources: Include → Specific zone → (select your domain)
- Copy the token (you'll only see it once)
Find Zone ID
- In Cloudflare Dashboard, select your domain
- Scroll down on the Overview page
- Find Zone ID in the right sidebar under API section
- Copy the Zone ID
3. Configure
Edit config.yaml:
cloudflare:
api_token: "your-token-here" # From step 2
zone_id: "your-zone-id-here" # From step 2
zone_name: "example.com" # Your domain
subdomains:
- name: "home" # Updates home.example.com
proxied: false
- name: "vpn"
proxied: true # Route through Cloudflare proxy
4. Run locally (test)
make run
Logs will show IP detection and DNS updates in real-time.
Production Deployment
Linux (systemd)
Install and set up service
# Build and install binary
make install-linux
# Edit config with your credentials
sudo nano /etc/ddns-updater/config.yaml
# Create systemd service
make service-linux
# Enable and start
sudo systemctl daemon-reload
sudo systemctl enable ddns-updater
sudo systemctl start ddns-updater
# Check status
sudo systemctl status ddns-updater
# View logs
sudo journalctl -u ddns-updater -f
Service management
sudo systemctl stop ddns-updater # Stop service
sudo systemctl restart ddns-updater # Restart service
sudo systemctl disable ddns-updater # Disable auto-start
macOS (launchd)
Install and set up service
# Build and install binary
make install-macos
# Edit config with your credentials
sudo nano /usr/local/etc/ddns-updater.yaml
# Create launchd service
make service-macos
# Load and start
launchctl load ~/Library/LaunchAgents/com.ddns-updater.plist
launchctl start com.ddns-updater
# View logs
tail -f /usr/local/var/log/ddns-updater.log
Service management
launchctl stop com.ddns-updater # Stop service
launchctl unload ~/Library/LaunchAgents/com.ddns-updater.plist # Unload service
Configuration Reference
# Check interval in minutes (how often to check for IP changes)
check_interval: 5
cloudflare:
api_token: "your-api-token"
zone_id: "your-zone-id"
zone_name: "example.com"
subdomains:
- name: "subdomain"
proxied: false # true = route through Cloudflare proxy (orange cloud)
logging:
file: "ddns-updater.log"
level: "info" # debug, info, warn, error
retry:
max_attempts: 3
delay_seconds: 5
webhook:
enabled: false
url: "" # Optional webhook for notifications
Building from Source
# Build for current platform
make build
# Build for all platforms
make build-all
# Clean build artifacts
make clean
Built binaries will be in ./bin/
Troubleshooting
Authentication errors
- Verify API token has correct permissions (Zone → DNS → Edit, Zone → Zone → Read)
- Confirm token is scoped to the correct zone
- Check token hasn't expired
DNS record not found
- Ensure
zone_namematches your Cloudflare domain exactly - Verify subdomain exists in Cloudflare DNS settings
- Check subdomain name doesn't include the domain (use
home, nothome.example.com)
Service won't start
Linux:
sudo journalctl -u ddns-updater -n 50
macOS:
cat /usr/local/var/log/ddns-updater.err
Docker deployment
Build the image:
docker build -t yourname/ddns-updater:latest .
Run with a local config file:
cp config.yaml.example config.yaml # or make init-config
# edit config.yaml with your Cloudflare settings
docker run -d \
--name ddns-updater \
--restart unless-stopped \
-v $(pwd)/config.yaml:/config/config.yaml:ro \
yourname/ddns-updater:latest
Or with Docker Compose:
docker compose up -d
The container runs in the foreground inside Docker; restarts are handled by Docker’s restart policy.