I rebooted my home MikroTik router, and both of my site-to-site WireGuard tunnels went quiet. Both remote sites (two small family-run locations I look after) dial into my home router, and neither would reconnect. This post covers how I tracked it down, why MikroTik’s built-in Cloud DDNS let me down, and how I replaced it with a Cloudflare DDNS updater running in Docker, plus a small RouterOS script so the tunnels heal themselves next time.
The setup
- Home router: MikroTik on RouterOS 7.20, PPPoE WAN with a dynamic public IP.
- Two remote sites, each with a MikroTik running a WireGuard peer that points back to my home router.
- The remote peers found my home router using MikroTik’s free
*.sn.mynetname.netCloud DDNS hostname.
The home router only listens. The remote sites always initiate the connection, so if they can’t find my current IP, nothing works.
Step 1: Both sites down means look at your own end
When two independent sites drop at the same moment, the common factor is the home router. The most likely cause after a reboot is a WAN IP change: PPPoE reconnects, the ISP hands out a new address, and the remote peers keep sending to the old one.
A quick comparison confirmed it. The DDNS hostname still resolved to my old IP, while a “what’s my IP” site showed a different one:
nslookup yourname.sn.mynetname.net 1.1.1.1
# Returned the OLD address, not the current one
In Winbox under IP → Cloud, the Public Address field was blank and the status was stuck on updating....
Step 2: Fix the clock first
The reboot was caused by a power outage, and the router’s clock was wrong when it came back up. The NTP client was disabled with no servers configured, so nothing was correcting it. A badly wrong clock can break the router’s cloud services, so this had to be fixed before anything else.
- Go to System → NTP Client and tick Enabled.
- Add servers, e.g.
time.cloudflare.comandza.pool.ntp.org(use your local pool). - Apply and wait for the status to change to
synchronized. - Check System → Clock has the correct time zone.
NTP syncing also proved that DNS and outbound UDP from the router itself were working, which narrowed the problem down further.
Step 3: Confirm it’s MikroTik’s side, not yours
With the clock fixed, Force Update still did nothing. Toggling DDNS to auto and back to yes didn’t help either. To see whether the update traffic was actually getting out, I used Tools → Torch on the PPPoE interface, filtered on port 15252 (the port MikroTik Cloud uses), and hit Force Update.
Torch showed traffic between my router and MikroTik’s cloud server, so the packets were reaching them and coming back. The router was doing its job; MikroTik’s backend just wasn’t publishing the new address. The MikroTik forums have plenty of threads describing this exact symptom over the years. Sometimes it clears up on its own; sometimes it doesn’t. Either way, it’s not something you can fix from your end.
Tip: the Winbox Ping tool only accepts IP addresses. To test name resolution from the router, use the terminal:
:put [:resolve cloud2.mikrotik.com]
/ping cloud2.mikrotik.com count=3
Step 4: Replace it with Cloudflare DDNS
My domains are already on Cloudflare, so the cleaner fix was to run my own DDNS updater and stop depending on a service I can’t troubleshoot. I used favonia/cloudflare-ddns, a small, well-maintained container.
Create a scoped API token
- In the Cloudflare dashboard, go to My Profile → API Tokens → Create Token.
- Use the Edit zone DNS template. The only permission needed is Zone → DNS → Edit.
- Under Zone Resources, limit it to the one zone you’re using.
- Copy the token and store it in your password manager. Cloudflare only shows it once.
Add it to your Docker stack
I already run cloudflared for a Cloudflare Tunnel on my entry host, so I added the DDNS updater to the same Compose stack (managed in Dockge). The only downside is that redeploying the stack restarts both containers; if that bothers you, give it its own stack.
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
restart: unless-stopped
command: tunnel --no-autoupdate run
network_mode: host
environment:
- TUNNEL_TOKEN=${TUNNEL_TOKEN}
cloudflare-ddns:
image: favonia/cloudflare-ddns:latest
container_name: cloudflare-ddns
restart: unless-stopped
network_mode: host
user: "1000:1000"
read_only: true
cap_drop: [all]
security_opt: [no-new-privileges:true]
environment:
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
- DOMAINS=yourrandomname.example.com
- PROXIED=false
- IP6_PROVIDER=none
- UPDATE_CRON=@every 5m
- TZ=Africa/Johannesburg
networks: {}
Put the token in the stack’s .env file rather than in the Compose file:
CLOUDFLARE_API_TOKEN=your_token_here
A few things worth knowing:
PROXIED=falseis essential. WireGuard is UDP and won’t work through Cloudflare’s orange-cloud proxy. The record must be DNS only (grey cloud).- The container detects your public IP via Cloudflare’s own trace endpoint, so the host must reach the internet through your normal WAN, not through a VPN or exit node.
- Check the container logs after deploying. You should see it detect your IP and create the A record.
Doesn’t this publish my IP?
Yes, but so did the MikroTik DDNS name, and internet-wide scanners will find your IP regardless. What a DNS record adds is a link between your IP and your domain, and a name that can be guessed. Two easy mitigations:
- Don’t call it
homeorvpn. Those are the first names subdomain enumeration tools try. Pick something silly and made up. Since you won’t issue a TLS certificate for it, it won’t show up in Certificate Transparency logs either. - WireGuard doesn’t reveal itself. It silently drops any packet not signed by a known peer key, so a port scan can’t tell it’s even there.
The real protection is a tight input firewall on your WAN, not hiding your IP. More on that below.
Step 5: Point the remote peers at the new name
On each remote MikroTik, in Winbox:
- Go to WireGuard → Peers and open the peer that points back home.
- Change Endpoint to your new Cloudflare hostname. Leave the port as it is.
- Make sure Persistent Keepalive is set (e.g.
25s). The remote side has to keep the tunnel alive, because the home router can’t initiate to it. - Apply, then disable and re-enable the peer so it resolves the new name.
Last Handshake should show a recent time within seconds. Nothing changes on the home router.
One catch: if the tunnels are already down, you need another way into the remote routers to make this change, such as a remote support tool on a PC at the site. Lesson learned: always have a second way in that doesn’t depend on the VPN you’re trying to fix.
Step 6: Make the tunnels heal themselves
Even with DNS correct, a RouterOS WireGuard peer can hold onto the IP it resolved earlier. This script checks the peer’s last handshake and, if it’s stale, disables and re-enables the peer to force a fresh DNS lookup. It finds the peer by endpoint name, so nothing else needs labelling.
:local endpoint "yourrandomname.example.com"
:local maxAge 00:05:00
:foreach p in=[/interface wireguard peers find where endpoint-address=$endpoint] do={
:local hs [/interface wireguard peers get $p last-handshake]
:if (([:typeof $hs] != "time") || ($hs > $maxAge)) do={
/interface wireguard peers disable $p
:delay 2s
/interface wireguard peers enable $p
:log warning "WireGuard: handshake stale, re-resolved $endpoint"
}
}
Set it up on each remote router:
- Go to System → Scripts → New. Name it
wg-reresolve, tick theread,writeandtestpolicies, and paste the script. - Go to System → Scheduler → New. Name it
wg-reresolve, set Interval to00:05:00, On Event towg-reresolve, and use the same three policies. - To test it, temporarily set
maxAgeto00:00:01, run the script, and check the warning appears in the Log and the tunnel comes straight back. Then set it back to00:05:00.
With a 25s keepalive, a healthy tunnel handshakes roughly every two minutes, so a five-minute threshold won’t trigger falsely. After an IP change, the sites reconnect by themselves within about ten minutes.
Step 7: Turn off MikroTik Cloud DDNS
With nothing depending on it anymore, disable it on the home router. In IP → Cloud, set DDNS Enabled to auto (only active when Back To Home needs it) and untick Update Time, since NTP handles the clock now. Or from the terminal:
/ip cloud set ddns-enabled=no update-time=no
Bonus: Check your logs while you’re in there
While troubleshooting, I opened the router’s log and found millions of hidden entries, almost all of them failed FTP login attempts from random internet IPs. If you see the same thing, a service is reachable from the WAN that shouldn’t be.
- In IP → Services, disable everything you don’t use (
ftp,telnet,www,api). - Restrict
winboxandsshwith Available From to your LAN and VPN subnets. - Make sure your input chain on the WAN interface ends in a drop, allowing only established/related traffic, your WireGuard port, and ICMP.
Takeaways
- If several sites drop at once, start with the hub.
- Enable NTP on every MikroTik. Routers without a battery-backed clock come back from a power cut with the wrong time.
- Don’t rely on a DDNS service you can’t see into. If your domain is on Cloudflare, running your own updater takes five minutes.
- Make remote peers re-resolve on their own, and always keep a second way into remote sites.










