4.0 KiB
WireGuard Tunnel for Remote MikroTik Access
When the user wants the agent to have direct SSH access to a MikroTik router for monitoring/onboarding, set up a WireGuard tunnel from the router to the management server. This is the same pattern used for the home CCR.
Server side (management box)
apt-get install -y wireguard
wg genkey | tee /root/wg-server.key | wg pubkey > /root/wg-server.pub
UFW: WireGuard port must be opened or handshakes never happen. The symptom is wg show wg0 shows 0 bytes transferred and no handshake timestamp, even though both sides are configured correctly and the router can reach the server.
ufw allow 51820/udp comment "WireGuard VPN"
ufw reload
Write /etc/wireguard/wg0.conf:
[Interface]
Address = 10.77.0.1/24
ListenPort = 51820
PrivateKey = <contents of /root/wg-server.key>
[Peer]
PublicKey = <client-public-key>
AllowedIPs = 10.77.0.2/32, <router-lan-subnet>
Start the service:
systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0
Client side (MikroTik CCR)
GENERATE FRESH CLIENT KEYS on the server for each new router:
CCR_PRIV=$(wg genkey)
CCR_PUB=$(echo "$CCR_PRIV" | wg pubkey)
Update the server config with CCR_PUB, then present the MikroTik script with CCR_PRIV embedded:
/interface wireguard add name=wg-itpp listen-port=13231 \
private-key="<CCR_PRIV>" comment="IT Pro Partner Tunnel"
/interface wireguard peers add interface=wg-itpp \
public-key="<server-public-key>" \
endpoint-address=<server-public-ip> endpoint-port=51820 \
allowed-address=10.77.0.0/24 persistent-keepalive=25
/ip address add address=10.77.0.2/24 interface=wg-itpp
/ip firewall filter add chain=input protocol=udp dst-port=13231 \
place-before=1 comment="allow WG tunnel (ITPP)"
Verify with /ping 10.77.0.1 on the router.
Key principle: generate-then-present-not-store
- Generate fresh client keys on the server
- Update the server's peer config with the client's public key
- Present the generated private key in the MikroTik script
- Do this in the same terminal session
- The private key is delivered in the script output — the user pastes it onto the router immediately
Verification
After the tunnel is up on both sides:
# From the management server
ping -c 2 10.77.0.2
# Then SSH to the router through the tunnel
ssh -i ~/.ssh/wisp_rsa admin@10.77.0.2 "/system identity print"
The MikroTik's LAN subnet (e.g. 10.10.10.0/24) is also reachable through the tunnel via the AllowedIPs directive.
Pitfall: Router public key in export vs live mismatch
The /export show-sensitive output shows the router's public key from when the config was last saved. If the private key was regenerated on the router (e.g. someone ran /interface wireguard reset), the export becomes stale. Always verify the live public key:
/interface wireguard print detail where name=wg-itpp
Compare the public-key= field against what the server's wg0.conf peer entry has. If they differ, update the server peer config with the live router public key. The router's live public key is authoritative — the export file is not.
Pitfall: Router-side peer key mismatches after migration
When migrating Hermes from one server to another, the router's WireGuard peer points at the old server's public key. On the router, update the peer:
/interface wireguard peers set [find comment="Core (netcup)"] public-key="<new-server-public-key>"
Also verify the endpoint-port matches the new server's ListenPort. If the port changed (e.g. 51820→51821), the router side endpoint-port must match.
Pitfall: Multiple tunnels to the same router
Each server needs its own WG IP (10.77.0.1 for primary, 10.77.0.3 for standby) and its own peer entry on the router. Add the second peer via:
/interface wireguard peers add interface=wg-itpp public-key="<second-server-pubkey>" allowed-address=10.77.0.3/32 endpoint-address=<second-server-ip> endpoint-port=51821 persistent-keepalive=25s comment="app1-bu (Hetzner standby)"