Como identificar e remover chaves do apt não utilizadas?

Como identificar e remover chaves do apt não utilizadas?

Em uma instalação típica, várias chaves GPG apt são adicionadas, seja para PPAs ou outras fontes, e posteriormente não são utilizadas.

É difícil identificar na GUI (propriedades de software) quais chaves são realmente usadas para quais repositórios.

Existe uma maneira fácil de identificar quais chaves são usadas, para que todas as outras chaves possam ser removidas?

Na minha opinião, isso tem algumas implicações de segurança. Se o proprietário de um repositório perder sua chave privada e atualizar o repositório para usar uma nova chave, muitas pessoas ainda terão a chave antiga (não confiável) instalada, certo?

Responder1

Remover chaves não utilizadas é bastante simples, mas assim como ao adicionar chaves, você é o responsável por fazer sua lição de casa e decidir quais chaves não estão mais em uso e podem ser removidas.

Comece listando as chaves do apt que você possui atualmente sudo apt-key list.

Depois de identificar uma chave que não precisa mais, você pode simplesmente removê-la com sudo apt-key del KEYID.

Com o comando list você normalmente poderá ver o que é cada chave, principalmente se for de um ppa, já que normalmente terá um uid que inclui algo como "Launchpad PPA for John". Portanto, se você removeu esse ppa das fontes e não o usa mais, poderá removê-lo com segurança.

Às vezes você pode precisar de um google rápido para saber de onde vem uma chave específica, por exemplo, a chave mono tem o uid "Xamarin Public Jenkins", que se você pesquisar no Google xamarin poderá ver de onde veio essa chave. Além disso, você sempre pode voltar ao histórico do bash e encontrar a chave que adicionou se não tiver certeza.

man apt-keyestá lá para mais informações e outros comandos.

Responder2

Escrevi um script que identifica automaticamente (e opcionalmente exclui) chaves GPG não utilizadas.

#!/bin/bash
#------------------------------------
# Script that identifies and optionally removes unused trusted gpg keys.
# These keys are usually added to install software from non-standard repositories (e.g. PPAs)
# TODO:
# - what if source repo is not reachable
# - dunno why but the delete doesn't actually delete keys anymore ¯\_(ツ)_/¯
# - dunno why but slack key gets detected as unused even if slack is on the system ¯\_(ツ)_/¯
#------------------------------------

usage() { 
    echo "Usage: $(basename "$0") [-b] [-d] [-h]" 1>&2
    echo "prints to stdout the unused keys in the format <keyid> <userid>" 1>&2
    echo "-b, backups trusted.gpg and trusted.gpg.d/ appending .bak (requires superuser)" 1>&2
    echo "-d, deletes unused keys (requires superuser)" 1>&2
    echo "-h, shows this help" 1>&2
}

backup=0
delete=0

while getopts ":bdh" o; do
    case "${o}" in
        b)
            backup=1    
            ;;
        d)
            delete=1
            ;;
        h)
            usage
            exit 0
            ;;
        *)
            usage
            exit 1
            ;;
    esac
done
shift $((OPTIND-1))

# create directory in /tmp with random name
tmpdir=$(mktemp -d)
#echo "storing tmp files in $tmpdir" 1>&2

# get list of sources
grep -h ^deb /etc/apt/sources.list /etc/apt/sources.list.d/*.list > "${tmpdir}"/sources

# get list of releases files
# first sed expression removes content between square brackets (such as architecture specifications)
# awk is used to get only the source url and the distro we are using
# the 2 subsequent sed expressions are used piece everything together and generate the url to the Release.gpg file we need
# sort and uniq are used to eliminate duplicate entries
sed -e "s/\[.*\] //" "${tmpdir}/sources" | awk '{print $2" "$3}' | sed -E -e "s/\/? /\/dists\//" | sed -e "s/$/\/Release.gpg/" | sort | uniq > "${tmpdir}"/releases

# for each source, compute the keyid and save it in a file
while read -r url; do
    domain=$(echo $url | awk -F/ '{print $3}')
    #echo "processing ${url}"
    wget -q -T 10 -O "${tmpdir}"/"${domain}"_Release.gpg "$url"
    gpg --list-packets "${tmpdir}"/"${domain}"_Release.gpg | grep "keyid" | grep -Eo "[0-9A-F]{16}" >> "${tmpdir}"/sourcekeyidstemp
done <"${tmpdir}"/releases

# remove duplicate entries
sort "${tmpdir}"/sourcekeyidstemp | uniq > "${tmpdir}"/sourcekeyids

# for each trusted gpg key, extract his keyid and userid
gpg --list-packets /etc/apt/trusted.gpg | grep -A 8 "public key packet" | grep -E "keyid:|user ID" | grep -oE "[0-9A-F]{16}|\".*\""  | awk '{(getline tmp); print $0,tmp}' > "${tmpdir}"/trustedkeys

for f in /etc/apt/trusted.gpg.d/*.gpg; do
    gpg --list-packets "$f" | grep -A 8 "public key packet" | grep -E "keyid:|user ID" | grep -oE "[0-9A-F]{16}|\".*\""  | awk '{(getline tmp); print $0,tmp}' >> "${tmpdir}"/trustedkeys
done

# for each trusted gpg key, check if in use
touch "${tmpdir}"/unusedkeys
while read -r line; do
    keyid=$(echo "$line" | cut -d "\"" -f 1)
    userid=$(echo "$line" | cut -d "\"" -f 2)
    check=$(grep ${keyid} "${tmpdir}"/sourcekeyids)
    if [ -z "$check" ]; then
        echo "${keyid} ${userid}" >> "${tmpdir}"/unusedkeys
    fi 
done <"${tmpdir}"/trustedkeys

# backup gpg keys 
if [ $backup -eq 1 ]; then
    sudo cp /etc/apt/trusted.gpg /etc/apt/trusted.gpg.bak
    sudo cp -r /etc/apt/trusted.gpg.d/ /etc/apt/trusted.gpg.d.bak
fi

# delete unused gpg keys
if [ $delete -eq 1 ]; then
    while read -r line; do
        keyid=$(echo "$line" | cut -d "\"" -f 1)
        sudo apt-key del "$keyid" >/dev/null 
    done <"${tmpdir}"/unusedkeys
    echo "deleted keys:"
fi

# print unused keys
cat "${tmpdir}"/unusedkeys

É bastante desajeitado, mas funciona. Pode haver bugs, use por sua conta e risco.

O fluxo de trabalho do script é o seguinte:

  • extraia os KEYIDs de todas as fontes do apt buscando o arquivo Release.gpg do repositório online
  • extraia os KEYIDs de todas as suas chaves locais confiáveis.
  • verifique se alguns KEYIDs estão presentes localmente e não naqueles extraídos das fontes online. Essas são as chaves não utilizadas.

Editar: link fixo Editar: colei o código aqui porque estou cansado de consertar links

informação relacionada