我gpg
在 DockerDebian:latest
自动构建中使用,并且gpg
在终端中它可以工作,但是当我在脚本中使用时,无论我做什么,它要求输入密码,我确实喜欢这个:
passphrase=$(cat /build/secure/passphrase.txt)
echo $passphrase | gpg --passphrase-fd 0 --import /build/secure/gpg/secret-signing-key.pgp
但如果我在终端上这样做,它就可以工作!
为什么?怎么会这样?
答案1
GnuPG 2gpg-agent
和 Loopback Pinentry
GnuPG 2.0 及更新版本仅在应用--passphrase-...
时才考虑 -options 。来自:--batch
man gpg
--batch
请注意,仅当给出了选项时才使用此密码。这与 GnuPG 版本 1.x 不同。
因此 GnuPG 2.0 的有效命令是:
gpg --batch --passphrase-fd 0 --import <path>
此外,自 GnuPG 2.1 起,gpg-agent
它处理所有密钥操作并要求输入密码。其背后的想法是让一个小的核心应用程序处理加密的最关键部分,并让(相对)较大的 GnuPG 应用程序(可能存在更多错误和安全问题)处理所有其他工作。默认情况下,gpg-agent
不会查询gpg
密码,而是尝试直接询问用户(这在无人值守的构建中显然会失败)。不过,还有最后一个解决方法:您可以使用--pinentry-mode loopback
查询gpg-agent
密码gpg
,但由于这会影响安全性(如前所述),您还必须配置gpg-agent
以允许回送 pinentry。
添加以下行~/.gnupg/gpg-agent.conf
:
allow-loopback-pinentry
现在,您应该能够在 GnuPG 2.1 及更新版本中使用以下命令:
gpg --batch --pinentry-mode loopback --passphrase-fd 0 --import <path>
传递gpg-agent
套接字
比将私钥导入 Docker 容器更好的选择通常是将私钥存储(并解锁)在主机上,然后将套接字传递gpg-agent
到 Docker 容器中。这样,关键机密就永远不会进入 Docker 容器,而且您可以非常确定它不会被存储在镜像层中并被意外发布。