O seu túnel funcionava ontem, a máquina reiniciou após uma atualização e agora a interface não sobe. Num sistema onde o WireGuard é compilado como módulo externo, a causa habitual é que o módulo no disco pertence a uma versão do kernel diferente da que está em execução agora. Cabeçalhos com um nome semelhante na mesma máquina não provam nada sobre essa correspondência. Só a cadeia de versão decide isso.

Kernel em execução ou instalado

Uma atualização instala um novo pacote de kernel e deixa o antigo no disco até a máquina reiniciar. Após o reinício a versão em execução muda, e qualquer módulo compilado contra a anterior fica inutilizável mesmo que os seus ficheiros ainda estejam lá. Essa lacuna explica o relato habitual de uma máquina que estava bem antes de um reinício e avariada depois, sem qualquer alteração de configuração pelo meio. Também explica porque é que reinstalar os cabeçalhos às vezes parece resolver o problema e outras não.

O pacote de cabeçalhos que instala pode corresponder ao pacote de kernel mais recente em vez do kernel que realmente arrancou, e nada no nome do pacote distingue esses casos; só a cadeia de versão o faz. Verifique o que está em execução antes de verificar o que está instalado.

Três verificações antes de recompilar

A primeira verificação é qual kernel está em execução. A segunda é se existe um módulo para essa versão e se pode ser encontrado. A terceira é se o kernel já o carregou. A quarta pergunta, se a interface pode ser criada, testa privilégios e não o módulo, por isso vai depois da recompilação e não nesta lista.

Os comandos abaixo respondem às três primeiras sem alterar nada. Leia cada resultado antes de continuar, porque cada resposta exclui uma reparação diferente.

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

Se a segunda linha indicar que o caminho não existe, falta o ambiente de compilação do kernel em execução e nada do que compilar corresponderá. Se modinfo falhar enquanto o caminho existe, o módulo pode não estar instalado de todo, o que é normal em kernels que fornecem a implementação na árvore. Se modinfo tiver êxito e lsmod não mostrar nada, o módulo existe mas não está carregado, o que é um problema de carregamento e não de compilação. Cada resultado leva-o a um sítio diferente, por isso ler importa mais do que os comandos.

Compile contra a versão em execução

Um módulo externo compila-se contra uma árvore do kernel preparada, e o guia do kernel para módulos externos descreve o uso do diretório de compilação que pertence ao kernel em execução e não o que tem o número de versão mais alto. Esse diretório de compilação é uma ligação simbólica mantida pelo pacote do kernel, por isso aponta para a árvore da versão que está arrancada. A indireção é exatamente o ponto: elimina uma escolha que de outra forma faria mal. Nomeá-lo explicitamente torna o alvo inequívoco.

Um detalhe importa quando a árvore só foi preparada e não totalmente compilada. O alvo de preparação não produz o ficheiro de versionamento de símbolos de que algumas compilações externas precisam, por isso uma árvore cheia de cabeçalhos não é automaticamente um ambiente de compilação completo. Se uma compilação falhar por símbolos em falta, esse ficheiro é o primeiro sítio a olhar.

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 os cabeçalhos empacotados ficam atrás

Em distribuições e computadores de placa única que empacotam os seus próprios kernels, os cabeçalhos podem ficar dias ou semanas atrás da versão. O pacote de cabeçalhos pode estar correto no nome e mais antigo no conteúdo, o que produz uma compilação que compila e depois falha ao carregar em vez de durante a compilação. Misturar fontes piora a situação: um kernel de distribuição com cabeçalhos de um repositório de terceiros, ou um kernel de fabricante com cabeçalhos genéricos, pode compilar limpo e ainda assim ser rejeitado pelo kernel em execução porque a configuração difere. Os números de versão por si só não resolvem isso.

Se a máquina segue um canal de kernel experimental, decida conscientemente se fica lá com artefactos de compilação correspondentes ou se volta ao conjunto de pacotes suportado. Repetir a atualização e esperar que as peças se alinhem não é um plano, porque a mesma incompatibilidade se repete de cada vez.

Verifique a interface após a recompilação

Após uma instalação bem-sucedida, criar a interface é o teste que importa, seguido de ler o que o kernel carregou realmente e o que diz o registo se recusou. Um módulo que carrega e uma interface que não pode ser criada são falhas diferentes com causas diferentes. Os três comandos abaixo separam-nas.

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

Se o módulo recusar carregar, o registo do kernel indica o motivo, e uma incompatibilidade de versão é apenas uma das possibilidades. Leia essa linha antes de recompilar, porque uma segunda compilação idêntica gasta os mesmos dez minutos e produz a mesma recusa. Depois remova a interface temporária para que o teste seguinte comece de um estado limpo.

Artigos relacionados