DDNS client

DDNS stands for Dynamic DNS. Simply put, using this service gives a name to your IP. So if you're hosting something on your line, people would not have to bother typing your IP. They can just type in your domain name! It also helps when your IP changes. Users won't need to discover what your new IP is, they can simply type your domain name.

This guide will help you configure your DDNS service, so that your router auto-updates your IP to your DDNS provider. The simplest method possible would be through LuCI.

OpenWrt uses ddns-scripts which are shell scripts. There are other scripts and programs available in the web, also some DDNS providers offer their own programs. All of them are currently not ported and tested on OpenWrt.

ddns-scripts support other special communication functions:

  • Run once, useful for usage with cron.
  • Set proxy with/without authentication for HTTP/HTTPS requests.
  • Set DNS server to use other than system default.
  • Binding to specific network if wget or to specific interface if curl installed.
  • Force the usage of either IPv4 or IPv6 communication only. Require either wget or curl AND bind-host
  • DNS requests via TCP, require either wget or curl AND bind-host.

First of all, you'll need to pick and register a DNS name with a compatible DDNS service provider. For a list of DDNS providers, see:

ddns-scripts support the following Dynamic DNS service providers out of the box:
3322.org dnspark.com easydns.com mythic-beasts.com 6) servercow.de
afraid.org 6) dnsever.com editdns.net namecheap.com simply.com
all-inkl.com do.de 6) goip.de 6) nettica.com sitelutions.com
changeip.com domopoli.de google.com 5) 6) njal.la spdyn.de 6) (spdns.de)
cloudflare.com 2) 5) 6) dtdns.com dns.he.net 6) now-dns.com strato.com
core-networks.de 6) duckdns.org 6) he.net no-ip.com 1) (noip.com) system-ns.com
ddnss.de 6) duiadns.net 6) hosting.de no-ip.pl 6) thatip.com
ddo.jp dy.fi infomaniak.com nsupdate.info 6) transip.nl
desec.io dyndns.it ipnodns.ru nubem.com twodns.de
dhis.org 6) dyndns.org 6) (dyn.com) inwx.de ovh.com udmedia.de
dnsdynamic.org dyndnss.net joker.com opendns.com variomedia.de 6)
dnsexit.com dyns.net loopia.se 6) (loopia.com) oray.com xlhost.de
dnshome.de 6) dynsip.org moniker.com regfish.de 6) zoneedit.com 5)
dnsmax.com dynu.com mydns.jp 6) schokokeks.org BIND nsupdate 3) 4) 6)
dnsomatic.com dynv6.com 6) myonlineportal.net 6) selfhost.de
  1. Requires additional package ddns-scripts-noip to be installed.
  2. Needs additional package ddns-scripts-cloudflare to be installed.
  3. Directly updates a DNS server (Bind, PowerDNS, Knot) via nsupdate (RFC 2136).
  4. Needs additional package ddns-scripts-nsupdate and bind-client to be installed.
  5. Requires SSL support.
  6. Supports IPv6.

If you have picked a DDNS service provider and create your host/domain name you need to note additional your username and password. Now you need to decide if you want to use secure communication with your DDNS provider or not. Some provider require secure HTTPS communication. Read their help pages for details and also read provider specific information below.

Set up DDNS client service using web interface.

  1. Navigate to LuCI → System → Software
  2. Press the button Update Lists to update internal lists of available packages.
  3. Install the packages ddns-scripts and luci-app-ddns to provide DDNS client service and web interface.
  4. Install the packages wget-ssl and ca-certificates, or curl and ca-bundle for SSL support.
  5. Install the provider specific packages ddns-scripts_* and LuCI language packages luci-i18n-ddns-*.
  6. Refresh the page and navigate to LuCI → Services → Dynamic DNS.
  7. Use the instances myddns_ipv4 and myddns_ipv6 or delete them and define your own.
  8. Modify the fields you need to change and check the Enabled option.
  9. Click Save & Apply button to save changes.

Install ddns-scripts and the provider-specific packages ddns-scripts_xxxxx. Also provide SSL support with wget and ca-certificates, or curl and ca-bundle.

opkg update
opkg install ddns-scripts
opkg install ddns-scripts_xxxxx
opkg install wget ca-certificates
opkg install curl ca-bundle

Proceed with setting up the service using the UCI commands.

ddns-scripts are designed to update one host per configuration/section. To update multiple hosts or providers or IPv4 and IPv6 for the same host you need to define separate configurations/sections. Some providers offer to update multiple host within one update request. A possible solution for this option is to use --custom-- service name settings. Have a look at provider specifics.

The main settings you need to set:

Service name The DDNS service provider to use
Lookup Host One of your FQDNs you want to update, used by ddns-scripts with nslookup to check if update has happened
Host/Domain Mostly same as lookup host, but can provide a list of hosts to be updated
Username Username or other parameter to use as username (send urlencoded)
Password Password or other parameter to use as password (send urlencoded)
:!: Ensure this password does not have have $ characters, as this breaks the script.
Interface Network name used by OpenWrt hotplug event system to start ddns-scripts, e.g. wan, wan6
  • It is not allowed to use dash-sign “-” inside configuration/section names.
  • A full list of supported settings (some not supported by LuCI) you will find in UCI documentation.
  • Always keep in mind the Provider specific settings if there are any.
  • Don't forget to enable your configuration/section.
  • You need minimum one enabled configuration/section for ddns service to start.
  • You need to enable ddns service to enable updates being sent on reboot and hotplug events.
  • Do not change the files /usr/lib/ddns/services or /usr/lib/ddns/services_ipv6 as they can be overwritten by system and package updates.

SSL support

Options to configure HTTPS communication are only available if wget or curl package is installed.

  • Check Use HTTP Secure option. Additional field Path to CA-Certificate is shown with it's default setting.
    • If you have installed ca-certificates package leave the shown default /etc/ssl/certs.
    • If you have installed CA certificates in one file from above set the value to /etc/ssl/certs/ca-certificates.crt.
    • If you like to use other certificate you need to set here the full path to the certificate including file name, e.g. /path/to/file.crt.
    • If your certificates are stored in a different path, set here the path where your certificates are located, e.g. /path/to/files.
  • Click Save & Apply button to save changes.

Custom service

If you want to use a DDNS provider currently not listed or you want to update multiple hosts within one configuration/section then you should do the following:

  • Choose --custom-- as service. Additional field Custom update-URL is shown.
  • Fill in the URL you like to use. :!: Please read URL syntax description below. Also have a look at provider specifics.
  • Click Save & Apply button to save changes.

:!: If you found a DDNS provider not listed or with additional IPv6 support or with changed update URL please open an issue at Github-OpenWrt-Packages so it can be included with the next release.

The easiest way to configure ddns-scripts via console is to edit the file /etc/config/ddns directly using build-in vi editor or any other editor you prefer. Other editors as vi needs to be installed separately.

A configuration/section looks like:

# /etc/config/ddns
config 'service' 'myddns'
	option 'service_name'	'example.org'
	option 'enabled'	'1'
	option 'domain'		'yourhost.example.org'
	option 'username'	'your_username'
	option 'password'	'your_password'
	option 'interface'	'wan'
	option 'ip_source'	'network'
	option 'ip_network'	'wan'

Alternatively you can use UCI command line interface. Example input:

uci set ddns.myddns.service_name="ddnsprovider.com"	# only use names listed in /usr/lib/ddns/services
							# or /usr/lib/ddns/services_ipv6 (since CC 15.05)
uci set ddns.myddns.domain="host.yourdomain.net"
uci set ddns.myddns.username="your_user_name"
uci set ddns.myddns.password="p@ssw0rd"
uci set ddns.myddns.interface="wan"	# network interface that should start this configuration/section
uci set ddns.myddns.enabled="1"
uci commit ddns				# don't forget this, otherwise data not written to configuration file

ddns.myddns.enabled=“1” means:

  • ddns is the configuration file to change (here /etc/config/ddns)
  • myddns is the configuration/section to change
  • enabled is the option to set/change
  • behind the equal-sign is the value to set. :!: Set single- or double-quotes around the value and no space or whitespace around the equal-sign.

Example to create/add a new configuration/section “newddns”:

uci set ddns.newddns="service"
uci set ddns.newddns.service_name="ddnsprovider.com"	# only use names listed in /usr/lib/ddns/services
							# or /usr/lib/ddns/services_ipv6 (since CC 15.05)
uci set ddns.newddns.domain="host.yourdomain.net"
uci set ddns.newddns.username="your_user_name"
uci set ddns.newddns.password="p@ssw0rd"
uci set ddns.newddns.interface="wan"	# network interface that should start this configuration/section
uci set ddns.newddns.enabled="1"
uci commit ddns				# don't forget this, otherwise data not written to configuration file
/etc/init.d/ddns restart

SSL support

You need to add the following entries to the desired section in /etc/config/ddns file using ca-certificates package:

# /etc/config/ddns
config 'service' 'myddns'
	option 'use_https'	'1'
	option 'cacert'		'/etc/ssl/certs'

using single file (ie. as descriped above):

# /etc/config/ddns
config 'service' 'myddns'
	option 'use_https'	'1'
	option 'cacert'		'/etc/ssl/certs/ca-certificates.crt'
#	option 'cacert'		'/full/path/to/file.crt'

Above options can also be set via LuCI. The options are only shown if wget or curl package is installed!

Custom service

Following changes need to be done if you use a DDNS provider currently not listed or to update multiple hosts within one configuration/section. Edit /etc/config/ddns.

# /etc/config/ddns
config 'service' 'myddns'
#	option 'service_name'	'example.org'		# comment out "#" or delete
	option 'update_url'	'http://your.update.url...[USERNAME]...[PASSWORD]...[DOMAIN]...[IP]'

or use UCI command line interface

uci delete ddns.myddns.service_name
uci set ddns.myddns.update_url="http://your.update.url...[USERNAME]...[PASSWORD]...[DOMAIN]...[IP]"
uci commit ddns		# don't forget this, otherwise data not written to configuration file
URL Syntax
  • No need to set https://, it is replaced automatically if SSL support is activated.
  • The entries [USERNAME] [PASSWORD] [DOMAIN] [IP] are replaced by ddns-scripts just before update.
  • [USERNAME] is replaced by content of option username from configuration file.
  • [PASSWORD] is replaced by content of option password from configuration file.
  • [DOMAIN] is replaced by content of option domain from configuration file.
  • [IP] is replaced by the current IP address of your OpenWrt system.
  • Carefully set option domain in your configuration, also used to detect if the update was successfully done.
  • This entry is the DNS name your OpenWrt system will be reachable from the internet.
  • Have a look at Provider specifics for samples.

:!: If you found a DDNS provider not listed or with additional IPv6 support or with changed update URL please open an issue at Github-OpenWrt-Packages so it can be included with the next release.

Here a list (without preferences) of URLs to detect your current public ip used by your system:

Dual-Stack IPv4-only IPv6-only Server Location
http://checkip.dns.he.net/ - - US
http://checkip.freedyn.org/ - - DE
http://bot.whatismyipaddress.com/ - - US
http://whatismyip.org/ - - US
http://myexternalip.com/raw - - DE
http://wtfismyip.com/text http://ipv4.wtfismyip.com/text http://ipv6.wtfismyip.com/text US
http://domains.google.com/checkip - - part of Google
http://icanhazip.com/ http://ipv4.icanhazip.com/ http://ipv6.icanhazip.com/ US
http://checkip.feste-ip.net/ http://v4.checkip.feste-ip.net/ http://v6.checkip.feste-ip.net/ DE
http://ident.me/ http://ipv4.ident.me/ http://ipv6.ident.me/ UK
http://ddnss.de/meineip.php http://ip4.ddnss.de/meineip.php http://ip6.ddnss.de/meineip.php DE
http://checkip.spdyn.de/ http://checkip4.spdyn.de/ http://checkip6.spdyn.de/ DE
http://ifcfg.me/ip http://4.ifcfg.me/ip http://6.ifcfg.me/ip FR
http://nsupdate.info/myip http://ipv4.nsupdate.info/myip http://ipv6.nsupdate.info/myip DE
http://checkip.zerigo.com http://checkip4.zerigo.com/ http://checkip6.zerigo.com/ US
- http://checkip.dyndns.com/ 1) http://checkipv6.dyndns.com/ 1) US + UK
- http://checkip.dyndns.com:8245/ http://checkipv6.dyndns.com:8245/ US + UK
- http://checkip.dyn.com/ 1) 2) http://checkipv6.dyn.com/ 1) 2) US + UK
- http://ipv4.myip.dk/api/info/IPv4Address http://ipv6.myip.dk/api/info/IPv6Address US
- http://ipv4.ipogre.com/linux.php http://ipv6.ipogre.com/linux.php US
- http://v4.ipv6-test.com/api/myip.php http://v6.ipv6-test.com/api/myip.php FR
- http://ipecho.net/plain - NL
- http://ipinfo.io/ip - part of Amazon AWS
- http://ifconfig.me/ip - JP
- http://checkip.amazonaws.com - part of Amazon AWS
- http://myip.dtdns.com - US
- http://ip.changeip.com - US
- http://freedns.afraid.org/dynamic/check.php - ?
- http://freedns.afraid.org:8080/dynamic/check.php - ?

- Users reported timeout problems, use links in the line below (...:8245). - Alias of *.dyndns.com.

If you don't like to use one of the above you can write your own. Here is a sample script in PHP which can easily be deployed on any web hosting:

<!DOCTYPE html>

If your WAN interface has the IP you want to propagate, this approach has the advantage of not depending on external services or even a working DNS resolution.

Create the script:

cat << "EOF" > /etc/ddns/getwanip
. /lib/functions/network.sh
for IPV in 4 6
eval network_find_wan${IPV%4} NET_IF
eval network_get_ipaddr${IPV%4} NET_ADDR "${NET_IF}"
echo "${NET_ADDR}"
chmod +x /etc/ddns/getwanip

Use it in the DDNS configuration by issuing these UCI commands:

uci set ddns.NAMEOFYOURSERVICE.ip_source="script"                 #Change NAMEOFYOURSERVICE to yours
uci set ddns.NAMEOFYOURSERVICE.ip_script="/etc/ddns/getwanip"     #Change NAMEOFYOURSERVICE to yours

Or by editing these lines in /etc/config/ddns:

config service 'NAMEOFYOURSERVICE'                 #Change NAMEOFYOURSERVICE to yours
        option ip_source 'script'
        option ip_script '/etc/ddns/getwanip'

:!: Enable minimum one configuration/section and ddns service!

Normally no user actions are required because ddns-scripts starts when hotplug ifup event happens. This will happen automatically at system startup when the named interface comes up. Event ifup also happens when a dialup network comes up. ddns-scripts regularly check if there is a difference between your IP address at DNS and your interface. If different an update request is sent to DDNS provider.

  • Whenever you Save & Apply an Enabled configuration/section from LuCI the corresponding script is automatically restarted.
  • If you modify /etc/config/ddns configuration file from CLI, you need to restart ddns-scripts (see below) to apply changes.

To check if ddns-scripts are running you could check with LuCI → Status → Processes or via console running

pgrep -f -a dynamic

You should find something like ... /bin/sh /usr/lib/ddns/dynamic_dns_updater.sh myddns 0 for every configuration/section you configured and enabled, where myddns shows your configuration/section name.

Inside LuCI also exists a section Dynamic DNS → Status → Overview page showing the current status of your DDNS configurations.

Web interface instructions

To check running ddns-scripts processes from the menu go to Status → Processes. Look for something like /bin/sh /usr/lib/ddns/dynamic_dns_updater.sh -v 0 -S myddns -- start.

To stop a desired process press the Terminate or Kill button. The process should remove from the list.

You can enable/disable and start/stop ddns-scripts from System → Startup menu. Look for service ddns and press the button for the desired action.

You can additionally enable/disable and start/stop individual configuration/section from Overview → Services → Dynamic DNS.

Command-line instructions

From console command line you could create an ifup hotplug event for the desired network interface. This will start all enabled ddns configurations/sections monitoring this interface. :!: Keep in mind that also other service processes (i.e. firewall) might be (re-)started via ifup hotplug event! For INTERFACE, type the specified ddns-scripts interface name (the interface name from /etc/config/network, usually 'wan')

ACTION=ifup INTERFACE=wan /sbin/hotplug-call iface

To start only one ddns-scripts configuration/section (here myddns):

/usr/lib/ddns/dynamic_dns_updater.sh -S myddns start &

Note that verbosity can also be increased, which is very useful for debugging when creating your own ddns client scripts. e.g.

/usr/lib/ddns/dynamic_dns_updater.sh -S myddns -v1 start

see /usr/lib/ddns/dynamic_dns_updater.sh -h for more details

To stop one configuration/section you need to find it's PID and kill it manually e.g.

pgrep -f -a dynamic
kill <pid of matching dynamic_dns_updater.sh process>

To start all ddns-scripts configurations configured for a given interface e.g. wan

/usr/lib/ddns/dynamic_dns_updater.sh -n wan start

All configured ddns services in /etc/config/ddns can of can be stopped,started,restarted and reloaded accordingly with the service command e.g.

service ddns restart

Using scheduler

Each configuration/section of ddns-scripts can be configured to run once including retry on error so it is guaranteed that the update is sent to the provider.

To configure your configuration/section to run once you need to set option force_interval 0. Setting of option force_unit is ignored. Inside LuCI set Force Interval in Timer Settings tab of your desired configuration or edit /etc/config/ddns on console.

# /etc/config/ddns
config 'service' 'myddns'
	option 'force_interval'	'0'

If you set ddns service to enable then all configurations/sections are started during interface ifup. The configuration/section configured to run once will stop after successful update. To guarantee that your configurations only run once not looking for an interface event you need to disable ddns service. To start your configuration via build in crond use the following entry as command inside crontab configuration (replace myddns with the name of your configuration/section):

/usr/lib/ddns/dynamic_dns_updater.sh myddns 0 &


The option use_syslog (also in LuCI) allows to define the level of events logged to syslog:

Value Reporting
0 disable
1 info, notice, warning, errors
2 notice, warning, errors
3 warning, errors
4 errors
:!: Critical errors forcing ddns-scripts to break (stop) are always logged to syslog


ddns-scripts have built-in logfile support. Logfiles are automatically truncated to a settable number of lines (default 250 lines).

Inside LuCI you could enable logfile in Advanced Settings tab of desired configuration/section. From console you need to edit the config file:

# /etc/config/ddns
config 'service' 'myddns'
	option 'use_logfile'	'1'

In case your device has enough built in memory or if you are using Extroot, you might want to store the ddns logs persistently. To achieve this, you need to change the log file location by adding the following line in the global section of /etc/config/ddns:

# /etc/config/ddns
config 'ddns' 'global'
	option 'ddns_logdir'	'<your_custom_log_dir>'

This option must be defined in the global section of the /etc/config/ddns file. If the option is defined at config service level, it will be ignored by the /usr/lib/ddns/dynamic_dns_functions.sh script and the log location will be defaulted to /var/log/ddns.

To view logfile content from LuCI select the Log File Viewer tab of desired configuration/section and press the Read / Reread log file button. From console you should change to the ddns log directory, default /var/log/ddns. You will find a logfile for every configuration/section.

cat /var/log/ddns/myddns_ipv4.log
cat /var/log/ddns/myddns_ipv6.log

To debug what's going on, you can run ddns-scripts in verbose mode. Following verbose level are defined:

Level Description
0 Non verbose, no output
1 Output to console (default)
2 Output to console and logfile, run once WITHOUT retry on error
3 Output to console and logfile, run once WITHOUT retry on error, sending NO update to DDNS service

Before starting debugging stop all running ddns-scripts processes:

/etc/init.d/ddns stop
/etc/init.d/ddns disable

validate that no ddns-scripts processes running:

pgrep -f -a dynamic

Now you can start one configuration/section for debugging. To stop/break running script press [CTRL]+C. Replace myddns with your desired configuration/section name and level with the desired verbose level.

/usr/lib/ddns/dynamic_dns_updater.sh myddns level

You will get full description of errors and the output of programs like wget, nslookup etc. used by ddns-scripts.

Network and name resolution problems

Check your communication settings with the following commands:

nslookup google-public-dns-a.google.com
ping -c 5 google-public-dns-a.google.com
ping -c 5 -4 google-public-dns-a.google.com	# (-4) force IPv4 communication
ping -c 5 -6 google-public-dns-a.google.com	# (-6) force IPv6 communication if installed
wget -O- http://checkip.dyndns.com		# for IPv4
wget -d -O- http://checkipv6.dyndns.com		# for IPv6 needs wget package and IPv6 to be installed
curl -v http://checkipv6.dyndns.com		# for IPv6 needs curl package and IPv6 to be installed

HTTPS/SSL problems

Check if your DDNS provider ONLY supports secure requests and enable HTTPS option use_https in your configuration. Packages wget or curl not installed to support secure communication. wget/curl could not access/validate SSL certificates. Check certificate installation and run wget or curl in verbose/debug mode:

ls -a -R -l /etc/ssl
wget -d -O /tmp/wget.out https://www.google.com --ca-certificate=/etc/ssl/certs/ca-certificates.crt	# single certificate file
wget -d -O /tmp/wget.out https://www.google.com --ca-directory=/etc/ssl/certs		# certificate directory
wget -d -O /tmp/wget.out https://www.google.com --no-check-certificate			# ignore certificate !!! INSECURE !!!
curl -v -o /tmp/curl.out https://www.google.com --cacert /etc/ssl/certs/ca-certificates.crt	# single certificate file
curl -v -o /tmp/curl.out https://www.google.com --capath /etc/ssl/certs		# certificate directory
curl -v -o /tmp/curl.out https://www.google.com --insecure			# ignore certificate !!! INSECURE !!!

Remember to read how to configure a custom service. At provider specific settings, only parameters that needs to be changed are described. The relevant parameters to use together with a custom settings are:

UCI option LuCI description Explanatory note
service_name DDNS Service provider Inside LuCI set to --custom-- or delete from /etc/config/ddns if you need to use custom update URL
update_url Custom update-URL Copy from description below, if necessary
domain Hostname/Domain The already registered name at your DDNS provider.
:!: Must be your public FQDN because used by nslookup command to check if the send IP update was recognized by your provider and published around World Wide DNS
username Username Normally your username but possibly used with different settings
password Password Normally your password but possibly used with different settings

If you find a FIXME at a provider description below, please support the ddns-scripts maintainer to test and update this page. Please post a support request if something is not working as described or needs to be updated.

If you find problem “Failed writing HTTP request: Bad file descriptor” in some server / wget version (see: https://bugzilla.redhat.com/show_bug.cgi?id=912358), it is worth to try changing:

# /etc/config/ddns
- http://[USERNAME]:[PASSWORD]path_to_your_provider_and_other_things
+ --user=[USERNAME] --password:[PASSWORD] http://path_to_your_provider_and_other_things
# /usr/lib/ddns/dynamic_dns_updater.sh
- update_output=$( $retrieve_prog "$final_url" )
+ update_output=$( $retrieve_prog $final_url )

Last updated: 2021-10-23

If you have your own domain and are running bind as your primary DNS server, you can use the ddns-scripts-nsupdate package to update bind. There are two parts:

  1. Configure bind to accept DNS updates using TSIG.
  2. Configure OpenWRT to send DNS updates to bind when the IP changes.

In the below example, we will use the following parameters:

  • Domain name: example.org
  • DNS Server: ns.example.org
  • Router hostname: openwrt.example.org

Configure Bind

The first step is to set up bind to allow updates to the A (IPv4) and AAAA (IPv6) records for openwrt.example.org. To do this, log onto your DNS server and run /usr/sbin/ddns-confgen -s openwrt.example.org. This will generate the key and shared secret that will be used to update DNS. You should see output similar to the following:

$ /usr/sbin/ddns-confgen -s openwrt.example.org
# To activate this key, place the following in named.conf, and
# in a separate keyfile on the system or systems from which nsupdate
# will be run:
key "ddns-key.openwrt.example.org" {
        algorithm hmac-sha256;
        secret "B1m6Xb1ngrEeNFSExr8homgfzeN8kWIBkJpnoAHF5D8=";

# Then, in the "zone" statement for the zone containing the
# name "openwrt.example.org", place an "update-policy" statement
# like this one, adjusted as needed for your preferred permissions:
update-policy {
          grant ddns-key.openwrt.example.org name openwrt.example.org ANY;

# After the keyfile has been placed, the following command will
# execute nsupdate using this key:
nsupdate -k <keyfile>

The two important things to note for the second part of the setup, on openwrt, are:

  1. Key Name: ddns-key.openwrt.example.org
  2. Shared Secret (Base64 encoded): B1m6Xb1ngrEeNFSExr8homgfzeN8kWIBkJpnoAHF5D8= (yours will differ as it is randomly generated)

You then need to do as the comments in the output say and put both the key block and the update-policy block in the proper places within your bind configuration file (generally /etc/bind/named.conf.local or /etc/bind/named.conf) and reload/restart bind.

To test that bind is now properly configured you can run a test as follows:

$ nsupdate
server ns.example.org
key hmac-sha256:ddns-key.openwrt.example.org B1m6Xb1ngrEeNFSExr8homgfzeN8kWIBkJpnoAHF5D8=
update del openwrt.example.org A
update add openwrt.example.org 600 A
$ dig @ns.example.org openwrt.example.org A

You should see no errors, and the IPv4 address returned for openwrt.example.org. If so, you are ready to move on to the next step which is to configure DDNS on OpenWRT to send updates to bind.

See also: BIND 9 Administrator Reference Manual



To configure DDNS using the LuCI WUI, you will need to install the luci-app-ddns package. Once you log into LuCI, go to ServicesDynamic DNS. In the bottom section, Services, you will see two example configurations: one for IPv4 and one for IPv6. Click the Edit button, and enter the following information (based on the example config from above; but, use your own values):

  • Lookup Hostname: openwrt.example.org
  • DDNS Service provider: bind-nsupdate
  • Domain: openwrt.example.org
  • Username: hmac-sha256:ddns-key.openwrt.example.org
  • Password: B1m6Xb1ngrEeNFSExr8homgfzeN8kWIBkJpnoAHF5D8=
  • DNS-Server (on the Advanced Settings tab): ns.example.org

Then click Save, followed by Save & Apply.

Congratulations, if you did everything right, openwrt should now update DNS with the current IP Address for your router.


If you are not using LuCI and want to configure manually, you will need to edit /etc/config/ddns as follows (using the example config from above):

config ddns 'global'
        option ddns_dateformat '%F %R'
        option ddns_loglines '250'
        option ddns_rundir '/var/run/ddns'
        option ddns_logdir '/var/log/ddns'

config service 'myddns_ipv4'
        option enabled '1'
        option lookup_host 'openwrt.example.org'
        option use_ipv6 '0'
        option service_name 'bind-nsupdate'
        option domain 'openwrt.example.org'
        option ip_source 'network'
        option ip_network 'wan'
        option interface 'wan'
        option dns_server 'ns.example.org'
        option use_syslog '2'
        option check_unit 'minutes'
        option force_unit 'minutes'
        option retry_unit 'seconds'
        option username 'hmac-sha256:ddns-key.openwrt.example.org'
        option password 'B1m6Xb1ngrEeNFSExr8homgfzeN8kWIBkJpnoAHF5D8='

You can then add another stanza for IPv6, by turning on use_ipv6 and changing ip_network and interface to wan6.

Last updated: 2022-09-11


As of OpenWrt version 22.03.0, ddns-scripts supports the use of API tokens. API Tokens provide a new way to authenticate with the Cloudflare API.

Create Custom Token by following the Creating API tokens guide. make sure to add “Zone DNS Edit” Permission to your custom token. You can also “include Specific zone” under Zone Resources. These allow for scoped and permissioned access to resources and use the RFC compliant Authorization Bearer Token Header. For more information on Token vs Key see the Cloudflare v4 API documentation.

service_name	cloudflare.com-v4
domain		[Your domain, here: example.com]
username	Bearer
password	[Your API token]

To use subdomains (CNAME or A records), use the format below when filling your credentials:

domain		{subdomain}@[zone]


  • If the hostname is “sample.example.com”, the “domain” field would be “sample@example.com”
  • If the hostname is “dev1.sample.example.com”, the “domain” field would be “dev1.sample@example.com”
  • If using Cloudflare's “Subdomain Support”, your zone may already be “foo.example.com”, so if the DDNS hostname is “bar.foo.example.com” the domain field would be “bar@foo.example.com”

Last updated: 2021-05-16

DNS-O-Matic provides you a free, easy and secure way to announce your dynamic IP changes to multiple services with a single update. Using DNS-O-Matic allows you to pick and choose what Dynamic DNS services you want to notify, all from one easy to use interface. From dns-o-matic homepage -- Documentation

DNS-O-Matic authentication is integrated with OpenDNS, so your DNS-O-Matic credentials are the same as your OpenDNS ones. You need to change your OpenDNS password to one that doesn't contain HTML special characters On dnsomatic username and password

If you would like to make sure your SSL connection is verified, then install the CA certificates and set the path to /etc/ssl/certs (Path to CA-Certificate in the LuCI or option 'cacert' '/etc/ssl/certs' when configuring by command line.)

To update all services registered with DNS-O-Matic in one configuration/section use the following settings in /etc/config/ddns:

# /etc/config/ddns
config service 'DNSoMATIC'
        option lookup_host   'anotherddns.com'             # It must be a FQDN that is active on dns-o-matic dashboard to be refreshed by it. if using openDNS, use myip.opendns.com
        option interface     'wan'                         # Set it to the network interface to be monitored on changes
        option ip_source     'web'
        option ip_url        'http://checkip.amazonaws.com/' # does not appear to be used, at least by the LUCI interface
        option use_https     '1'
        option cacert         '/etc/ssl/certs'
        option service_name  'dnsomatic.com'
        option domain        'all.dnsomatic.com'            # It will instruct dns-o-matic to update all services set on its dashboard
        option username      'OPENDNSusername'              # dns-o-matic uses OpenDNS login credentials
        option password      'OPENDNSpassword'              # It must not contain html reserved characters
        option enabled       '1'

Alternatively, you can issue uci commands:

uci add ddns dnsomatic
uci set ddns.dnsomatic.lookup_host='DDNSchangedBYdnsomatic.com'  ##Change it to yours
uci set ddns.dnsomatic.interface='wan'                           ##Change it to yours
uci set ddns.dnsomatic.ip_source='web'
uci set ddns.dnsomatic.ip_url='http://checkip.amazonaws.com/'    ## not mandatory
uci set ddns.dnsomatic.use_https='1'
uci set ddns.dnsomatic.service_name='dnsomatic.com'
uci set ddns.dnsomatic.domain='all.dnsomatic.com'
uci set ddns.dnsomatic.username='OPENDNSusername'                ##Change it to yours
uci set ddns.dnsomatic.password='OPENDNSpassword'                ##Change it to yours
uci set ddns.dnsomatic.enabled='1'
uci commit
/etc/init.d/ddns reload

Last updated: 2024-01-02

For detailed instructions, see DuckDNS DDNS Client.

Last updated: 2015-07-15

Homepage -- FAQ

Option 1: FIXME

service_name	afraid.org-v2-token
domain		[Your FQDN]
username	[NOT used. Set to a character of your choice, because LuCI does not accept empty field]
password	[Your authorisation token, NOT your account password]

To find your authorisation token, go to http://freedns.afraid.org/dynamic/, login, click “Direct URL”. On the location bar of your browser, copy the authorisation token, which is the part after http://freedns.afraid.org/dynamic/update.php? URL and paste it in the password field. The URL to update IP result in error 404, need to change source code.

Option 2: FIXME (Taken from here)

service_name	delete / --custom--
update_url	[Your direct URL updater from your freedns.afraid.org account]
domain		[Your FQDN]
username	[NOT used. Set to a character of your choice, because LuCI does not accept empty field]
password	[NOT used because already part of direct URL. Set to a character of your choice, because LuCI does not accept empty field]

Option 3

service_name	afraid.org-v2-basic or afraid.org-basicauth
domain		[Your FQDN]
username	[your username of afraid.org]
password	[Your account password]

Option 4 Prefer

service_name	afraid.org-keyauth
domain		[Your FQDN]
username	[NOT used. Set to a character of your choice, because LuCI does not accept empty field]
password	[Your authorisation token, NOT your account password]

Last updated: 2016-04-20

Google Domains allows for dynamic names to be set up in the section called Synthetic Records. To access it, log in to https://domains.google.com and go to Configure DNS for the domain in question, then scroll down to Synthetic Records and add a new one. It will issue a specific username and password for this hostname. Google requires HTTPS for updates, so be sure to also install package wget or curl in order to allow this. Use the following settings:

service_name	--custom--
update_url	http://[USERNAME]:[PASSWORD]@domains.google.com/nic/update?hostname=[DOMAIN]&myip=[IP]
domain		[Your defined hostname]
username	[assigned username for hostname]
password	[assigned password for hostname]
http_secure	Enabled
ca_path		Set to "IGNORE" or download certs and provide path

Last updated: 2015-07-20

Homepage (Danish only)

Taken from OpenWrt forum

GratisDNS.dk is only supported by ddns-scripts using custom service settings and requires to install and configure SSL support.

service_name	delete / --custom--
update_url	https://ssl.gratisdns.dk/ddns.phtml?u=[USERNAME]&p=[PASSWORD]&d=Mydomain&h=[DOMAIN]&i=[IP]
		!!! replace "Mydomain" in this url with domain part of your FQDN.
		Sample: your FQDN: host.example.com -> "Mydomain" set to example.com
		Sample: https://ssl.gratisdns.dk/ddns.phtml?u=[USERNAME]&p=[PASSWORD]&d=example.com&h=[DOMAIN]&i=[IP]
domain		[Your FQDN]
username	[Your username]
password	[Your password]

Last updated: 2023-10-05

Homepage Details about their free dynamic DNS service

Background (who they are): Hurricane Electric (referred to as HE.net below) is one of the original supporters/pushers of the IPv6 internet (and also provide a free tunnel broker if you want IPv6 connectivity but your ISP is in the stone-ages), and HE.net also run major internet backbones.

HE.net is a great option if you already have a domain (or sub-domain) you can point at their 5 nameservers (ns[1-5]/dot/he.net). This will need to be done before you can setup the zone (your domain or subdomain) up.

You can then opt for one of an A (for IPv4) record or an AAAA (for IPv6) record under that sub-domain, to be updated dynamically by the ddns-service. Security of this ability is provided via a 16-character api-access-key they can generate for you (or you can specify your own).

If you don't have an HE.net account, you will need to open a free account

If you don't already have a domain (or subdomain) pointing to HE.net: * Go to the DNS management page. * Click on Add a new domain (on the left side-bar) * Enter your domain or subdomain (that should already have pointed to their 5 nameservers), and click the green Add domain! button (the page may take a few seconds to respond, do not click multiple times) * Next to the new domain, click the 2nd icon (the one that looks like classic-windows app + pencil icon) to Edit the records for that dns-zone. * Click the New A button (for IPv4) or New AAAA button (for IPv6). * For Name, enter only the part part before the first period in the FQDN (the part that goes before the domain or subdomain you pointed at HE's nameserver). * MAKE SURE you click Enable entry for dynamic dns checkbox ON * Click Submit * Click the icon that looks like a small two-arrows in a circle (pointing to each other) in the DDNS column. * In the popup Dynamic DNS Record, here you can either generate a key (up to 16 characters) or specify your own. You will need this for the password in the example config below

(src - above steps tested and based on this blog).

*Note:* In order for a zone to be accepted for addition to HE.net's DNS-manager, it must already be configured to point to ns1.he.net / ns2.he.net / ns3.he.net / ns4.he.net / ns5.he.net. Adding the domain or subdomain to HE.net will fail w/ an error otherwise. Note: I don't know if they check for all five nameservers, but may as well just add all 5 NS records to your domain (with the registrar you setup the domain) or if a sub-domain (at your existing host.

Lastly, if you want to (it's optional) protect the update-requests that the ddns-service does, with TLS, you can see the above section on SSL. The following settings have been tested/worked:

In the below example config, the (sub-)domain pointing to HE.net nameservers is “zone.domain.tld”, and the A record is “addr-a-record” (thus the full dynamic hostname will be addr-a-record.zone.domain.tld).

# /etc/config/ddns
config service 'dns_he_net'
        option service_name 'he.net'
        option enabled '1'
        option domain 'addr-a-record.your.domain.tld'       # this is the A or AAAA record you created and set up a DynDNS Key for 
        option lookup_host 'addr-a-record.your.domain.tld'  # same as above - script queries this to see if it's outdated and needs to be updated
        option use_ipv6 '0'                                 # whether to update your AAAA record (by default: A record)
        option username 'your.domain.tld'                   # this is not your HE.net username, but your zone (zone.domain.tld) delegated to HE.net nameservers
        option password 'XXXXXXXXXXXXXXXX'                  # this part is the generated Key for the DynDNS function 
        option ip_source 'network'
        option ip_network 'wan'
        option interface 'wan'
        option use_syslog '2'
        option check_unit 'minutes'
        option force_unit 'minutes'
        option retry_unit 'seconds'

More info about how this works underneath the covers: https://dns.he.net/docs.html

Note: There is another (older) doc here: doc here.

Last updated: 2015-07-20

Homepage -- Support

FIXME Looking on description at “Use Mythic Beasts Dynamic DNS with your OpenWRT router” and on the existing source code I found out that there must be issues updating Dynamic DNS. I have gone in contact with support of mythic-beasts.com. I will update as soon a solution is available.

Last updated: 2015-07-21

Homepage -- Knowledgebase

Note that with the namecheap protocol, the username option is translated to the host argument in the update request. Therefore, it should be the host-part on the DNS record, not the username that you use to log into the namecheap.com site. To update multiple hosts you might need to define separate configuration/section for each host. To get your password, log into the namecheap.com site, enter the management console for the domain, and click the Dynamic DNS menu option.

:!: Currently ddns-scripts only supports the case where your dynamic subdomain has the same IP address as for your unqualified domain. Otherwise you will send updates to namecheap.com every “option check_interval” 10 minutes (default) because your FQDN is not validated. Proposed solution here, which you can easily implement yourself. This may only be an issue for ddns-scripts 2.4.

Let assume you define two FQDN at your domain “example.com”: “www.example.com” and “ftp.example.com”. To update only your domain record “example.com”:

service_name	namecheap.com
domain		[Your domain, here: example.com]
username	@
password	[Your password]

To update for example only your “ftp.example.com” host:

service_name	namecheap.com
domain		[Your domain, here: example.com]
username	ftp
password	[Your password]

To update all to the same IP address:

NOTE: For namecheap updating multiple subdomains is NOT working nowadays, you have to make one request per subdomain, so configure one section per subdomain. https://www.namecheap.com/support/knowledgebase/article.aspx/29/11/how-do-i-use-a-browser-to-dynamically-update-the-hosts-ip#comment-936527059:

service_name	namecheap.com
domain		[Your domain, here: example.com]
username	@ -a www -a ftp
		!!! @ stands for your domain, www for www.example.com, ftp for ftp.example.com
password	[Your password]

Last updated: 2015-07-21

Homepage -- SupportCenter

:!: Install the ddns-scripts_no-ip_com package.

The default is to use your username and password as normal inside ddns-scripts together with service_name no-ip.com or noip.com.

If you want to update multiple hosts inside one configuration/section you need the following settings:

service_name	delete / --custom--
update_url	http://[USERNAME]:[PASSWORD]@dynupdate.no-ip.com/nic/update?myip=[IP]&hostname=

		!!! After the 'hostname=' fill in a comma separated list of hosts to update.
		Sample: host1.example.com,host2.example.com,host3.example.com without any spaces in between.
		Sample: http://[USERNAME]:[PASSWORD]@dynupdate.no-ip.com/nic/update?myip=[IP]&hostname=host1.example.com,host2.example.com,host3.example.com

domain		[Only ONE of your defined hostnames, i.e. host1.example.com]
username	[Your username]
password	[Your password]

Last updated: 2016-08-02

Homepage -- Wiki/FAQ (German only)

The web-pages of spdns.de are now reachable at spdyn.de. Currently updates send to update.spdns.de pages are still handled but produce warnings in DDNS update log at the provder. Created accounts and domains at spdns.de are still working without any problems.

The default is to use your username and password as normal inside ddns-scripts together with service_name spdyn.de. If you want to use Update-Token, keep in mind that this token can only update the host it is generated for. Use this settings:

service_name	spdyn.de
domain		[Your defined hostname at spdyn.de]
username	[Your defined hostname at spdyn.de]
password	[The token generated for this hostname]

If you want to update multiple hosts inside one configuration/section you need the following settings (Update-Token doesn't work):

service_name	delete / --custom--
update_url	http://[USERNAME]:[PASSWORD]@update.spdyn.de/nic/update?myip=[IP]&hostname=

		!!! After the 'hostname=' fill in a comma separated list of hosts (max. 20) to update.
		Sample: host1.spdyn.de,host2.spdyn.de,host3.spdyn.de without any spaces in between.
		Sample: http://[USERNAME]:[PASSWORD]@update.spdyn.de/nic/update?myip=[IP]&hostname=host1.spdyn.de,host2.spdyn.de,host3.spdyn.de

domain		[Only ONE of your defined hostnames i.e. host3.spdyn.de]
username	[Your username at spdyn.de]
password	[Your password at spdyn.de]

Hurricane Electric provides a free IPv6inIPv4 tunnel through Tunnel Broker that demands a permanent IP or a real-time updated one. From its homepage: “Our free tunnel broker service enables you to reach the IPv6 Internet by tunneling over existing IPv4 connections from your IPv6 enabled host or router to one of our IPv6 routers. To use this service you need to have an IPv6 capable host (IPv6 support is available for most platforms) or router which also has IPv4 (existing Internet) connectivity.”

Apply the following patch to include that service on OpenWRT DDNS

grep -q -e "ipv4\.tunnelbroker\.net" /etc/ddns/services \
&& echo -e "\"tunnelbroker.net\"\t\"http://[USERNAME]:[PASSWORD]@ipv4.tunnelbroker.net/nic/update?hostname=[DOMAIN]&myip=[IP]\"\t\"good|nochg\"" >> /etc/ddns/services

Now you can configure your tunnelbroker ddns:

# /etc/config/ddns
config service 'HE6in4'
        option service_name  'tunnelbroker.net'
        option lookup_host   'hostToCheck.com'             #Change it to yours. It should be a hostname updated by a DDNS with the current IP.
        option ip_source     'web'
        option ip_url        'http://checkip.amazonaws.com/'
        option interface     'wan'                         #Change it to yours
        option username      'tunnelbrokerUSERname'        #Change it to yours. It's the same tunnelbroker login.
        option password      'tunnelbrokerDDNSpassword'    #Change it to yours. It's not the same tunnelbroker login.
        option domain        'tunnelbrokerDDNSnumber'      #Change it to yours. It's only numbers.
        option enabled       '1'

Instead of using a web service, that has the risk of being eventually offline, to detect the public IP, you can detect the WAN public IP by this script.

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
  • Last modified: 2024/05/09 21:45
  • by maurerle