Как определить и удалить неиспользуемые ключи apt?

Как определить и удалить неиспользуемые ключи apt?

При типичной установке добавляется несколько подходящих ключей GPG, будь то для PPA или других источников, которые в дальнейшем не используются.

В графическом интерфейсе (свойствах программного обеспечения) сложно определить, какие ключи на самом деле используются для тех или иных репозиториев.

Есть ли простой способ определить, какие ключи используются вообще, чтобы можно было удалить все остальные ключи?

По моему мнению, это имеет некоторые последствия для безопасности. Если владелец репозитория потеряет свой закрытый ключ и обновит репозиторий, чтобы использовать новый ключ, у многих людей все еще будет установлен старый (не заслуживающий доверия) ключ, верно?

решение1

Удалить неиспользуемые ключи довольно просто, но, как и при добавлении ключей, вы сами отвечаете за выполнение своей домашней работы и решение о том, какие ключи больше не используются и могут быть удалены.

Начните с перечисления имеющихся у вас в данный момент ключей apt sudo apt-key list.

Как только вы определите ключ, который вам больше не нужен, вы можете просто удалить его с помощью sudo apt-key del KEYID.

С помощью команды list вы обычно сможете увидеть, что представляет собой каждый ключ, особенно если он из ppa, поскольку он обычно имеет uid, включающий что-то вроде "Launchpad PPA for John". Так что, если вы удалили этот ppa из источников и больше не используете его, вы можете безопасно удалить их.

Иногда вам может понадобиться быстрый поиск в Google, чтобы узнать, откуда взялся определенный ключ, например, ключ mono имеет uid "Xamarin Public Jenkins", и если вы загуглите xamarin, вы увидите, откуда взялся этот ключ. Кроме того, вы всегда можете вернуться к истории bash и найти ключ, который вы добавили, если вы не уверены.

man apt-keyесть ли там дополнительная информация и другие команды.

решение2

Я написал скрипт, который автоматически идентифицирует (и при необходимости удаляет) неиспользуемые ключи GPG.

#!/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

Это довольно неуклюже, но работает. Могут быть ошибки, используйте на свой страх и риск.

Рабочий процесс скрипта следующий:

  • извлеките KEYID всех исходных кодов apt, загрузив файл Release.gpg из онлайн-репозитория
  • извлеките KEYID всех ваших локальных доверенных ключей.
  • проверьте, присутствуют ли некоторые KEYID локально и отсутствуют в извлеченных из онлайн-источников. Это неиспользуемые ключи.

Редактировать: исправленная ссылка Редактировать: вставил код сюда, потому что я устал исправлять ссылки

Связанный контент