Nach einem Internet-Reconnect zuhause ändert sich die öffentliche IP-Adresse, aber der WireGuard-Tunnel auf dem Hetzner-Server sendet weiterhin Pakete an die alte IP. Der Tunnel stirbt still und erholt sich nicht von selbst.
WireGuard löst den Endpoint-Hostnamen eines Peers einmal beim Start auf und nie wieder. Das ist beabsichtigt — WireGuard ist ein schlanker kryptografischer Transport ohne eingebautes dynamisches Peer-Management.
t=0 wg0 startet → myhost.dyndns.org wird zu 1.2.3.4 aufgelöst ✓
t=4h ISP vergibt neue IP 5.6.7.8, DynDNS aktualisiert
→ WireGuard sendet immer noch an 1.2.3.4 ✗ → Tunnel tot
wireguard-tools enthält reresolve-dns.sh genau für diesen Fall. Das Skript liest die Konfiguration neu ein, löst den Hostnamen jedes Peers erneut auf und führt ein Live-wg set peer ... endpoint-Update aus — ohne Tunnel-Neustart, ohne Verbindungsabbrüche. Es bearbeitet nur Peers, deren letzter Handshake veraltet ist (> 135 Sekunden), sodass gesunde Peers nie angetastet werden.
Skript finden:
find / -name "reresolve-dns.sh" 2>/dev/null
# Normalerweise: /usr/share/doc/wireguard-tools/examples/reresolve-dns/reresolve-dns.sh
Crontab-Eintrag (crontab -e als root), läuft alle 15 Minuten:
*/15 * * * * /usr/share/doc/wireguard-tools/examples/reresolve-dns/reresolve-dns.sh wg0 >> /var/log/wg-reresolve.log 2>&1
Das Log erhält nur Einträge, wenn tatsächlich eine IP-Änderung erkannt wurde.
Das Skript ist ein zeilenweiser Parser für die WireGuard-.conf-Datei, kombiniert mit einer Entscheidungsfunktion pro Peer.
Parser — liest jeden [Peer]-Block und sammelt PublicKey und Endpoint. Alle anderen Schlüssel werden ignoriert. process_peer() wird bei jedem neuen Abschnittsheader und am Dateiende aufgerufen.
process_peer() Entscheidungslogik:
1. Gültiger Peer-Block mit PublicKey + Endpoint? Nein → überspringen
2. Bei wg bekannt (hat einen Handshake-Eintrag)? Nein → überspringen
3. Letzter Handshake älter als 135 Sekunden? Nein → überspringen (Peer lebt)
Ja → wg set <if> peer <key> endpoint <host:port>
Der wg set-Aufruf in der letzten Zeile löst die frische DNS-Abfrage aus — $ENDPOINT enthält noch den ursprünglichen Hostnamen aus der Konfiguration, sodass WireGuard ihn an Ort und Stelle neu auflöst.
Die 135-Sekunden-Schwelle liegt über dem standardmäßigen 25-Sekunden-Keepalive-Fenster von WireGuard. Dadurch feuert das Skript nie bei einem gesunden Peer, der zufällig gerade still ist, erwischt aber trotzdem einen toten Peer innerhalb des 15-Minuten-Cron-Intervalls.
Was das Skript NICHT tut:
Endpoint behandeln (Inbound-Only / Road-Warrior-Clients)