Corrigindo erros de chave GPG de repositorio (NO_PUBKEY)

Corrigindo erros de chave GPG de repositorio (NO_PUBKEY)

O que voce vai aprender

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

Resumo rapido

  • NO_PUBKEY <KEYID> -> a chave publica nao esta na sua maquina. Busque-a em um keyring
  • EXPKEYSIG / KEYEXPIRED -> a chave de assinatura expirou. Busque novamente a chave atual
  • O padrao seguro e buscar a URL da chave via HTTPS -> gpg --dearmor -> colocar em /etc/apt/keyrings/ -> signed-by=

Premissas

  • SO: Ubuntu 20.04+ / Debian 11+
  • Voce tem sudo
  • O alvo e um repositorio APT de terceiros (para a chave oficial do arquivo, veja a secao dedicada)

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

Conclusao: O APT verifica a assinatura de cada repositorio com uma chave publica. Se a chave esta ausente, expirada ou foi rotacionada, apt update emite um erro GPG.

O APT verifica, em cada execucao, se o arquivo Release de um repositorio esta assinado por uma chave confiavel (secure apt). Quando a verificacao falha, ele recusa a atualizacao e imprime um aviso. As causas se dividem em tres grupos.

Mensagem Significado Causa comum
NO_PUBKEY <KEYID> Nenhuma chave publica correspondente localmente Chave nunca adicionada ou foi removida
EXPKEYSIG <KEYID> Assinatura e da chave, mas a chave expirou Chave de assinatura do fornecedor passou da validade
KEYEXPIRED <unixtime> O periodo de validade da chave passou Mesmo que acima (redacao do gpg)

Uma saida tipica 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 verificacao (trusted=yes ou --allow-unauthenticated) significa que voce corre o risco de instalar pacotes adulterados. Como regra, corrija instalando a chave correta.

Como corrigir um erro NO_PUBKEY?

Conclusao: Anote o KEYID na mensagem, depois busque a chave publica do fornecedor em um keyring. Se o fornecedor publica a chave via HTTPS, essa URL e a fonte mais segura.

1. Identifique o ID da chave ausente

O valor hexadecimal de 16 digitos (ou 8 digitos) apos NO_PUBKEY e o ID da chave. Acima, e 871920D1991BC93C.

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

A maioria dos fornecedores publica uma chave publica .gpg ou .asc via HTTPS. Converta para um keyring binario 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 binario. Se o arquivo ja e binario .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 repositorio 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 voce so tem o ID da chave: busque de um keyserver

Se voce nao 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 nao pode provar que o ID da chave realmente pertence ao fornecedor. Prefira a URL HTTPS do fornecedor sempre que disponivel.

Como corrigir uma assinatura expirada (EXPKEYSIG / KEYEXPIRED)?

Conclusao: Uma assinatura expirada nao e uma chave ausente - e a mesma chave apos sua validade. Busque novamente a chave publica atualizada do fornecedor e sobrescreva o keyring.

A saida se parece com:

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

A correcao e quase identica 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 nao atualizou a chave, voce nao pode corrigir do seu lado. Verifique o anuncio do fornecedor ou a pagina de instrucoes do repositorio.

Devo evitar o apt-key?

Conclusao: apt-key esta obsoleto no Ubuntu 20.04 / Debian 11 e posterior. Nao use em novos procedimentos - migre para arquivos keyring mais signed-by=.

Voce vera guias antigos usando apt-key adv --recv-keys ..., mas apt-key esta programado para remocao e tem uma falha de design: ele adiciona a chave a um unico keyring confiavel por todos os repositorios (a chave de um fornecedor pode entao verificar pacotes de outro fornecedor).

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

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

Quando voce ver este aviso, migre para o metodo da proxima secao.

Como colocar a chave corretamente com signed-by?

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

Localizacao e permissoes

Item Recomendado
Local da chave /etc/apt/keyrings/ (crie com sudo install -d -m 0755 /etc/apt/keyrings)
Formato da chave binario, produzido por gpg --dearmor
Permissao arquivo 644 ou mais (legivel por nao-root)

Se o arquivo keyring for 600 (somente root), o usuario _apt nao pode ler a chave e NO_PUBKEY nao 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 tambem 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 repositorio Ubuntu estiver expirada?

Conclusao: As chaves oficiais do arquivo sao gerenciadas pelo pacote ubuntu-keyring (ou debian-archive-keyring). Atualiza-lo instala as chaves mais recentes.

Se o erro e no repositorio 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 proprio apt update esta falhando com o erro de chave, ele pode nao conseguir baixar o pacote acima. Nesse caso, verifique o anuncio de rotacao de chave do fornecedor, obtenha o novo pacote *-keyring (.deb) por um canal confiavel e instale com sudo dpkg -i.

Cheat sheet de troubleshooting

Conclusao: O texto da mensagem decide a causa. NO_PUBKEY significa buscar, EXPKEYSIG significa buscar novamente, e verifique permissoes e caminhos por ultimo.

Sintoma Verificar Correcao
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 permissao 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 repositorio oficial - Reinstalar ubuntu-keyring / debian-archive-keyring

Proximas leituras