为什么apt GPG密钥必须是可读的?

当使用apt仓库条目的"Signed-by"选项时,如果密钥不可读,则apt会抛出错误。
示例:
deb [arch=amd64 signed-by=/etc/apt/keyrings/hashicorp.gpg] https://apt.releases.hashicorp.com jammy main

sudo chmod 660 /etc/apt/keyrings/hashicorp.gpg
sudo apt-get update  


https://apt.releases.hashicorp.com jammy InRelease  
The following signatures couldn't be verified because the public key is not available: NO_PUBKEY DA418C88A3219F7B  

sudo chmod 664 /etc/apt/keyrings/hashicorp.gpg  
sudo apt-get update  
Hit:10 https://apt.releases.hashicorp.com jammy InRelease  

为什么会这样呢?

抱歉,你好。由于Ubuntu 22.04目前还不存在,所以任何与它相关的问题都不符合当前的讨论主题。非常抱歉。 - David
在Focal上可以复现。 - martibs
1个回答

它们不必对全世界可读,但必须可以被用户apt所运行的用户读取。即使以root用户身份运行,Apt通常会通过切换到_apt用户来放弃权限,以执行不需要权限的操作。例如:

# getent passwd _apt
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
# strace -f apt update |& grep si_uid
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=708, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
[pid   709] --- SIGINT {si_signo=SIGINT, si_code=SI_USER, si_pid=707, si_uid=0} ---
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=709, si_uid=0, si_status=100, si_utime=0, si_stime=0} ---
[pid   712] --- SIGINT {si_signo=SIGINT, si_code=SI_USER, si_pid=707, si_uid=0} ---
[pid   707] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=712, si_uid=0, si_status=SIGINT, si_utime=0, si_stime=0} ---
[pid   715] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=716, si_uid=100, si_status=0, si_utime=0, si_stime=0} ---
[pid   717] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=718, si_uid=100, si_status=0, si_utime=0, si_stime=0} ---
[pid   715] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=717, si_uid=100, si_status=0, si_utime=0, si_stime=0} ---

注意许多子进程的UID是100,而_apt用户的UID也是100。
话虽如此,将密钥仅限root用户可读并没有任何好处。

5为了澄清上一点,APT使用的(公共)密钥是公开可用的信息,可以根据所配置的系统仓库列表轻松获取,并且可以简单地根据已安装的内容确定。 - Austin Hemmelgarn