Knowledge baseDomains & DNS
Dynamic DNS
Keep a name pointed at a changing IP: from a mesh node with no software, or from a router or ddclient over dyndns2.
On this page
- How dynamic DNS works
- Before you start
- Choose a source
- DDNS from a mesh network node
- DDNS with a token
- Linux and Proxmox: ddclient
- Without ddclient: one cron line
- Routers
- IPv6 (AAAA records)
- Which address does mesh-net see?
- The update request and its answers
- If it doesn't work
- DDNS for your own domain
- Change the token or turn DDNS off
How dynamic DNS works
A home internet connection usually gets a new public IP from time to time. Dynamic DNS (DDNS) keeps an A or AAAA
record pointed at the current address, so myhome.mesh-net.space always leads home. mesh-net offers two
sources of the address:
- A mesh network node — no software at all: a device of your private network already tells the network its public IP, and mesh-net updates the record itself.
- A token — your router, NAS or server reports its IP over the standard dyndns2
protocol (the one routers and
ddclientspeak).
DDNS works for names in our zones and for A/AAAA records of your own domain.
Before you start
DDNS fills in A and AAAA records only, so the name needs one first. For a name in our zones, add it on the name's page — an empty value is fine there, the source fills it in (see Names and DNS records). Then open the name (click it in the list on Domains) and scroll to Dynamic DNS (DDNS): every A and AAAA record gets its own card. A record of your own domain needs an address from the start — any will do, DDNS replaces it.
Choose a source
A card without a source shows disabled and offers two ways:
| Mesh network node | Token | |
|---|---|---|
| What runs on your side | Nothing extra: the node is already in your network | A router, ddclient or a cron line |
| Needs | A private network (Paid plan) with that device | Any plan |
| Card status | source: mesh node | source: token |
A record has one source at a time. To switch, first remove the current one — Unbind node for a node, Turn off for a token; then the card offers both ways again.
DDNS from a mesh network node
- In the record's card, under Mesh network node — no software, pick the device in the list. Each entry shows the device's current public IP of the right family (IPv4 for A, IPv6 for AAAA).
- Press Bind. If the device is online, the record gets its address right away; if not, the address appears once the device connects.
From then on mesh-net checks the device about once a minute. A new address must hold for 2 minutes before the record moves, so a short flap doesn't throw the name around; the record follows a change within about 3 minutes. While the device is offline, the record keeps its last address. Unbind node stops the updates.
The record is public DNS: anyone who looks up the name sees the device's public IP.
The list only has devices of your own private networks that are running. With no such device the card says so — use a token instead.
DDNS with a token
Press Use a token. The card shows everything a client needs:
| Field | Value |
|---|---|
| Server / URL | https://mesh-net.space/nic/update (server mesh-net.space) |
| Hostname | the full name, e.g. myhome.mesh-net.space |
| Username | anything — it is ignored |
| Password (token) | the token, shk_… |
The token belongs to this one record; treat it like a password. Below the fields the card has ready-made setups for Linux and a cron line with your token already filled in — the same commands as below.
On an AAAA record's card, the ddclient config and the cron line work with IPv6 only: the address is found on the machine itself, because our server can't see it. See IPv6.
Linux and Proxmox: ddclient
On Debian, Ubuntu and a Proxmox host (it is Debian too):
- Install ddclient. If the installer asks for a protocol or a server, press Enter to skip: the next step writes
the config.
sudo DEBIAN_FRONTEND=noninteractive apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ddclient - Write
/etc/ddclient.confwith one command. Put your token and your name in place ofTOKENandmyhome.mesh-net.space(the card on the name's page has them filled in):
The public IP is detected by our own servicesudo tee /etc/ddclient.conf >/dev/null <<'EOF' daemon=300 ssl=yes usev4=webv4 webv4=https://mesh-net.space/nic/ip protocol=dyndns2 server=mesh-net.space login=token password='TOKEN' myhome.mesh-net.space EOF sudo chmod 600 /etc/ddclient.confhttps://mesh-net.space/nic/ip, so no third-party checkip is needed. - Run a one-off check — it should answer
goodornochgwith your IP:sudo ddclient -daemon=0 -debug -verbose -force - Enable autostart; with
daemon=300it checks every 5 minutes:sudo systemctl enable --now ddclient && systemctl status ddclient --no-pager
Without ddclient: one cron line
The server takes the address from the request itself, so nothing has to detect it. On any always-on Linux machine
in the same network, open crontab -e and add:
*/5 * * * * curl -fsS "https://mesh-net.space/nic/update?hostname=myhome.mesh-net.space" -u token:TOKEN
Every 5 minutes the line reports the network's current public IP. The answer goes to cron's mail; add
>/dev/null if you don't need it.
Routers
A router is the best place for DDNS: it is always on and knows its public address. The parameters are the ones
from the card: server mesh-net.space, the full name, any username, the token as the password, protocol
dyndns2.
OpenWrt
- Install
luci-app-ddnsin System → Software; for HTTPS alsocurlandca-bundle. - Services → Dynamic DNS → add a service with the provider -- custom --.
- Custom update URL — the token goes in the URL itself, so it works whichever download program the router uses:
https://mesh-net.space/nic/update?hostname=[DOMAIN]&myip=[IP]&token=[PASSWORD] - Lookup hostname and Domain — the full name; Username —
token; Password — the token; turn on HTTPS.
MikroTik
RouterOS has no custom dyndns2 client, but a two-line script does the job. In the terminal (put your token in
place of TOKEN):
/system script add name=mesh-ddns source="/tool fetch url=\"https://mesh-net.space/nic/update\?token=TOKEN\" keep-result=no"
/system scheduler add name=mesh-ddns interval=5m on-event=mesh-ddns
The token goes in the URL (\? is how the RouterOS terminal takes a question mark). The token alone tells
which record to update, so the request needs no hostname. It leaves through the router's WAN, and the server records
that public address.
Keenetic
Use a dyndns2-compatible (custom) provider in the router's dynamic DNS settings, if your KeeneticOS version offers one, with the parameters above. If it doesn't, put the cron line on any always-on device in the LAN.
ASUS
Stock ASUS firmware can't use a custom dyndns2 server. Either run ddclient or the
cron line on another machine in the LAN, or install Asuswrt-Merlin: choose the custom DDNS
server and save this as /jffs/scripts/ddns-start (executable):
#!/bin/sh
curl -fsS "https://mesh-net.space/nic/update?hostname=myhome.mesh-net.space&myip=$1" -u token:TOKEN >/dev/null \
&& /sbin/ddns_custom_updated 1 || /sbin/ddns_custom_updated 0
IPv6 (AAAA records)
The card of an AAAA record gives its own setup. Two things differ from an A record:
- The address is found on the machine itself. Our server has no IPv6, so it can't see yours:
/nic/ipand an update withoutmyipget an IPv4 address. - Only IPv6 lines. The record follows the family of the address it receives: an IPv4 address turns an AAAA record into an A record, and back. With IPv4 lines next to the IPv6 ones, ddclient sends the IPv4 address first.
ddclient 3.10 or newer takes the address from the network interface that the machine's IPv6 internet route goes
through. The shell fills in the interface name when it writes the file — that's why this EOF has no
quotes:
sudo tee /etc/ddclient.conf >/dev/null <<EOF
daemon=300
ssl=yes
usev6=ifv6
ifv6=$(ip -6 route show default | grep -o 'dev [^ ]*' | head -n1 | cut -d' ' -f2)
protocol=dyndns2
server=mesh-net.space
login=token
password='TOKEN'
myhome.mesh-net.space
EOF
sudo chmod 600 /etc/ddclient.conf
An empty ifv6= in the file means the machine has no IPv6 route to the internet — there is no IPv6
address to publish. Without ddclient, the cron line passes the machine's global IPv6 address explicitly and sends
nothing while there is none:
*/5 * * * * ip6=$(ip -6 -o addr show scope global -temporary -deprecated | grep -o 'inet6 [23][0-9a-f:]*' | head -n1 | cut -d' ' -f2) && [ -n "$ip6" ] && curl -fsS "https://mesh-net.space/nic/update?hostname=myhome.mesh-net.space&myip=$ip6" -u token:TOKEN
Routers usually report only their IPv4 address — for an AAAA record, run ddclient or the cron line on the machine itself.
Which address does mesh-net see?
https://mesh-net.space/nic/ip answers with the public IP your request comes from, as plain text — the same
address the update takes when myip isn't given:
curl https://mesh-net.space/nic/ip
The update request and its answers
GET https://mesh-net.space/nic/update with these parameters in the query string. POST is accepted
too, but the parameters still go in the URL: a form body is ignored.
| Parameter | Meaning |
|---|---|
Basic auth password, or token= | The record's token (the username is ignored) |
hostname= | The full name; optional, but if given it must match the token's record |
myip= (or ip=) | The address to publish; the first one if there is a list. Without it — the address of the request |
| Answer | Meaning |
|---|---|
good 203.0.113.7 | The record now has this address |
nochg 203.0.113.7 | The address hasn't changed; nothing to do |
badauth | No token, or it is wrong — the token was changed or DDNS is off. HTTP 401 with
WWW-Authenticate: Basic realm="mesh-net DDNS", so clients that wait to be asked send the token |
nohost | hostname isn't the name of this token's record |
dnserr | myip isn't an IP address |
911 | Our DNS server didn't accept the change; the client will retry |
If it doesn't work
- Old ddclient (before 3.10) doesn't know
usev4/webv4: use the single lineuse=web, web=https://mesh-net.space/nic/ipinstead. It can't take an IPv6 address from an interface: for an AAAA record, use the cron line. - The public IP is right on the interface (the machine isn't behind NAT): use
usev4=ifv4, ifv4=eth0; look up the interface name withip -br a. - Behind CGNAT — the address mesh-net sees is in the 100.64–100.127 range: your connection has no public address of its own, and DDNS won't help. Ask your ISP for a public IP, or reach the machine through a mesh network instead.
- badauth after it used to work — someone pressed Change token: put the new token into the client.
- badauth although the token is right — the token didn't reach mesh-net. Clients that send the
username and password only when the server asks for them get that request with the
badauthanswer (HTTP 401 withWWW-Authenticate: Basic) and repeat the update with them; a client that still sends nothing can carry the token in the URL instead:https://mesh-net.space/nic/update?token=TOKEN. - An AAAA record became an A record — the client sent an IPv4 address (or none, and mesh-net took the address of the request). Set it up as in IPv6.
- Logs of ddclient:
journalctl -u ddclient -n 50 --no-pager. - The record changed but the name still resolves to the old address — that's caching; see How fast changes appear.
DDNS for your own domain
Once your own domain has its zone at mesh-net, its page has a
Dynamic DNS (DDNS) section with a card for every A and AAAA record of the zone. Press
Turn on DDNS: the record gets a token, and everything else is the same —
the same https://mesh-net.space/nic/update, ddclient, cron and router setups, with the record's full name as the
hostname. Binding to a mesh node is available for names in our zones only.
Change the token or turn DDNS off
- Change token issues a new token at once; the old one stops working (
badauth), so update the client right after. - Turn off removes the token. The record keeps its last address and no longer changes.