docker - 如何处理临时 apt-key adv 故障?

标签 docker debian gnupg apt openpgp

我有一个 dockerfile 可以动态添加 OpenPGP key 。问题是 key 服务器 hkp://pgp.mit.edu:80 不时无法响应。我能做些什么来避免这种浪费时间的失败?

最佳答案

问题

经常使用的 key 服务器 pool.sks-keyserver.net 实际上不是单个服务器,而是整个 key 服务器池,您可以通过 DNS 随机选择其中的 key 服务器。它们彼此同步,并且由于服务器数量庞大,您可以假设其中任何一个都可用。但并非所有服务器都非常稳定,许多服务器是由个人提供的,甚至在家里运行。如果服务器非常可靠,则选择一个固定的服务器(您引用的 MIT 的服务器),但通常关键服务器会不时宕机。
keys.gnupg.net 实际上指向 pool.sks-keyservers.net(更具体地说,设置了一个 CNAME 记录)。

尽管每次查询池时都会返回一大堆服务器,但 GnuPG 只会选择其中一个。如果服务器没有响应,GnuPG 只会失败,而不是尝试另一个(甚至并行尝试多个)。

可能的解决方案

所有这些解决方案都试图要么不查询关键服务器网络,要么处理网络稳定性降低的问题。

  • 将 key 的本地副本添加到存储库

    这是我在重新设计 Dockerfile 时选择的方式。我将签名 key 的最小副本添加到保存 Dockerfile 的 git 存储库,然后将其导入到镜像中。我写的 prosody Dockerfile 的一个例子:
    COPY 107D65A0A148C237FDF00AB47393D7E674D9DBB5.gpg /root
    RUN apt-key add /root/107D65A0A148C237FDF00AB47393D7E674D9DBB5.gpg && \
        echo deb http://packages.prosody.im/debian jessie main >>/etc/apt/sources.list && \
        apt-get update
    

    这种策略的优点是不依赖任何外部资源,也不会拉取所有可能严重放大图像的签名(如果有很多签名,OpenPGP key 可以很容易地增长到多个 MB)。无论如何,如果您在带外验证 key 并添加经过验证的 key (实际上,使用其指纹从 key 服务器网络中提取 key 并没有太大区别,无论如何,您都不需要签名)。一个可能的缺点是您将无法获取撤销,因此请注意 key 、邮件列表、安全通知,...在极少数情况下, key 被泄露并随后被撤销。
  • 从存储库服务器获取

    如果您从存储库服务器拉取 key (假设他们提供下载),您也可以直接从那里拉取。与存储本地副本相比,我看不到任何相关优势。你必须确保你拉的是正确的 key (即验证指纹)。如果服务器受到威胁(并且上传了被操纵的包),他们将能够以任何方式操纵 key (即,取消撤销证书)。
  • 使用特定的 key 服务器

    如果你知道一个特定的、非常可靠的 key 服务器,你总是可以通过 --keyserver 选项选择一个固定的服务器。例如,如果您希望 Ubuntu 的服务器 super 稳定(或托管您自己的服务器,但请确保将其包含在 key 服务器网络中),请考虑选择此服务器。
  • 重试。

    重试获取 key ,直到成功。其中一台服务器肯定没问题。缺点:构建镜像在构建时间方面更加不稳定,网络故障将导致无限循环(除非您添加一些最大重试次数)。你必须自己编写脚本。
  • 选择高可用池

    ha.pool.sks-keyservers.net ,它要求包含的服务器是高度可用的集群设置。如果反向代理/负载均衡器关闭,您无论如何都会卡住;但预计普遍可用性会比通常的 pool.sks-keyservers.net 高得多。如果人们关心提供集群设置,他们可能正在正确监控他们的系统。

    如果您想坚持使用关键服务器网络,这可能是最好的方法。将本地副本与此池混合(并回退到本地副本)也可能是可行的,这提供了很高的机会来捕获已撤销 key 的罕见事件,同时仍然不会因 key 服务器不时超时而导致构建失败。
  • 关于docker - 如何处理临时 apt-key adv 故障?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37952031/

    相关文章:

    docker - Bluemix 无法连接或 ping 到容器

    php - GPG 错误代码 2

    powershell - gpg with powershell - 密码安全

    centos - 无法在 Docker centos 镜像中以普通用户身份 ping

    docker - 在docker中,如何关闭dockerfile暴露的端口?

    r - future 的解决方案

    linux - 如何将 SQLite3 数据库更改刷新到磁盘?

    linux - sudo apt-get install -f 从 debian 中删除了所有软件包

    Golang pgp 无需加密

    shell - 如何使用端口号删除Docker容器