Corrigindo erros de chave GPG de repositório (NO_PUBKEY)

Corrigindo erros de chave GPG de repositório (NO_PUBKEY)

O que você vai aprender

  • Diferenciar os erros GPG do apt lendo NO_PUBKEY vs EXPKEYSIG
  • Buscar a chave pública ausente em um keyring e vincular com signed-by=
  • Migrar do obsoleto apt-key para o modelo atual de gerenciamento de chaves

Resumo rápido

  • NO_PUBKEY <KEYID> -> a chave pública não está na sua máquina. Busque-a em um keyring
  • EXPKEYSIG / KEYEXPIRED -> a chave de assinatura expirou. Busque novamente a chave atual
  • O padrão seguro é buscar a URL da chave via HTTPS -> gpg --dearmor -> colocar em /etc/apt/keyrings/ -> signed-by=

Premissas

  • SO: Ubuntu 20.04+ / Debian 11+
  • Você tem sudo
  • O alvo é um repositório APT de terceiros (para a chave oficial do arquivo, veja a seção dedicada)

O que é um erro de chave GPG e por que acontece?

Conclusão: O APT verifica a assinatura de cada repositório com uma chave pública. Se a chave está ausente, expirada ou foi rotacionada, apt update emite um erro GPG.

O APT verifica, em cada execução, se o arquivo Release de um repositório está assinado por uma chave confiável (secure apt). Quando a verificação falha, ele recusa a atualização e imprime um aviso. As causas se dividem em três grupos.

Mensagem Significado Causa comum
NO_PUBKEY <KEYID> Nenhuma chave pública correspondente localmente Chave nunca adicionada ou foi removida
EXPKEYSIG <KEYID> Assinatura é da chave, mas a chave expirou Chave de assinatura do fornecedor passou da validade
KEYEXPIRED <unixtime> O período de validade da chave passou Mesmo que acima (redação do gpg)

Uma saída típica se parece com:

W: GPG error: https://repo.example.com stable InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 871920D1991BC93C
E: The repository 'https://repo.example.com stable InRelease' is not signed.

Silenciar o aviso desabilitando verificação (trusted=yes ou --allow-unauthenticated) significa que você corre o risco de instalar pacotes adulterados. Como regra, corrija instalando a chave correta.

Como corrigir um erro NO_PUBKEY?

Conclusão: Anote o KEYID na mensagem, depois busque a chave pública do fornecedor em um keyring. Se o fornecedor publica a chave via HTTPS, essa URL é a fonte mais segura.

1. Identifique o ID da chave ausente

O valor hexadecimal de 16 dígitos (ou 8 dígitos) após NO_PUBKEY é o ID da chave. Acima, é 871920D1991BC93C.

2. Busque da URL de chave do fornecedor (recomendado)

A maioria dos fornecedores publica uma chave pública .gpg ou .asc via HTTPS. Converta para um keyring binário com gpg --dearmor e coloque em keyrings.

$ curl -fsSL https://repo.example.com/gpg.key \
  | sudo gpg --dearmor -o /etc/apt/keyrings/example.gpg

--dearmor converte o formato ASCII (-----BEGIN PGP PUBLIC KEY-----) em um keyring binário. Se o arquivo já é binário .gpg, salve diretamente com curl -fsSL ... -o /etc/apt/keyrings/example.gpg.

3. Adicione signed-by na entrada de sources

Use signed-by= para declarar qual repositório esta chave verifica (veja detalhes).

$ echo "deb [signed-by=/etc/apt/keyrings/example.gpg] https://repo.example.com stable main" \
  | sudo tee /etc/apt/sources.list.d/example.list
$ sudo apt update

Quando você só tem o ID da chave: busque de um keyserver

Se você não tem a URL do fornecedor mas sabe o ID da chave, receba diretamente em um keyring de um keyserver.

$ sudo gpg --no-default-keyring \
  --keyring /etc/apt/keyrings/example.gpg \
  --keyserver keyserver.ubuntu.com \
  --recv-keys 871920D1991BC93C

Uma busca em keyserver não pode provar que o ID da chave realmente pertence ao fornecedor. Prefira a URL HTTPS do fornecedor sempre que disponível.

Como corrigir uma assinatura expirada (EXPKEYSIG / KEYEXPIRED)?

Conclusão: Uma assinatura expirada não é uma chave ausente - é a mesma chave após sua validade. Busque novamente a chave pública atualizada do fornecedor e sobrescreva o keyring.

A saída se parece com:

W: GPG error: https://repo.example.com stable InRelease: The following signatures were invalid: EXPKEYSIG 871920D1991BC93C Example Repo Signing Key

A correção é quase idêntica a NO_PUBKEY: sobrescreva o keyring com a chave mais recente. Fornecedores geralmente republicam a mesma chave com validade estendida, ou uma chave sucessora.

# Buscar novamente e sobrescrever a chave publica
$ curl -fsSL https://repo.example.com/gpg.key \
  | sudo gpg --dearmor -o /etc/apt/keyrings/example.gpg
$ sudo apt update

Verifique a validade da chave buscada aqui - procure [expired] ou uma linha expires:.

$ gpg --show-keys /etc/apt/keyrings/example.gpg

Se o fornecedor ainda não atualizou a chave, você não pode corrigir do seu lado. Verifique o anuncio do fornecedor ou a página de instruções do repositório.

Devo evitar o apt-key?

Conclusão: apt-key está obsoleto no Ubuntu 20.04 / Debian 11 e posterior. Não use em novos procedimentos - migre para arquivos keyring mais signed-by=.

Você verá guias antigos usando apt-key adv --recv-keys ..., mas apt-key está programado para remoção e tem uma falha de design: ele adiciona a chave a um único keyring confiável por todos os repositórios (a chave de um fornecedor pode então verificar pacotes de outro fornecedor).

A resposta atual é manter chaves em arquivos separados e definir o escopo de cada uma com signed-by= para que se aplique apenas ao repositório pretendido.

Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).

Quando você ver este aviso, migre para o método da próxima seção.

Como colocar a chave corretamente com signed-by?

Conclusão: Coloque a chave em /etc/apt/keyrings/ e informe o caminho completo na entrada [signed-by=...] do sources. O arquivo precisa de permissão de leitura 644 ou mais.

Localização e permissões

Item Recomendado
Local da chave /etc/apt/keyrings/ (crie com sudo install -d -m 0755 /etc/apt/keyrings)
Formato da chave binário, produzido por gpg --dearmor
Permissão arquivo 644 ou mais (legível por não-root)

Se o arquivo keyring for 600 (somente root), o usuário _apt não pode ler a chave e NO_PUBKEY não vai desaparecer. Verifique com sudo chmod 644 /etc/apt/keyrings/example.gpg.

Entrada do sources (formato de uma linha)

deb [signed-by=/etc/apt/keyrings/example.gpg] https://repo.example.com stable main

Entrada do sources (formato deb822 / .sources)

Ubuntu / Debian recentes também aceitam o formato deb822. Coloque o mesmo caminho em Signed-By:.

$ sudo tee /etc/apt/sources.list.d/example.sources > /dev/null <<'EOF'
Types: deb
URIs: https://repo.example.com
Suites: stable
Components: main
Signed-By: /etc/apt/keyrings/example.gpg
EOF

E se a chave oficial do repositório Ubuntu estiver expirada?

Conclusão: As chaves oficiais do arquivo são gerenciadas pelo pacote ubuntu-keyring (ou debian-archive-keyring). Atualizá-lo instala as chaves mais recentes.

Se o erro é no repositório oficial do Ubuntu/Debian em vez de um terceiro, tente atualizar o pacote de keyring.

# Ubuntu
$ sudo apt install --reinstall ubuntu-keyring

# Debian
$ sudo apt install --reinstall debian-archive-keyring

Se o próprio apt update está falhando com o erro de chave, ele pode não conseguir baixar o pacote acima. Nesse caso, verifique o anuncio de rotação de chave do fornecedor, obtenha o novo pacote *-keyring (.deb) por um canal confiável e instale com sudo dpkg -i.

Cheat sheet de troubleshooting

Conclusão: O texto da mensagem decide a causa. NO_PUBKEY significa buscar, EXPKEYSIG significa buscar novamente, e verifique permissões e caminhos por último.

Sintoma Verificar Correção
NO_PUBKEY <KEYID> Anotar o ID da chave Buscar da URL do fornecedor ou keyserver no keyring
EXPKEYSIG / KEYEXPIRED gpg --show-keys para validade Sobrescrever o keyring com a chave mais recente
Adicionou chave mas sem efeito ls -l /etc/apt/keyrings/ Definir permissão para 644+ (chmod 644)
Adicionou chave mas sem efeito caminho signed-by= no sources Corresponder ao caminho completo do keyring
apt-key is deprecated - Migrar para keyring + signed-by=
Acontece no repositório oficial - Reinstalar ubuntu-keyring / debian-archive-keyring

Próximas leituras