Dynamic DNS (DDNS) in VyOS
Dynamic DNS (DDNS) is a service that automatically updates DNS records when an IP address changes. VyOS includes a built-in DDNS client that can update records at various dynamic DNS providers, which is critical for remote access to devices with dynamic IP addresses.
Overview
Dynamic DNS solves the problem of accessing devices with changing IP addresses:
- Home/small offices: Access to the network through a dynamic IP from the ISP
- Branch offices: Remote access without static IP addresses
- VPN connections: Stable endpoints for VPN tunnels
- Remote management: A persistent DNS name for SSH/HTTPS access
- Self-hosted services: Access to web servers, cameras, and NAS on a home IP
How DDNS works
- VyOS monitors the IP address on the specified interface
- When the IP changes, the change is detected
- VyOS sends an update to the DDNS provider via an API/protocol
- The provider updates the DNS record
- The DNS name now points to the new IP address
Supported protocols
VyOS supports a wide range of DDNS providers and protocols:
- Standard protocols: DynDNS2, Cloudflare, Namecheap, No-IP, Google Domains
- Custom protocols: RFC2136 (DNS UPDATE), custom HTTP/HTTPS APIs
- Multiple providers: Several providers and records at the same time
Basic configuration
DynDNS2 protocol (No-IP, DynDNS)
# DDNS configuration for No-IP
set service dns dynamic name noip service noip
set service dns dynamic name noip host-name myrouter.ddns.net
set service dns dynamic name noip username myusername
set service dns dynamic name noip password mypassword
set service dns dynamic name noip interface eth0
commit
saveCloudflare DDNS
# Cloudflare uses email + API key
set service dns dynamic name cloudflare service cloudflare
set service dns dynamic name cloudflare host-name myrouter.example.com
set service dns dynamic name cloudflare username email@example.com
set service dns dynamic name cloudflare password cloudflare-api-key
set service dns dynamic name cloudflare zone example.com
set service dns dynamic name cloudflare interface eth0
commit
saveGoogle Domains DDNS
# Google Domains DDNS
set service dns dynamic name google service googledomains
set service dns dynamic name google host-name myrouter.example.com
set service dns dynamic name google username generated-username
set service dns dynamic name google password generated-password
set service dns dynamic name google interface eth0
commit
saveNamecheap DDNS
# Namecheap DDNS
set service dns dynamic name namecheap service namecheap
set service dns dynamic name namecheap host-name myrouter
set service dns dynamic name namecheap username example.com
set service dns dynamic name namecheap password ddns-password
set service dns dynamic name namecheap interface eth0
commit
saveAdvanced configuration
RFC2136 (DNS UPDATE)
RFC2136 lets you update DNS records directly on a server that supports dynamic updates (for example, BIND).
# RFC2136 setup
set service dns dynamic name rfc2136 service rfc2136
set service dns dynamic name rfc2136 server ns1.example.com
set service dns dynamic name rfc2136 zone example.com
set service dns dynamic name rfc2136 host-name router.example.com
set service dns dynamic name rfc2136 key /config/auth/ddns-key.txt
set service dns dynamic name rfc2136 ttl 60
set service dns dynamic name rfc2136 interface eth0
commit
saveThe key file /config/auth/ddns-key.txt (TSIG key):
key "ddns-key" {
algorithm hmac-sha256;
secret "base64-encoded-secret-here==";
};Multiple DDNS records
# First provider (No-IP for primary access)
set service dns dynamic name primary service noip
set service dns dynamic name primary host-name myrouter.ddns.net
set service dns dynamic name primary username user1
set service dns dynamic name primary password pass1
set service dns dynamic name primary interface eth0
# Second provider (DuckDNS as a backup)
set service dns dynamic name backup service duckdns
set service dns dynamic name backup host-name myrouter.duckdns.org
set service dns dynamic name backup password duckdns-token
set service dns dynamic name backup interface eth0
# Third provider (Cloudflare for the corporate domain)
set service dns dynamic name corporate service cloudflare
set service dns dynamic name corporate host-name vpn.company.com
set service dns dynamic name corporate username admin@company.com
set service dns dynamic name corporate password cloudflare-api-key
set service dns dynamic name corporate zone company.com
set service dns dynamic name corporate interface eth0
commit
saveMonitoring through the provider web interface
# Configuration with an IP-check URL (to determine the external IP)
set service dns dynamic name myservice service custom
set service dns dynamic name myservice host-name myhost.example.com
set service dns dynamic name myservice username myuser
set service dns dynamic name myservice password mypass
set service dns dynamic name myservice interface eth0
set service dns dynamic name myservice protocol dyndns2
set service dns dynamic name myservice server updates.example.com
commit
saveUsing a web request to obtain the IP
If the router is behind NAT and you need to determine the external IP:
# DDNS setup with a web-based IP detection method
set service dns dynamic name myservice service noip
set service dns dynamic name myservice host-name myrouter.ddns.net
set service dns dynamic name myservice username myuser
set service dns dynamic name myservice password mypass
set service dns dynamic name myservice interface eth0
set service dns dynamic name myservice ip-check web
set service dns dynamic name myservice web-url https://api.ipify.org
commit
saveUpdate interval
# Set the check interval (in seconds, default 300)
set service dns dynamic name myservice service noip
set service dns dynamic name myservice host-name myrouter.ddns.net
set service dns dynamic name myservice username myuser
set service dns dynamic name myservice password mypass
set service dns dynamic name myservice interface eth0
set service dns dynamic name myservice timeout 600 # Check every 10 minutes
commit
saveIPv6 DDNS
# DDNS for an IPv6 address
set service dns dynamic name ipv6ddns service cloudflare
set service dns dynamic name ipv6ddns host-name myrouter-v6.example.com
set service dns dynamic name ipv6ddns username email@example.com
set service dns dynamic name ipv6ddns password cloudflare-api-key
set service dns dynamic name ipv6ddns zone example.com
set service dns dynamic name ipv6ddns interface eth0
set service dns dynamic name ipv6ddns ip-version ipv6
commit
saveConfiguration examples
Example 1: Home router with No-IP
# Simple configuration for home access
set service dns dynamic name home service noip
set service dns dynamic name home host-name myhome.ddns.net
set service dns dynamic name home username homeuser
set service dns dynamic name home password HomePass123!
set service dns dynamic name home interface eth0
commit
saveVerification:
show dns dynamic statusExample 2: VPN endpoint with Cloudflare
# DDNS for a VPN endpoint on a corporate domain
set service dns dynamic name vpn-endpoint service cloudflare
set service dns dynamic name vpn-endpoint host-name vpn.company.com
set service dns dynamic name vpn-endpoint username admin@company.com
set service dns dynamic name vpn-endpoint password cf_api_key_here
set service dns dynamic name vpn-endpoint zone company.com
set service dns dynamic name vpn-endpoint interface eth0
# The WireGuard VPN endpoint uses this DNS name
set interfaces wireguard wg0 address 10.10.0.1/24
set interfaces wireguard wg0 listen-port 51820
set interfaces wireguard wg0 peer client1 allowed-ips 10.10.0.2/32
set interfaces wireguard wg0 peer client1 public-key 'peer-public-key-here'
commit
saveWireGuard client configuration:
[Interface]
PrivateKey = client-private-key
Address = 10.10.0.2/24
[Peer]
PublicKey = server-public-key
Endpoint = vpn.company.com:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25Example 3: Multiple branch offices
# Head office
set service dns dynamic name hq service cloudflare
set service dns dynamic name hq host-name hq-router.company.com
set service dns dynamic name hq username admin@company.com
set service dns dynamic name hq password cloudflare-key
set service dns dynamic name hq zone company.com
set service dns dynamic name hq interface eth0
# Backup record on a free service
set service dns dynamic name hq-backup service duckdns
set service dns dynamic name hq-backup host-name company-hq.duckdns.org
set service dns dynamic name hq-backup password duckdns-token
set service dns dynamic name hq-backup interface eth0
commit
saveExample 4: Self-hosted services (web, mail)
# DDNS for a web server
set service dns dynamic name webserver service cloudflare
set service dns dynamic name webserver host-name www.example.com
set service dns dynamic name webserver username admin@example.com
set service dns dynamic name webserver password cloudflare-api-key
set service dns dynamic name webserver zone example.com
set service dns dynamic name webserver interface eth0
# Port forwarding for the web server
set nat destination rule 100 description 'Port forward HTTP'
set nat destination rule 100 inbound-interface name eth0
set nat destination rule 100 destination port 80
set nat destination rule 100 protocol tcp
set nat destination rule 100 translation address 192.168.1.10
set nat destination rule 110 description 'Port forward HTTPS'
set nat destination rule 110 inbound-interface name eth0
set nat destination rule 110 destination port 443
set nat destination rule 110 protocol tcp
set nat destination rule 110 translation address 192.168.1.10
commit
saveExample 5: RFC2136 with your own DNS server
# BIND DNS server with dynamic update support
set service dns dynamic name internal service rfc2136
set service dns dynamic name internal server 192.168.1.53
set service dns dynamic name internal zone internal.company.com
set service dns dynamic name internal host-name router.internal.company.com
set service dns dynamic name internal key /config/auth/ddns-update-key.txt
set service dns dynamic name internal ttl 300
set service dns dynamic name internal interface eth1
commit
saveOn the BIND server (/etc/bind/named.conf.local):
key "ddns-key" {
algorithm hmac-sha256;
secret "your-base64-secret==";
};
zone "internal.company.com" {
type master;
file "/var/lib/bind/db.internal.company.com";
allow-update { key ddns-key; };
};Example 6: Dual-stack (IPv4 + IPv6)
# IPv4 DDNS
set service dns dynamic name dual-v4 service cloudflare
set service dns dynamic name dual-v4 host-name router.example.com
set service dns dynamic name dual-v4 username admin@example.com
set service dns dynamic name dual-v4 password cloudflare-key
set service dns dynamic name dual-v4 zone example.com
set service dns dynamic name dual-v4 interface eth0
set service dns dynamic name dual-v4 ip-version ipv4
# IPv6 DDNS (AAAA record)
set service dns dynamic name dual-v6 service cloudflare
set service dns dynamic name dual-v6 host-name router.example.com
set service dns dynamic name dual-v6 username admin@example.com
set service dns dynamic name dual-v6 password cloudflare-key
set service dns dynamic name dual-v6 zone example.com
set service dns dynamic name dual-v6 interface eth0
set service dns dynamic name dual-v6 ip-version ipv6
commit
saveMonitoring and diagnostics
Viewing DDNS status
# Show the status of all DDNS services
show dns dynamic status
# The output includes:
# - Service name
# - Hostname
# - Current IP
# - Last update
# - Status (good, nochange, error)Example output:
service: cloudflare
hostname: myrouter.example.com
address: 203.0.113.45
status: good
last update: Mon Jan 15 10:30:45 2024Forcing an update
# Force an update for a specific service
update dns dynamic interface eth0
# This makes VyOS immediately send an update to all configured providersViewing DDNS logs
# DDNS logs in syslog
show log | match ddclient
# The last 50 entries
show log tail 50 | match ddclient
# Real-time monitoring
monitor log | match ddclientChecking the current IP
# Current IP on the interface
show interfaces ethernet eth0 | grep "inet "
# External IP (if behind NAT)
curl ifconfig.me
curl api.ipify.orgChecking DNS resolution
# Verify that the DNS record has been updated
nslookup myrouter.ddns.net
# Or using dig
dig myrouter.ddns.net +short
# Check through a specific DNS server
dig @8.8.8.8 myrouter.ddns.netDebugging issues
# Check the configuration
show configuration service dns dynamic
# Detailed logs (enable debug)
set system syslog file ddns.log facility daemon level debug
commit
# View the logs
tail -f /var/log/ddns.log
# Disable debug after troubleshooting
delete system syslog file ddns.log facility daemon level debug
commitMonitoring with a script
#!/bin/bash
# /config/scripts/monitor-ddns.sh
HOSTNAME="myrouter.ddns.net"
EXPECTED_IP=$(curl -s ifconfig.me)
RESOLVED_IP=$(dig +short $HOSTNAME | head -n1)
if [ "$EXPECTED_IP" != "$RESOLVED_IP" ]; then
echo "DDNS mismatch: Expected $EXPECTED_IP, Got $RESOLVED_IP"
logger -t ddns-monitor "DDNS mismatch detected"
# Send an alert
echo "DDNS issue on $(hostname)" | mail -s "DDNS Alert" admin@example.com
else
logger -t ddns-monitor "DDNS check OK: $RESOLVED_IP"
fiAdd it to the Task Scheduler:
set system task-scheduler task ddns-monitor interval '*/15 * * * *'
set system task-scheduler task ddns-monitor executable path '/config/scripts/monitor-ddns.sh'
commit
saveTroubleshooting
Problem: DDNS is not updating
Diagnostics:
# 1. Check the configuration
show configuration service dns dynamic
# 2. Check the status
show dns dynamic status
# 3. Check the logs
show log | match ddclient
# 4. Check the interface
show interfaces ethernet eth0
# 5. Check connectivity to the provider
ping updates.no-ip.comSolution:
# Verify credentials
set service dns dynamic name myservice username correct-username
set service dns dynamic name myservice password correct-password
# Force an update
update dns dynamic interface eth0
# Restart the service (if necessary)
sudo systemctl restart ddclient
commit
saveProblem: The IP is detected incorrectly (behind NAT)
Cause: VyOS uses the interface IP instead of the external IP.
Solution:
# Use the web method to determine the IP
set service dns dynamic name myservice ip-check web
set service dns dynamic name myservice web-url https://api.ipify.org
commit
saveAlternative URLs for IP detection:
https://api.ipify.orghttps://ifconfig.me/iphttps://icanhazip.comhttps://checkip.amazonaws.com
Problem: Updates are too frequent
Cause: The provider may block you for abuse (too many requests).
Solution:
# Increase the check interval
set service dns dynamic name myservice timeout 3600 # 1 hour
commit
saveProblem: Authentication fails
Diagnostics:
# Check the logs
show log | match "authentication failed"
show log | match ddclientSolution:
# Verify the credentials in the provider's web interface
# Recreate the configuration with the correct credentials
delete service dns dynamic name myservice
set service dns dynamic name myservice service noip
set service dns dynamic name myservice host-name myrouter.ddns.net
set service dns dynamic name myservice username correct-username
set service dns dynamic name myservice password correct-password
set service dns dynamic name myservice interface eth0
commit
save
# Force an update
update dns dynamic interface eth0Problem: Hostname is not updating on Cloudflare
Cause: Cloudflare requires the zone to be specified.
Solution:
# Make sure the zone is specified
set service dns dynamic name cloudflare zone example.com
# Make sure you use the correct API key (not an API token)
# Cloudflare requires the Global API Key, not a Scoped API Token
commit
saveProblem: RFC2136 updates do not work
Diagnostics:
# Check DNS server availability
ping 192.168.1.53
# Check UDP port 53
nc -vu 192.168.1.53 53
# Check the key
cat /config/auth/ddns-key.txtSolution:
# Make sure the key is configured correctly on both sides
# On VyOS, the key file must contain:
# key "ddns-key" {
# algorithm hmac-sha256;
# secret "base64-secret==";
# };
# On BIND, the zone must allow updates:
# allow-update { key ddns-key; };
# Test the update manually from the client
nsupdate -k /config/auth/ddns-key.txt
> server 192.168.1.53
> zone example.com
> update add test.example.com 300 A 192.168.1.100
> send
> quitPopular DDNS providers
Free services
| Provider | Protocol | Notes |
|---|---|---|
| No-IP | noip | 3 hostnames free, requires confirmation every 30 days |
| DuckDNS | duckdns | Free, no limits, simple |
| FreeDNS | freedns | Many domains, free |
| Dynu | dynu | 4 hostnames free |
Paid/Freemium services
| Provider | Protocol | Notes |
|---|---|---|
| Cloudflare | cloudflare | Free plan + DNS management |
| Google Domains | googledomains | Requires a domain in Google Domains |
| Namecheap | namecheap | DDNS for Namecheap domains |
| DynDNS | dyndns2 | Paid service, reliable |
Configuration for popular providers
DuckDNS:
set service dns dynamic name duckdns service duckdns
set service dns dynamic name duckdns host-name mysubdomain.duckdns.org
set service dns dynamic name duckdns password token-from-duckdns
set service dns dynamic name duckdns interface eth0FreeDNS:
set service dns dynamic name freedns service freedns
set service dns dynamic name freedns host-name myhost.freeddns.org
set service dns dynamic name freedns password update-token
set service dns dynamic name freedns interface eth0Dynu:
set service dns dynamic name dynu service dynu
set service dns dynamic name dynu host-name myhost.dynu.net
set service dns dynamic name dynu username dynu-username
set service dns dynamic name dynu password dynu-password
set service dns dynamic name dynu interface eth0Best practices
1. Use reliable providers
Choose proven providers with a good SLA:
# For production - Cloudflare or Google Domains
set service dns dynamic name primary service cloudflare
# For home/lab - DuckDNS or No-IP
set service dns dynamic name home service duckdns2. DDNS redundancy
Configure multiple providers for redundancy:
# Primary
set service dns dynamic name primary service cloudflare
set service dns dynamic name primary host-name router.example.com
# Backup
set service dns dynamic name backup service duckdns
set service dns dynamic name backup host-name router-backup.duckdns.org3. Secure password storage
Do not use simple passwords:
# Bad
set service dns dynamic name myservice password 123456
# Good - use complex tokens/keys
set service dns dynamic name myservice password 'aB3$kL9@mN5&pQ2#'4. DDNS monitoring
Set up monitoring for critical hostnames:
# Task Scheduler for checks
set system task-scheduler task ddns-check interval '*/15 * * * *'
set system task-scheduler task ddns-check executable path '/config/scripts/check-ddns.sh'5. Logging
Enable DDNS logging for auditing:
set system syslog file ddns.log facility daemon level info6. A proper update interval
Do not set updates too frequently:
# 5-15 minutes is recommended for dynamic IPs
set service dns dynamic name myservice timeout 600 # 10 minutes7. TTL for DNS records
Use a low TTL for DDNS records:
# For RFC2136
set service dns dynamic name internal ttl 60 # 1 minute8. Documentation
Document the DDNS hostnames you use:
# Use descriptive names in the configuration
set service dns dynamic name vpn-endpoint ...
set service dns dynamic name web-server ...
set service dns dynamic name remote-access ...9. Test after setup
Always test DDNS after configuring it:
# Force an update
update dns dynamic interface eth0
# Check the status
show dns dynamic status
# Check DNS
dig myrouter.ddns.net +short10. Automation for multiple devices
Use Ansible to manage DDNS across many routers:
- name: Configure DDNS
vyos.vyos.vyos_config:
lines:
- set service dns dynamic name {{ ddns_name }} service {{ ddns_provider }}
- set service dns dynamic name {{ ddns_name }} host-name {{ ddns_hostname }}
- set service dns dynamic name {{ ddns_name }} username {{ ddns_username }}
- set service dns dynamic name {{ ddns_name }} password {{ ddns_password }}
- set service dns dynamic name {{ ddns_name }} interface {{ ddns_interface }}Useful commands
# Show DDNS status
show dns dynamic status
# Force an update
update dns dynamic interface eth0
# DDNS configuration
show configuration service dns dynamic
# DDNS logs
show log | match ddclient
show log tail 50 | match ddclient
# Real-time log monitoring
monitor log | match ddclient
# Check DNS resolution
nslookup myrouter.ddns.net
dig myrouter.ddns.net +short
# Check the external IP
curl ifconfig.me
curl api.ipify.org
# Restart the DDNS client (if needed)
sudo systemctl restart ddclient
# Service status
sudo systemctl status ddclient
# View the ddclient configuration
sudo cat /etc/ddclient/ddclient.confIntegration with other features
DDNS + VPN
# DDNS for a WireGuard endpoint
set service dns dynamic name wg-endpoint service cloudflare
set service dns dynamic name wg-endpoint host-name wg.example.com
set service dns dynamic name wg-endpoint username admin@example.com
set service dns dynamic name wg-endpoint password cloudflare-key
set service dns dynamic name wg-endpoint zone example.com
set service dns dynamic name wg-endpoint interface eth0
# WireGuard configuration
set interfaces wireguard wg0 address 10.10.0.1/24
set interfaces wireguard wg0 listen-port 51820Clients use wg.example.com:51820 as the endpoint.
DDNS + Port Forwarding
# DDNS for self-hosted services
set service dns dynamic name web service cloudflare
set service dns dynamic name web host-name web.example.com
# NAT for HTTP/HTTPS
set nat destination rule 100 inbound-interface name eth0
set nat destination rule 100 destination port 80
set nat destination rule 100 protocol tcp
set nat destination rule 100 translation address 192.168.1.10
set nat destination rule 110 inbound-interface name eth0
set nat destination rule 110 destination port 443
set nat destination rule 110 protocol tcp
set nat destination rule 110 translation address 192.168.1.10DDNS + Let’s Encrypt
# DDNS updates the DNS record for the Let's Encrypt DNS-01 challenge
set service dns dynamic name acme service cloudflare
set service dns dynamic name acme host-name router.example.com
# Let's Encrypt can verify domain ownership through DNSConclusion
Dynamic DNS in VyOS is a reliable solution for keeping devices with dynamic IP addresses reachable. The built-in DDNS client supports all the major providers and protocols, providing both flexibility and reliability.
Key benefits of DDNS in VyOS:
- Support for multiple providers at the same time
- Automatic updates when the IP changes
- Integration with VPN, web services, and remote access
- RFC2136 for integration with your own DNS servers
- Dual-stack support (IPv4 + IPv6)
Recommendations for production:
- Use reliable providers (Cloudflare, Google Domains)
- Configure backup DDNS records
- Monitor the status of DDNS updates
- Use a proper update interval (5-15 minutes)
- Document all DDNS hostnames
- Test after every configuration change
Dynamic DNS in VyOS provides stable remote access to your network infrastructure without the need for static IP addresses, which is critical for small offices, branch offices, and home networks.