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-ddnsRecent 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:
| Field | Value |
|---|---|
| Lookup Hostname | home.yourname.uk.app |
| IP address version | IPv4 |
| DDNS Service provider | custom |
| Custom update‑URL | https://[USERNAME]:[PASSWORD]@ddns.uk.app/nic/update?hostname=[DOMAIN]&myip=[IP] |
| Domain | home.yourname.uk.app |
| Username | yourname.uk.app |
| Password | your DDNS token |
| Use HTTP Secure | ticked |
| 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 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 restartThe 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 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 restartGive 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 restart5. 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
- Does the name point home? Look up
home.yourname.uk.appwith 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. - 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.
- Is the certificate right? The SSL checker shows whether the certificate covers the exact name, who issued it and when it expires.
- 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.