ROS公钥服务器接收失败的核心结论与修复路径
ROS从公钥服务器接收失败的根本原因是APT在验证ROS软件源签名时,无法从Ubuntu密钥服务器或ROS官方密钥地址拉取对应GPG公钥,常见于网络不可达、密钥地址变更或代理配置缺失,优先使用官方提供的raw.githubusercontent.com/ros/rosdistro/master/ros.key地址重新导入,并配置[signed-by]方式替代已弃用的apt-key。
先确认报错类型,别急着改源
很多用户在终端执行sudo apt update时看到类似提示:The following signatures couldn't be verified because the public key is not available: NO_PUBKEY F42ED6FBAB17C654,这条报错并不代表ROS源地址写错了,而是APT缺少对应公钥,另一种常见情况是gpg: keyserver receive failed: Connection refused,说明访问密钥服务器(如keyserver.ubuntu.com)的网络链路被中断。
业内专家指出,公钥接收失败在三个场景里最集中:一是新装Ubuntu后按旧版教程操作,教程里的密钥地址已过期;二是企业内网或校园网限制了对keyserver.ubuntu.com的访问;三是国内网络访问GitHub原始文件地址不稳定,先对号入座,能省掉大量试错时间。
ROS公钥服务器接收失败怎么解决的完整操作链
用官方key文件走curl + gpg导入
这是目前最稳妥的路径,不依赖密钥服务器端口。
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
随后确认sources.list.d里的ROS源行带有[signed-by=/usr/share/keyrings/ros-archive-keyring.gpg]参数,示例:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
执行sudo apt update验证,若不再出现NO_PUBKEY即修复完成。关键点在于把公钥文件直接落到/usr/share/keyrings/,并让源条目显式指向它,绕开密钥服务器环节。
指定Ubuntu密钥服务器手动拉取
当方案一因网络原因失败时,可以换一个keyserver再试:
sudo gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-key F42ED6FBAB17C654 sudo gpg --export F42ED6FBAB17C654 | sudo tee /usr/share/keyrings/ros-archive-keyring.gpg > /dev/null
如果keyserver.ubuntu.com持续超时,可替换为hkp://pgp.mit.edu或hkp://keys.openpgp.org,注意端口80比默认的11371更容易穿过防火墙,近年来不少高校网络对高位端口限制更严,改用80端口成功率明显提升。
配置APT代理或切换镜像源
内网环境需要给APT单独设代理:
sudo sh -c 'echo "Acquire::http::Proxy \"http://your-proxy:port\";" > /etc/apt/apt.conf.d/95proxy'
若只是访问GitHub不稳,可以将ROS源替换为国内镜像(如清华、中科大镜像站),再配合镜像站文档给出的key文件地址导入。镜像源不改变签名验证逻辑,公钥仍需正确落地,否则同样报错。
国内ROS公钥服务器连接失败的场景差异
不同网络环境的表现差别很大,下面这张表可作为排查参照:
| 场景 | 典型报错 | 优先方案 | 备注 |
|---|---|---|---|
| 家庭宽带直连 | Connection timed out |
方案一(raw文件) | GitHub地址偶发不通 |
| 校园网/企业内网 | Connection refused |
方案三(代理)+方案一 | 密钥服务器端口常被拦 |
| Docker容器内 | NO_PUBKEY |
方案二(80端口keyserver) | 容器缺CA证书也会失败 |
| 旧教程遗留源 | 签名不匹配 | 清理旧源+方案一 | 密钥ID可能已轮换 |
近年来,ROS 2的apt源逐步统一使用ros-archive-keyring.gpg这一命名,旧教程里的apt-key add写法在Ubuntu 22.04之后虽然还能执行,但会触发弃用警告,行业共识认为,signed-by方式是新版Ubuntu下更规范的做法,迁移时应同步更新。
修复后如何确认公钥真的生效
别只看apt update有没有报错,建议做两步验证:
- 执行
apt-key list(旧系统)或gpg --show-keys /usr/share/keyrings/ros-archive-keyring.gpg,确认输出里包含F42ED6FBAB17C654或ROS对应的新密钥指纹。 - 执行
apt-cache policy ros-<distro>-desktop,若能列出候选版本,说明源与签名链路都已打通。 - 检查
/etc/apt/sources.list.d/下是否残留重复的ROS源条目,重复条目会引发签名冲突的假象。
把公钥文件路径写死在源条目里,比依赖全局信任环更可控,也便于后续换机器复现。
提前规避ROS GPG密钥接收失败的三个习惯
- 安装前先核对官方文档给出的密钥地址,不要照搬两年前博客里的
apt-key adv命令。 - 在容器或CI环境里,把
curl下载key文件这一步写进Dockerfile,避免每次构建都依赖外部密钥服务器。 - 保留一份
ros-archive-keyring.gpg离线副本,内网批量部署时直接分发,比逐台联网拉取稳定得多。
关于ROS公钥接收失败的常见疑问
ROS公钥服务器接收失败和ROS版本有关系吗
有关系,ROS 1与ROS 2的源地址和密钥文件路径不同,ROS 2在Humble及之后版本普遍使用ros-archive-keyring.gpg命名,混用两套教程里的密钥ID会直接导致NO_PUBKEY,安装前先确认发行版代号与源条目是否匹配。
执行apt update仍然报NO_PUBKEY但公钥文件已存在怎么办
先检查源条目是否带[signed-by=...]并指向正确路径;若路径拼写无误,用gpg --show-keys确认文件内容非空,空文件通常由curl被重定向到登录页导致,重新下载并检查文件大小即可定位。
ROS公钥导入失败需要重装系统吗
绝大多数情况不需要,公钥问题属于APT签名验证层面的配置问题,清理/etc/apt/sources.list.d/中残留条目、重新导入key文件、修正signed-by参数即可恢复,重装系统对网络限制类问题并无帮助,反而会重复踩坑。
把公钥文件落到/usr/share/keyrings/并在源条目里显式引用,是当前Ubuntu环境下处理ROS公钥接收失败最可复现的路径。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/792264.html


