Il vostro tunnel funzionava ieri, la macchina si è riavviata dopo un aggiornamento e ora l’interfaccia non sale. Su un sistema in cui WireGuard viene compilato come modulo esterno, la causa abituale è che il modulo sul disco appartiene a una versione del kernel diversa da quella in esecuzione ora. Intestazioni con un nome simile sulla stessa macchina non dimostrano nulla su quella corrispondenza. Solo la stringa di versione lo decide.

Kernel in esecuzione o kernel installato

Un aggiornamento installa un nuovo pacchetto del kernel e lascia il vecchio sul disco finché la macchina non si riavvia. Dopo il riavvio la versione in esecuzione cambia, e ogni modulo compilato contro la precedente diventa inutilizzabile anche se i suoi file sono ancora lì. Quel divario spiega il resoconto abituale di una macchina che andava bene prima di un riavvio e si è rotta dopo, senza alcun cambiamento di configurazione nel mezzo. Spiega anche perché reinstallare le intestazioni a volte sembra risolvere il problema e a volte no.

Il pacchetto di intestazioni che installate può corrispondere al pacchetto del kernel più recente invece che al kernel realmente avviato, e nulla nel nome del pacchetto distingue quei casi; solo la stringa di versione lo fa. Controllate cosa è in esecuzione prima di controllare cosa è installato.

Tre controlli prima di ricompilare

Il primo controllo è quale kernel è in esecuzione. Il secondo è se esiste un modulo per quella versione e se si può trovare. Il terzo è se il kernel lo ha già caricato. La quarta domanda, se l’interfaccia può essere creata, mette alla prova i privilegi e non il modulo, quindi va dopo la ricompilazione e non in questo elenco.

I comandi qui sotto rispondono ai primi tre senza cambiare nulla. Leggete ogni risultato prima di proseguire, perché ogni risposta esclude una riparazione diversa.

uname -r
ls -l /lib/modules/$(uname -r)/build
modinfo wireguard
lsmod | grep wireguard

Se la seconda riga riporta che il percorso non esiste, manca l’ambiente di compilazione per il kernel in esecuzione e nulla di ciò che compilate vi corrisponderà. Se modinfo fallisce mentre il percorso esiste, il modulo potrebbe non essere affatto installato, cosa normale sui kernel che forniscono l’implementazione nell’albero. Se modinfo riesce e lsmod non mostra nulla, il modulo esiste ma non è caricato, il che è un problema di caricamento e non di compilazione. Ogni esito vi manda altrove, per questo leggere conta più dei comandi.

Compilate contro la versione in esecuzione

Un modulo esterno si compila contro un albero del kernel preparato, e la guida del kernel per i moduli esterni descrive l’uso della directory di compilazione che appartiene al kernel in esecuzione e non di quella che porta il numero di versione più alto. Quella directory di compilazione è un collegamento simbolico mantenuto dal pacchetto del kernel, quindi punta all’albero della versione attualmente avviata. L’indirezione è proprio il punto: elimina una scelta che altrimenti fareste male. Nominarla esplicitamente rende l’obiettivo inequivocabile.

Un dettaglio conta quando l’albero è solo preparato e non compilato del tutto. L’obiettivo di preparazione non produce il file di versionamento dei simboli che alcune compilazioni esterne richiedono, quindi un albero pieno di intestazioni non è automaticamente un ambiente di compilazione completo. Se una compilazione fallisce per simboli mancanti, quel file è il primo posto da guardare.

sudo make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
sudo make -C /lib/modules/$(uname -r)/build M=$(pwd) modules_install
sudo depmod -a

Quando le intestazioni impacchettate restano indietro

Sulle distribuzioni e sui computer a scheda singola che impacchettano i propri kernel, le intestazioni possono restare indietro di giorni o settimane rispetto alla versione. Il pacchetto di intestazioni può essere corretto nel nome e più vecchio nel contenuto, il che produce una compilazione che compila e poi fallisce al caricamento invece che durante la compilazione. Mescolare le fonti peggiora le cose: un kernel di distribuzione con intestazioni da un repository di terze parti, o un kernel di produttore con intestazioni generiche, può compilare pulito ed essere comunque rifiutato dal kernel in esecuzione perché la configurazione è diversa. I numeri di versione da soli non risolvono questo.

Se la macchina segue un canale kernel sperimentale, decidete consapevolmente se restare lì con artefatti di compilazione corrispondenti o tornare all’insieme di pacchetti supportato. Ripetere l’aggiornamento e sperare che i pezzi si allineino non è un piano, perché la stessa discrepanza si ripete ogni volta.

Verificate l’interfaccia dopo la ricompilazione

Dopo un’installazione riuscita, creare l’interfaccia è il test che conta, seguito dalla lettura di ciò che il kernel ha davvero caricato e di ciò che dice il registro se ha rifiutato. Un modulo che si carica e un’interfaccia che non può essere creata sono guasti diversi con cause diverse. I tre comandi qui sotto li separano.

sudo ip link add wg9 type wireguard
lsmod | grep wireguard
sudo dmesg | tail -5

Se il modulo rifiuta di caricarsi, il registro del kernel ne indica il motivo, e una discrepanza di versione è solo una delle possibilità. Leggete quella riga prima di ricompilare, perché una seconda compilazione identica costa gli stessi dieci minuti e produce lo stesso rifiuto. Poi rimuovete l’interfaccia usa e getta perché il test successivo parta da uno stato pulito.

Articoli correlati