Il tunnel sembra funzionare solo dopo che il server invia qualcosa per primo. Avviate dal client e non succede nulla, aspettate qualche secondo, riprovate e riesce. La diagnosi abituale è un NAT rotto, e la diagnosi abituale è sbagliata. Ciò che è cambiato è che un peer ha appreso dove vive l’altro.

La conoscenza dell’endpoint, non la raggiungibilità

Un peer WireGuard non avvierà un handshake finché non sa dove inviarlo. La configurazione lo fornisce come endpoint composto da indirizzo e porta, e lo stato in esecuzione segue l’endpoint in cui crede attualmente.

wg show stampa entrambi i lati di quel quadro, e un peer senza endpoint nell’output non può avviare nulla, per quanto corretti siano la sua chiave pubblica e i prefissi consentiti. Confrontate la visione del client con quella del server prima di cambiare qualsiasi regola, perché spesso i due non concordano su chi sa cosa.

Come un peer apprende un endpoint

WireGuard è volutamente silenzioso. Quando un pacchetto correttamente autenticato arriva da un indirizzo che il peer non si aspettava, l’implementazione aggiorna l’endpoint di quel peer alla nuova sorgente, ed è così che funziona il roaming su un portatile che cambia rete. Questo comportamento spiega la dipendenza dalla direzione: se il server invia per primo e il suo pacchetto raggiunge il client, il client apprende l’indirizzo attuale del server e può rispondere. Fino a quel momento non ha dove inviare. Il meccanismo è roaming autenticato e non una scorciatoia di fiducia al primo uso, perché il pacchetto doveva essere valido prima che l’endpoint si spostasse.

La documentazione degli strumenti per wg descrive quell’aggiornamento, e vale una lettura se intendete progettare attorno a questo.

La traduzione con stato aggiunge la propria direzione

Dove l’UDP attraversa un gateway che traduce, il gateway crea stato per il primo pacchetto che vede. RFC 4787 descrive quel comportamento e i timeout che alla fine rimuovono la mappatura. Una mappatura inattiva scade, e un pacchetto in ingresso dal lato lontano viene quindi scartato dal gateway prima di raggiungere l’host. Un tunnel che funzionava tutta la mattina smette di rispondere nel pomeriggio esattamente per questo motivo.

Questo è un secondo meccanismo indipendente che produce lo stesso sintomo direzionale. Sia la conoscenza dell’endpoint sia lo stato di traduzione devono essere corretti, e correggere uno non corregge l’altro.

Configurate la direzione che volete davvero

Per un client che deve avviare la connessione, mettete l’endpoint del server nella sezione dei peer del client e lasciatelo lì. Contare sull’invio del server per primo significa contare su un caso nell’ordine del traffico che cambierà in una rete tranquilla. La configurazione dovrebbe dichiarare la direzione prevista, non scoprirla.

Per un peer dietro una traduzione che deve restare raggiungibile, attivate un keepalive persistente su quel lato. Un keepalive ogni 25 secondi è il valore iniziale abituale, e il suo scopo è tenere aperta la mappatura anziché testare il tunnel. Scegliete un solo lato per portarlo, perché attivarlo su entrambi raddoppia il traffico e il rumore dei log senza migliorare il risultato.

Confrontate lo stato prima e dopo l’innesco

Catturate le due viste nel momento in cui fallisce, poi di nuovo dopo che il server invia. Il primo comando mostra gli endpoint e l’età dell’handshake. Il secondo mostra se esiste una voce di traduzione per la porta. La cattura mostra quale direzione ha davvero attraversato il cavo, e il controllo della rotta conferma che il client non invia quel traffico altrove.

wg show
conntrack -L -p udp 2>/dev/null | grep 51820
tcpdump -ni any -c 20 'udp port 51820'
ip route get 198.51.100.7

Annotate insieme la colonna dell’endpoint e la voce di traduzione. Un peer senza endpoint e un gateway senza mappatura sono due guasti diversi. Solo uno dei due si corregge con un keepalive.

Articoli correlati