dddns

command module
v0.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 19, 2026 License: MIT Imports: 2 Imported by: 0

README ΒΆ

Descoped Dynamic DNS - dddns

CI codecov Go Report Card Release License Go Version Platform

Most home networks receive dynamic public IP addresses via DHCP lease from ISPs, which can change on lease renewal or connection reset. Dynamic DNS (DDNS) solves this by automatically updating DNS records when your IP changes, keeping your domain (like home.example.com) always pointing to your current IP.

dddns is a lightweight, secure DDNS client specifically for AWS Route53, designed to run on resource-constrained devices like Ubiquiti Dream Machines. Perfect for VPN access, home servers, remote management, or any service that needs consistent access to your home network.

Features

πŸš€ Core Functionality
  • AWS Route53 Integration - Updates DNS A records automatically (Route53 only)
  • Smart IP Detection - Reliable public IP detection via checkip.amazonaws.com
  • Change Detection - Only updates when IP actually changes
  • Persistent Caching - Remembers last IP to minimize API calls
  • Proxy/VPN Protection - Detects and prevents updates when behind proxy
  • Dry Run Mode - Test changes without modifying DNS records
  • Force Updates - Override cache when needed
πŸ”’ Security
  • Device-Specific Encryption - AES-256-GCM with hardware-derived keys
  • Secure Credential Storage - Encrypted configs locked to specific hardware
  • No Environment Variables - Credentials stored securely in config files
  • File Permission Enforcement - Automatic 600/400 permissions
  • Memory Wiping - Sensitive data cleared after use
  • AWS Profile Support - Integrates with AWS CLI credentials
πŸ–₯️ Platform Support
  • Ubiquiti Dream Machine - UDM/UDR with UniFi OS v3/v4
  • Linux - AMD64, ARM64, ARM architectures
  • macOS - Intel and Apple Silicon
  • Windows - AMD64 and ARM64
  • Docker - Container deployment ready
  • Automatic Platform Detection - Adjusts paths and behavior per platform
πŸ“¦ Deployment

Three deployment forms, pick whichever matches your setup:

  • Cron mode β€” on-device polling every 30 minutes. The proven default for UDM / UDR / Raspberry Pi. Output flows through journalctl -t dddns; rotation handled by journald.
  • Serve mode β€” on-device event-driven listener for a same-host DDNS client (ddclient, a user script, a Docker sidecar). Supervised by systemd. Experimental on UniFi Dream β€” UniFi's built-in inadyn can't reach the loopback listener; use cron or Lambda there.
  • Lambda mode (v0.3.0+) β€” AWS Lambda + API Gateway endpoint. Event-driven from the cloud, provisioned via OpenTofu. Ideal when UniFi UI's Custom Dynamic DNS is the push source. Costs ~$0/month at household scale. See deploy/aws-lambda/README.md.

Other deployment traits:

  • Single Binary - No dependencies, <10MB size (6MB for the Lambda zip)
  • Low Memory - <20MB runtime usage; GOMEMLIMIT=16MiB ceiling on serve + Lambda
  • Boot Persistence - Survives firmware updates on UDM
  • Cross-platform builds - GoReleaser produces Linux / macOS / Windows / UDM artefacts on every tag

Quick Start

πŸ“‹ Prerequisites: Need to set up AWS Route53 first? See the AWS Setup Guide for step-by-step instructions.

Ubiquiti Dream Machine (UDM/UDR)
# One-line installation (prompts for cron or serve mode on fresh install)
bash <(curl -fsL https://raw.githubusercontent.com/descoped/dddns/main/scripts/install-on-unifi-os.sh)

# Configure
dddns config init

# Test
dddns update --dry-run

# Privacy-safe self-diagnosis (great to paste in a GitHub issue)
bash <(curl -fsL https://raw.githubusercontent.com/descoped/dddns/main/scripts/install-on-unifi-os.sh) --probe

⚠️ Compatibility Note: Check supported models and requirements before installation.

AWS Lambda (v0.3.0+, any cloud-hosted push target)

If the DDNS push source is UniFi UI's Custom Dynamic DNS entry and you don't want to run anything on-device, deploy dddns as an AWS Lambda behind API Gateway. The OpenTofu module at deploy/aws-lambda/tofu/ provisions the whole stack in one apply β€” Lambda, API Gateway, IAM, SSM parameter, CloudWatch log group.

# Build the Lambda zip (Linux arm64, provided.al2023)
just build-aws-lambda

# Configure your deployment (zone ID + hostname)
cd deploy/aws-lambda/tofu
cp terraform.tfvars.example terraform.tfvars
$EDITOR terraform.tfvars

# Deploy
tofu init && tofu apply

# Rotate secret and paste into UniFi UI
cd .. && ./scripts/rotate-secret.sh

Household-scale deployments stay in the AWS free tier. See deploy/aws-lambda/README.md for the full guide, cost breakdown, and teardown instructions.

macOS
# Install via Homebrew
brew tap descoped/tap
brew install dddns

# Configure and run
dddns config init
dddns update
Linux
Debian/Ubuntu
# Download and install the .deb package
curl -LO https://github.com/descoped/dddns/releases/latest/download/dddns_Linux_x86_64.deb
sudo dpkg -i dddns_Linux_x86_64.deb

# For ARM64 systems:
curl -LO https://github.com/descoped/dddns/releases/latest/download/dddns_Linux_arm64.deb
sudo dpkg -i dddns_Linux_arm64.deb
Red Hat/CentOS/Fedora
# Install the .rpm package
sudo rpm -ivh https://github.com/descoped/dddns/releases/latest/download/dddns_Linux_x86_64.rpm

# For ARM64 systems:
sudo rpm -ivh https://github.com/descoped/dddns/releases/latest/download/dddns_Linux_arm64.rpm
Configure and run
dddns config init
dddns update

Commands

dddns update [--dry-run] [--force] [--quiet]  # Update DNS record
dddns config init                              # Interactive configuration
dddns config check                             # Validate configuration
dddns ip                                       # Show current public IP
dddns verify                                   # Check DNS vs current IP
dddns secure enable                            # Enable encrypted config
dddns --version                                # Show version

Documentation

How It Works

flowchart LR
    A[Cron Job<br/>Every 30 min]:::start
    A -.-> B

    subgraph " "
        direction LR
        B[dddns update] --> C{Check IP}
        C --> D[Get IP]
        D --> E{Compare<br/>Cache}
        E -->|Changed| F[Query<br/>Route53]
        E -->|Same| G[Skip]
        F --> H{Need<br/>Update?}
        H -->|Yes| I[Update<br/>DNS]:::update
        H -->|No| G
        I --> J[Cache &<br/>Log]
    end

    J --> L[Exit]:::exit
    G --> L

    A ~~~ B
    J ~~~ L

    classDef start fill:#f9f,stroke:#333,stroke-width:2px
    classDef update fill:#9f9,stroke:#333,stroke-width:2px
    classDef exit fill:#ff9,stroke:#333,stroke-width:2px

The flow ensures minimal API calls and only updates DNS when necessary, making it efficient and ISP-friendly.

πŸ’‘ Cost Tip: Running your own dynamic DNS with AWS Route53 costs approximately USD 0.50 per month for a hosted zone. This makes dddns a very affordable solution for reliable home network access.

Development

Prerequisites
  • Go 1.26+
  • just (brew install just on macOS)
  • OpenTofu 1.6+ (only needed to deploy the AWS Lambda form)
Building
# Clone repository
git clone https://github.com/descoped/dddns.git
cd dddns

# Build for current platform
just build

# Race build for local dev
just dev

# Run tests
just test

# Cross-platform release binaries are produced by GoReleaser on every
# tag push β€” see .github/workflows/goreleaser.yml. To exercise it
# locally, install goreleaser and run `goreleaser build --snapshot`.
Project Structure
cmd/                  # CLI commands
internal/
β”œβ”€β”€ config/          # Configuration management
β”œβ”€β”€ crypto/          # Device-specific encryption
β”œβ”€β”€ dns/             # Route53 client
β”œβ”€β”€ profile/         # Platform detection
└── version/         # Version information
Release Process

Releases use GoReleaser with git tags:

git tag v1.0.0
git push origin v1.0.0

GitHub Actions automatically builds and releases binaries for all platforms.

Configuration

Need AWS Route53? Follow the AWS Setup Guide to create your hosted zone and IAM credentials first.

Example Configuration
# ~/.dddns/config.yaml
aws_region: us-east-1
hosted_zone_id: ZXXXXXXXXXXXXX  # Get this from AWS Setup Guide
hostname: home.example.com
ttl: 300

# AWS credentials (or use AWS profile)
access_key: AKIAXXXXXXXXXXXXXX
secret_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Secure Configuration

For enhanced security, use encrypted configuration:

# Convert to encrypted config
dddns secure enable

# Config is now encrypted with device-specific key
# Cannot be moved between devices

Support

Reporting Issues

If you encounter any problems:

  1. Check the Troubleshooting Guide first
  2. Search existing issues to see if it's already reported
  3. Create a new issue with:
    • Your platform (UDM model, OS version)
    • dddns version (dddns --version)
    • Error messages or logs
    • Steps to reproduce
Getting Help
  • πŸ“– Documentation - Comprehensive guides
  • πŸ› Issues - Report bugs or request features
  • πŸ’¬ Discussions - Ask questions and share ideas

Contributing

We welcome contributions! Whether it's bug fixes, new features, or documentation improvements, your help is appreciated.

How to Contribute
  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Run tests (just test)
  5. Commit your changes (git commit -m 'feat: add amazing feature')
  6. Push to your branch (git push origin feature/amazing-feature)
  7. Open a Pull Request
Development Guidelines
  • Follow Go best practices and conventions
  • Add tests for new functionality
  • Update documentation as needed
  • Keep commits atomic and well-described
  • Ensure all tests pass before submitting PR
Areas for Contribution
  • πŸ› Bug fixes
  • πŸ“š Documentation improvements
  • πŸ§ͺ Test coverage expansion
  • πŸ”§ Performance optimizations
  • 🎨 Code refactoring
  • 🌐 Support for more DNS providers

License

This project is licensed under the MIT License - see the LICENSE file for details.


Note: This tool is specifically designed for AWS Route53. If you need support for other DNS providers, please open an issue to discuss potential implementation.

Documentation ΒΆ

Overview ΒΆ

Copyright Β© 2024 NAME HERE <EMAIL ADDRESS>

Directories ΒΆ

Path Synopsis
deploy
aws-lambda command
Command aws-lambda is the dddns deployment form that runs behind an API Gateway HTTP API on AWS Lambda.
Command aws-lambda is the dddns deployment form that runs behind an API Gateway HTTP API on AWS Lambda.
internal
bootscript
Package bootscript generates the on_boot.d script for UniFi Dream devices.
Package bootscript generates the on_boot.d script for UniFi Dream devices.
dns
Package dns provides a minimal Route53 REST client (no AWS SDK).
Package dns provides a minimal Route53 REST client (no AWS SDK).
server
Package server implements the dddns HTTP listener that translates dyndns-style requests from UniFi's inadyn into Route53 updates.
Package server implements the dddns HTTP listener that translates dyndns-style requests from UniFi's inadyn into Route53 updates.
updater
Package updater implements the core DNS update flow shared by the cron path (cmd/update.go) and the serve handler (internal/server).
Package updater implements the core DNS update flow shared by the cron path (cmd/update.go) and the serve handler (internal/server).
verify
Package verify produces a DNS-propagation snapshot for the `dddns verify` command.
Package verify produces a DNS-propagation snapshot for the `dddns verify` command.
wanip
Package wanip resolves the router's current public IPv4 address by reading the WAN interface directly from the OS, avoiding the round trip to checkip.amazonaws.com.
Package wanip resolves the router's current public IPv4 address by reading the WAN interface directly from the OS, avoiding the round trip to checkip.amazonaws.com.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL