사용하지 않는 적절한 키를 식별하고 제거하는 방법은 무엇입니까?

사용하지 않는 적절한 키를 식별하고 제거하는 방법은 무엇입니까?

일반적인 설치에서는 PPA 또는 기타 소스용으로 여러 적절한 GPG 키가 추가되고 나중에 사용되지 않습니다.

어떤 키가 실제로 어떤 리포지토리에 사용되는지 GUI(소프트웨어 속성)에서 식별하기는 어렵습니다.

어떤 키가 사용되는지 식별하여 다른 모든 키를 제거할 수 있는 쉬운 방법이 있습니까?

제 생각에는 이것이 보안에 어느 정도 영향을 미친다고 생각합니다. 저장소 소유자가 개인 키를 분실하고 새 키를 사용하도록 저장소를 업데이트하는 경우 많은 사람들이 여전히 이전(신뢰할 수 없는) 키를 설치하고 있습니다. 그렇죠?

답변1

사용하지 않는 키를 제거하는 것은 매우 간단하지만, 키를 추가할 때와 마찬가지로 숙제를 하고 어떤 키가 더 이상 사용되지 않으며 제거할 수 있는지 결정하는 책임은 사용자에게 있습니다.

현재 가지고 있는 적절한 키를 나열하는 것부터 시작하세요 sudo apt-key list.

더 이상 필요하지 않은 키를 식별한 후에는 를 사용하여 간단히 제거할 수 있습니다 sudo apt-key del KEYID.

list 명령을 사용하면 일반적으로 각 키가 무엇인지 확인할 수 있습니다. 특히 ppa에서 가져온 경우 일반적으로 "Launchpad PPA for John"과 같은 내용이 포함된 uid가 있기 때문입니다. 따라서 소스에서 해당 ppa를 제거하고 더 이상 사용하지 않는 경우 안전하게 제거할 수 있습니다.

때로는 특정 키가 어디에서 왔는지 알기 위해 빠른 Google이 필요할 수 있습니다. 예를 들어 모노 키에는 uid "Xamarin Public Jenkins"가 있으며, Google 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

꽤 투박하지만 작동합니다. 버그가 있을 수 있으니 사용에 따른 책임은 본인에게 있습니다.

스크립트의 작업 흐름은 다음과 같습니다.

  • 온라인 저장소에서 Release.gpg 파일을 가져와 모든 적절한 소스의 KEYID를 추출합니다.
  • 모든 로컬 신뢰할 수 있는 키의 KEYID를 추출합니다.
  • 일부 KEYID가 로컬에 있는지, 온라인 소스에서 추출된 KEYID에는 없는지 확인하세요. 사용되지 않은 키입니다.

편집: 링크 수정 편집: 링크 수정에 지쳐서 여기에 코드를 붙여넣었습니다.

관련 정보