DIY Debian Router - Part 10: Dynamic DNS with ddclient
Introduction
This is Part 10 of the DIY Debian Router series. See Part 1 for the series introduction and links to all parts.
Residential ISPs assign dynamic public IP addresses that change periodically. Dynamic DNS (DDNS) tracks these changes, automatically updating DNS records to point to the current IP. This enables reliable remote access to services without requiring a static IP address.
This part covers:
- Dynamic DNS concepts and architecture
- Porkbun API setup and configuration
- ddclient installation and setup
- Testing and troubleshooting
- Security considerations
Dynamic DNS (DDNS) overview
Traditional DNS maps hostnames to static IP addresses:
example.com → 203.0.113.45 (static)
With dynamic IPs, this mapping becomes stale when the ISP reassigns addresses. DDNS solves this by:
- Detecting IP changes: Router monitors WAN interface for new IP
- Updating DNS records: Sends API request to DNS provider with new IP
- Propagating changes: DNS provider updates authoritative records
- Client resolution: External clients query DNS, receive current IP
Update frequency: Typically 5-15 minutes. DNS TTL should be low (1-5 minutes) for faster propagation.
Without DDNS: You must manually check and update IP address after each ISP change (impractical).
Porkbun API Setup
Porkbun is a domain registrar offering DNS hosting with full API access for DDNS updates. It is the registrar I use and will be covering in this post.
✏️ If you're using a different registrar you'll have to adjust certain steps specific to registrar DDNS configuration.
Enabling API access
- Log into Porkbun account
- Navigate to Account Settings → API Access
- Click Enable API Access (if not already enabled)
- Review and accept the API terms
⚠️ API access is account-wide. API keys will have access to all domains in the account, so protect them carefully.
Generating API keys
Per the official documentation:
- In API Access section, click Create API Key
- Save both keys securely
- API Key: Public identifier
- Secret Key: Private authentication credential
⚠️ HEY, READ THIS: These keys grant full DNS control over your domain. Never share them or commit them to version control. If compromised, an attacker can modify all DNS records for the domain.
Per-domain API enablement
Porkbun requires API access to be enabled per-domain:
- Navigate to Domain Management
- Go to your domain and click the Details button
- Click the API ACCESS button to enable
Without per-domain enablement, API requests will fail with authentication errors.
Porkbun DDNS configuration using ddclient
An example configuration file is given below:
⚠️ The Porkbun API endpoint has changed and it seems only
ddclientversion>=v4.0.0supports the new endpoint. Make sure you have an up-to-date version ofddclient. See this issue for more information.
/etc/ddclient.conf
# ddclient configuration for Porkbun DDNS
daemon=300 # Check every 300 seconds (5 minutes)
syslog=yes # Log to syslog
pid=/var/run/ddclient.pid # PID file location
# Use web-based IP detection (query external service)
usev4=webv4, webv4=ipify-ipv4
# Porkbun configuration
protocol=porkbun
apikey=YOUR_PORKBUN_API_KEY
secretapikey=YOUR_PORKBUN_SECRET_API_KEY
Replace:
YOUR_PORKBUN_API_KEYwith your API keyYOUR_PORKBUN_SECRET_API_KEYwith your secret API keyabsurdum.cawith your domain name
To update multiple hostnames (e.g., root domain and www subdomain):
protocol=porkbun
All listed hostnames will be updated with the same IP address. Porkbun will create or update A records for each hostname.
Make sure to protect the configuration file (contains API credentials):
Alternative IP detection methods
ddclient can detect public IP via multiple methods:
Web-based detection (Recommended)
Query external service:
usev4=webv4, webv4=ipify-ipv4
Providers:
ipify-ipv4: https://api.ipify.org (default, recommended)checkip.dyndns.org: http://checkip.dyndns.orgwhatismyip.akamai.com: http://whatismyip.akamai.com
Advantages: Works behind any NAT, reliable, widely supported.
Disadvantages: Requires external dependency.
Interface-based detection
Read IP from WAN interface:
usev4=if, webv4=enp8s0
Replace enp8s0 with your WAN interface name.
Advantages: No external dependency, faster.
Disadvantages: Requires publicly routable IP on interface (doesn't work if router is behind ISP NAT).
Router status page
Query router's status page:
usev4=web, web-skip='IP Address'
Advantages: Works when router is behind another device.
Disadvantages: Requires parsing router's HTML (fragile, provider-specific).
Starting and enabling ddclient
Enable and start ddclient:
Verify service status:
Check logs for IP updates:
Testing and verification
Manual update test
Force an immediate update:
This runs ddclient once in foreground with debug output.
Common issues:
- Authentication errors: Verify API key and secret are correct, per-domain API is enabled
- "No update required": IP hasn't changed since last update (normal)
- Network errors: Check Internet connectivity
DNS propagation verification
Query the updated DNS record:
This may not return your public IP address depending on how you've setup your internal DNS (unbound) settings. It's best to verify the records from an external host (e.g., VPS, mobile phone on cellular).
Verifying in Porkbun dashboard
Log into Porkbun and check DNS records:
- Navigate to Domain Management
- Select your domain
- Click DNS Records
- Verify A record for your hostname shows current public IP
This confirms updates are propagating to Porkbun's authoritative DNS servers.
IPv6 DDNS configuration
Update both IPv4 and IPv6 records:
# IPv4 configuration
# IPv6 configuration
usev6=webv6, webv6=ipify-ipv6
protocol=porkbun
apikey=YOUR_API_KEY
secretapikey=YOUR_SECRET_KEY
This updates both A (IPv4) and AAAA (IPv6) records. Requires separate configuration blocks.
Next Steps
With Dynamic DNS working, our router is now accessible via a consistent hostname regardless of IP changes.
This concludes our DIY Debian Router setup, see the epilogue for a recap and potential next steps.