Guide

OpenWrt: dynamic DNS with a custom provider, and port forwarding

OpenWrt is the most flexible router you are likely to own, and its ddns-scripts package can talk to any provider that updates through a URL. This guide sets it up for a uk.app name, then forwards ports and deals with the two OpenWrt defaults that trip people up.

Updated · Checked against OpenWrt 25.12 (apk) and 24.10 (opkg), ddns-scripts 2.8 · 4 min read

Packages
ddns-scripts, luci-app-ddns
LuCI menus
Services → Dynamic DNS; Network → Firewall
Update URL placeholders
[USERNAME] [PASSWORD] [DOMAIN] [IP]
Time
20 minutes

1. Install the packages

OpenWrt 25.12 switched to the apk package manager; 24.10 and older use opkg. Over SSH:

# OpenWrt 25.12 and later
apk update && apk add ddns-scripts luci-app-ddns

# OpenWrt 24.10 and earlier
opkg update && opkg install ddns-scripts luci-app-ddns

Recent images already include CA certificates and an HTTPS‑capable downloader, which ddns‑scripts needs because the uk.app update service only accepts HTTPS. If the log later says HTTPS isn’t supported, install curl as well and tick Use cURL in the Dynamic DNS global settings.

2. Add a custom DDNS service

First create a DDNS token for your name in the uk.app dashboard (My names → your name → Dynamic DNS). Then in LuCI, go to Services → Dynamic DNS and add a service, for example named ukapp, for IPv4:

FieldValue
Lookup Hostnamehome.yourname.uk.app
IP address versionIPv4
DDNS Service providercustom
Custom update‑URLhttps://[USERNAME]:[PASSWORD]@ddns.uk.app/nic/update?hostname=[DOMAIN]&myip=[IP]
Domainhome.yourname.uk.app
Usernameyourname.uk.app
Passwordyour DDNS token
Use HTTP Secureticked
Path to CA‑Certificate/etc/ssl/certs
IP address source (Advanced Settings)Network, wan
Check Interval / Force Interval (Timer Settings)10 minutes / 72 hours

Enable the service, save and apply, then press Reload on the overview page. Or do the same from the shell:

UCI
uci set ddns.ukapp=service
uci set ddns.ukapp.enabled='1'
uci set ddns.ukapp.lookup_host='home.yourname.uk.app'
uci set ddns.ukapp.domain='home.yourname.uk.app'
uci set ddns.ukapp.username='yourname.uk.app'
uci set ddns.ukapp.password='YOUR_DDNS_TOKEN'
uci set ddns.ukapp.update_url='https://[USERNAME]:[PASSWORD]@ddns.uk.app/nic/update?hostname=[DOMAIN]&myip=[IP]'
uci set ddns.ukapp.use_https='1'
uci set ddns.ukapp.cacert='/etc/ssl/certs'
uci set ddns.ukapp.interface='wan'
uci set ddns.ukapp.ip_source='network'
uci set ddns.ukapp.ip_network='wan'
uci set ddns.ukapp.check_interval='10'
uci set ddns.ukapp.check_unit='minutes'
uci commit ddns
/etc/init.d/ddns restart

The log (Services → Dynamic DNS → Log File Viewer, or /var/log/ddns/ukapp.log) should show the reply good <your IP> on the first run and nochg afterwards.

Behind another router?

If your OpenWrt router sits behind an ISP hub (double NAT), its wan address is private, and publishing it would break your name. Change IP address source to URL and set URL to detect to https://ip.uk.app/ip, which returns your public IPv4 address as plain text. Better still, remove the double NAT.

IPv6 (AAAA record)

Add a second service with IP address version IPv6, the same URL and credentials, and IP source Network wan6. Note that this publishes the router’s IPv6 address. For a server behind the router you usually want the server’s own IPv6 address instead, which is best updated from the server itself by passing its address in myip=.

3. Forward ports

In LuCI: Network → Firewall → Port Forwards → Add. Name it, set protocol TCP, source zone wan, external port 443, destination zone lan, internal IP address (your reverse proxy) and internal port 443. Save and apply. The UCI equivalent:

UCI
uci add firewall redirect
uci set firewall.@redirect[-1].name='https-proxy'
uci set firewall.@redirect[-1].target='DNAT'
uci set firewall.@redirect[-1].src='wan'
uci set firewall.@redirect[-1].src_dport='443'
uci set firewall.@redirect[-1].dest='lan'
uci set firewall.@redirect[-1].dest_ip='192.168.1.40'
uci set firewall.@redirect[-1].dest_port='443'
uci set firewall.@redirect[-1].proto='tcp'
uci commit firewall && service firewall restart

Give the target a static lease first (Network → DHCP and DNS → Static Leases), so its address doesn’t change. OpenWrt applies NAT loopback (“reflection”) to port forwards by default, so the public name also works from inside your network.

Allowing IPv6 in

IPv6 has no NAT, so there is nothing to forward: you allow the traffic instead with a rule under Network → Firewall → Traffic Rules: protocol TCP, source zone wan, destination zone lan, destination address the server’s IPv6 address, port 443, action accept, address family IPv6.

4. The DNS rebind exception

OpenWrt’s DNS server (dnsmasq) enables rebind protection by default: it discards public DNS answers that point at private addresses. That breaks two useful patterns from other guides – a pve.yourname.uk.app name that points at a LAN address (Proxmox, Pi‑hole) and Plex’s plex.direct addresses (Plex).

Add exceptions under Network → DHCP and DNS → Filter (the list of domains allowed to return private addresses), or from the shell:

uci add_list dhcp.@dnsmasq[0].rebind_domain='yourname.uk.app'
uci add_list dhcp.@dnsmasq[0].rebind_domain='plex.direct'
uci commit dhcp && service dnsmasq restart

5. Or run WireGuard on the router itself

OpenWrt supports WireGuard natively (luci-proto-wireguard). Running the VPN on the router saves a port forward and a separate machine: you create a WireGuard interface, add it to the lan firewall zone or its own zone, and allow UDP 51820 in from wan with a traffic rule. The client side is the same as in the WireGuard guide, with Endpoint = home.yourname.uk.app:51820 kept current by the DDNS service above.

Check it

  1. Does the name point home? Look up home.yourname.uk.app with the DNS lookup and compare the A record with the address on ip.uk.app. After a change, the propagation checker shows which resolvers still have the old one.
  2. Is the port open from the internet? Run the open port checker against port 443. “Open” means your router forwards it and something answers. “Closed” or “timed out” means the forward, the device’s own firewall or CGNAT is in the way.
  3. Is the certificate right? The SSL checker shows whether the certificate covers the exact name, who issued it and when it expires.
  4. Test from outside for real. Turn Wi‑Fi off on your phone and open the address over mobile data. Testing from inside your own network can give misleading results.

A name for your next idea

Give your website, home server or next project a memorable address: yourname.uk.app. Choose your name and check availability before registering.

Find your name

Questions people ask

Why not use the built-in “dyndns.org” provider entry with a different server?

Provider entries hard‑code the provider’s update address. The custom URL is the supported way to use any other dyndns2‑compatible service.

The log says “HTTPS not supported”. What now?

Your downloader lacks TLS support. Install curl (apk add curl, or opkg install curl) and tick Use cURL in the global settings, then restart the ddns service.

How often does it update?

It checks the WAN address every Check Interval and only contacts the provider when the address has changed, or when the Force Interval passes. uk.app sets a 60‑second TTL on dynamic records, so changes spread quickly.

Sources and further reading

We check each guide against the vendor’s own documentation and support forums. If something has changed on your firmware, tell us.

Partners