# 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 ```bash make init-config ``` This creates `config.yaml` with default settings. ### 2. Get Cloudflare credentials #### Generate API Token 1. Log in to [Cloudflare Dashboard](https://dash.cloudflare.com) 2. Go to **Profile** → **API Tokens** 3. Click **Create Token** 4. 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) 5. Copy the token (you'll only see it once) #### Find Zone ID 1. In Cloudflare Dashboard, select your domain 2. Scroll down on the **Overview** page 3. Find **Zone ID** in the right sidebar under **API** section 4. Copy the Zone ID ### 3. Configure Edit `config.yaml`: ```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) ```bash make run ``` Logs will show IP detection and DNS updates in real-time. ## Production Deployment ### Linux (systemd) #### Install and set up service ```bash # 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 ```bash 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 ```bash # 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 ```bash launchctl stop com.ddns-updater # Stop service launchctl unload ~/Library/LaunchAgents/com.ddns-updater.plist # Unload service ``` ## Configuration Reference ```yaml # 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 ```bash # 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_name` matches your Cloudflare domain exactly - Verify subdomain exists in Cloudflare DNS settings - Check subdomain name doesn't include the domain (use `home`, not `home.example.com`) ### Service won't start **Linux:** ```bash sudo journalctl -u ddns-updater -n 50 ``` **macOS:** ```bash cat /usr/local/var/log/ddns-updater.err ``` ### Docker deployment Build the image: ```bash docker build -t yourname/ddns-updater:latest . ``` Run with a local config file: ```bash 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: ```bash docker compose up -d ``` The container runs in the foreground inside Docker; restarts are handled by Docker’s restart policy.