amazon-web-services - AWS 上 Dockerfile 中的一些 GPG 命令突然失败

标签 amazon-web-services docker gnupg apache-tomee gpg-agent

我们有以下 Dockerfile(我已经删除了不必要的部分),我们已经使用它一年多了,突然,当它到达 gpg --batch --verify... 步骤构建在 CodeBuild 期间挂起并最终超时。这几天我一直在研究,但找不到任何相关内容。

FROM amazoncorretto:11-alpine-jdk

ENV PATH /usr/local/tomee/bin:$PATH
RUN mkdir -p /usr/local/tomee
ENV TZ America/New_York

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ /etc/timezone
WORKDIR /usr/local/tomee

# add the things we need to build the image 
RUN apk update \
    &&  apk add sudo \
    &&  apk add tar \
    &&  apk add gpg \
    &&  apk add curl \
    &&  apk add gpg-agent \
    &&  apk add bash
# add the users and sudo for Lacework
RUN adduser -S tomee
RUN addgroup tomee \
    && addgroup tomee tomee
RUN addgroup sudo \
    && addgroup tomee sudo
    
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

# download and import the GPG keys
RUN set -x \
    && curl -fsSL 'https://www.apache.org/dist/tomee/KEYS' -o GPG_KEYS | awk -F ' = ' '$1 ~ /^ +Key fingerprint$/ { gsub(" ", "", $2); print $2 }' | sort -u \
    && gpg --import GPG_KEYS

# verify keys
RUN set -xe \
    && for key in $GPG_KEYS; do \
        gpg --batch --keyserver hkp://keyserver.ubuntu.com --recv-keys "$key" || \
        gpg --batch --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys "$key" ; \
    done

# TOMEE variables
# Apache changes the version from time to time and removes the old version.
# When they do that, you have to go to https://dist.apache.org/repos/dist/release/tomee/ to what see version is available
# then match that here
ENV TOMEE_VER 8.0.15
ENV TOMEE_BUILD webprofile

# set up Apache/TOMEE
RUN set -x \
    && curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-${TOMEE_VER}/apache-tomee-${TOMEE_VER}-${TOMEE_BUILD}.tar.gz.asc -o tomee.tar.gz.asc \
    && curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-${TOMEE_VER}/apache-tomee-${TOMEE_VER}-${TOMEE_BUILD}.tar.gz -o tomee.tar.gz \
    && echo "verifying gpg signature" \
    && gpg --list-keys \
    && gpg --batch --verify tomee.tar.gz.asc tomee.tar.gz \
    && tar -zxf tomee.tar.gz \
    && mv apache-tomee-${TOMEE_BUILD}-${TOMEE_VER}/* /usr/local/tomee \
    && rm -Rf apache-tomee-${TOMEE_BUILD}-${TOMEE_VER} \
    && rm -Rf /usr/local/tomee/webapps/docs \
    && rm bin/*.bat \
    && rm tomee.tar.gz* \
    && chown -R tomee:tomee /usr/local/tomee 

# put everything in the right place with the correct permissions
COPY $PWD/server.xml /usr/local/tomee/conf/
RUN chown -R tomee:tomee /usr/local/tomee/conf
COPY $PWD/target/application/META-INF/ /usr/local/tomee/webapps/ROOT/META-INF/
COPY $PWD/target/application/WEB-INF/ /usr/local/tomee/webapps/ROOT/WEB-INF/
COPY $PWD/target/application.war /usr/local/tomee/webapps/ROOT.war
RUN chown -R tomee:tomee /usr/local/tomee/webapps/

USER tomee
EXPOSE 8080
CMD ["catalina.sh", "run"]

为了复制这一点,我设置了一个 EC2 实例并在该实例上安装了 Docker。这是构建挂起的位置:

+ curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-8.0.15/apache-tomee-8.0.15-webprofile.tar.gz.asc -o tomee.tar.gz.asc
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   833  100   833    0     0  17455      0 --:--:-- --:--:-- --:--:-- 17723
+ curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-8.0.15/apache-tomee-8.0.15-webprofile.tar.gz -o tomee.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 47.4M  100 47.4M    0     0   118M      0 --:--:-- --:--:-- --:--:--  118M
+ echo 'verifying gpg signature'
verifying gpg signature
+ gpg --batch --verify tomee.tar.gz.asc tomee.tar.gz
gpg: Signature made Mon May  8 12:36:19 2023 UTC
gpg:                using RSA key B83D15E72253ED1104EB4FBBDAB472F0E5B8A431

如果我注释掉批量验证,则构建成功完成。

REPOSITORY       TAG             IMAGE ID       CREATED          SIZE
gpg-test         latest          1aead64a5120   12 seconds ago   350MB
amazoncorretto   11-alpine-jdk   60ba21c1871e   2 weeks ago      274MB

现在我可以运行该图像了。当我猛击图像时,我可以看到 GPG_KEYS 文件,因此我运行导入:

gpg --导入 GPG_KEYS

工作正常,所以我下载了 Apache-Tomee:

curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-8.0.15/apache-tomee-8.0.15-webprofile.tar.gz.asc -o tomee.tar.gz.asc
curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-8.0.15/apache-tomee-8.0.15-webprofile.tar.gz -o tomee.tar.gz

所以容器现在有了文件,我手动运行批量验证命令并成功完成:

5ab9673fdbe2:/usr/local/tomee$ gpg --batch --verify tomee.tar.gz.asc tomee.tar.gz
gpg: Signature made Mon May  8 12:36:19 2023 UTC
gpg:                using RSA key B83D15E72253ED1104EB4FBBDAB472F0E5B8A431
gpg: Good signature from "Richard Zowalla (Code Signing Key) <<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="77050d184637160716141f1259180510" rel="noreferrer noopener nofollow">[email protected]</a>>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: B83D 15E7 2253 ED11 04EB  4FBB DAB4 72F0 E5B8 A431

为什么gpg --batch --verify tomee.tar.gz.asc tomee.tar.gz在构建镜像期间失败?

顺便说一句:我们的一位开发人员正在运行 Docker Desktop,他的构建过程在完全相同的位置挂起。其他使用 Lima ( https://itnext.io/replace-docker-desktop-with-lima-88ec6f9d6a19 ) 构建镜像的人没有遇到这个问题,因此我相信 Docker 生态系统中的某些东西导致了问题。

我错过了什么明显的事情吗?

更新

我将 gpg --list-keys 添加到 Dockerfile 中批处理验证行的正上方,并且它卡在 list-keys 命令处。所有其他 GPG 命令在此之前均有效。

我将 -v 添加到列表键命令中,我得到以下内容:

verifying gpg signature
+ gpg --list-keys -v
gpg: enabled compatibility flags:
gpg: using pgp trust model
gpg: no running keyboxd - starting '/usr/libexec/keyboxd'
gpg: waiting for the keyboxd to come up ... (5s)

更新 我通过在任何 GPG 命令之前添加 && export GNUPGHOME="$(mktemp -d)"\ 解决了 keyboxd 问题。

我相信我已将问题隔离到这一行:

&& gpg --导入 GPG_KEYS

导入发生,但是当我尝试循环访问 key 时,没有 $GPG_KEYS 环境变量,因此没有可用的公钥。您可以在这里看到 OP 实际上在 Dockerfile 中列出了关键列表,但这对我来说似乎效率低下。 Running TomEE API in Docker container successful, but reverse proxy returns a 404

另一个更新 我今天对此进行了相当多的摆弄,终于能够干净地将 GPG key 导出到 ENV 变量,如下所示:

+ export 'GPG_KEYS=/tmp/tmp.hoJlmJ/pubring.kbx
---------------------------
pub   dsa1024 2006-01-05 [SC]
      9056B710F1E332780DE7AF34CBAEBE39A46C4CA1
uid           [ unknown] Some Dude <<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="afdcc0c2cacbdacbcaefcedfceccc7ca81c0ddc8" rel="noreferrer noopener nofollow">[email protected]</a>>
sub   elg2048 2006-01-05 [E]

pub   rsa2048 2014-01-21 [SC]
      F067B8140F5DD80E1D3B5D92318242FE9A0B1183
uid           [ unknown] Another Dude <<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="82e3ecedf6eae7f0e6f7e6e7e9c2e3f2e3e1eae7acedf0e5" rel="noreferrer noopener nofollow">[email protected]</a>>
sub   rsa2048 2014-01-21 [E]

...and so on

在镜像构建中运行 printenv 显示 key

+ printenv
HOSTNAME=756af5d791b0
SHLVL=1
HOME=/root
GPG_KEYS=/tmp/tmp.hoJlmJ/pubring.kbx
---------------------------
pub   dsa1024 2006-01-05 [SC]
      9056B710F1E332780DE7AF34CBAEBE39A46C4CA1
uid           [ unknown] Some Dude <<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7e0d11131b1a0b1a1b3e1f0e1f1d161b50110c19" rel="noreferrer noopener nofollow">[email protected]</a>>
sub   elg2048 2006-01-05 [E]

pub   rsa2048 2014-01-21 [SC]
      F067B8140F5DD80E1D3B5D92318242FE9A0B1183
uid           [ unknown] Another Dude <<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1c7d72736874796e78697879775c7d6c7d7f747932736e7b" rel="noreferrer noopener nofollow">[email protected]</a>>
sub   rsa2048 2014-01-21 [E]

...and so on

当我手动运行下一个命令时,它起作用了。但是在 Dockerfile 中运行它失败(我们应该看到输出)

Step 13/21 : RUN set -xe && for key in $GPG_KEYS; do  gpg -v --batch --keyserver hkp://keyserver.ubuntu.com --recv-keys "$key" ; done

不存在我期望的 --keyserver 命令的输出。

最佳答案

我们继续研究并向 AWS 提出支持请求(未得到答复),以了解 GPG 在 CodeBuild 中的 Dockerfile 中开始失败的原因。

所有提到的测试都得出一个结论,GPG 调用可以从 EC2 实例上的命令行以及该实例上的 Docker 容器内正常工作。鉴于此,我们将所有 GPG 命令移至 bash 文件,然后在 Dockerfile 中调用该文件:

gpg-verify.sh

#!/bin/bash

# download and import the GPG keys

export GNUPGHOME="$(mktemp -d)" 
curl -fsSL 'https://www.apache.org/dist/tomee/KEYS' -o GPG_KEYS | awk -F ' = ' '$1 ~ /^ +Key fingerprint$/ { gsub(" ", "", $2); print $2 }' | sort -u 
gpg --batch --import GPG_KEYS
export GPG_KEYS="$(gpg --list-keys)"
printenv 

# verify keys

for key in $GPG_KEYS; do
    gpg -v --batch --keyserver hkp://keyserver.ubuntu.com --recv-keys "$key" ; 
done

# set up Apache/TOMEE

curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-${TOMEE_VER}/apache-tomee-${TOMEE_VER}-${TOMEE_BUILD}.tar.gz.asc -o tomee.tar.gz.asc
curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-${TOMEE_VER}/apache-tomee-${TOMEE_VER}-${TOMEE_BUILD}.tar.gz -o tomee.tar.gz
gpg --list-keys -v
gpg -v --batch --verify tomee.tar.gz.asc tomee.tar.gz

更新的 Dockerfile:

FROM amazoncorretto:11-alpine-jdk

ENV PATH /usr/local/tomee/bin:$PATH
RUN mkdir -p /usr/local/tomee
ENV TZ America/New_York

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ /etc/timezone
WORKDIR /usr/local/tomee

# add the things we need to build the image 
RUN apk update \
    &&  apk add sudo \
    &&  apk add tar \
    &&  apk add gnupg \
    &&  apk add curl \
    &&  apk add gpg-agent \
    &&  apk add bash \
    &&  apk add  ca-certificates
# add the users and sudo for Lacework
RUN adduser -S tomee
RUN addgroup tomee \
    && addgroup tomee tomee
RUN addgroup sudo \
    && addgroup tomee sudo
    
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

# TOMEE variables
# Apache changes the version from time to time and removes the old version.
# When they do that, you have to go to https://dist.apache.org/repos/dist/release/tomee/ to what see version is available
# then match that here
ENV TOMEE_VER 8.0.15
ENV TOMEE_BUILD webprofile

# GPG Verification / TOMEE Download
COPY $PWD/gpg-verify.sh .
RUN ./gpg-verify.sh

RUN set -x \
    && tar -zxf tomee.tar.gz \
    && mv apache-tomee-${TOMEE_BUILD}-${TOMEE_VER}/* /usr/local/tomee \
    && rm -Rf apache-tomee-${TOMEE_BUILD}-${TOMEE_VER} \
    && rm -Rf /usr/local/tomee/webapps/docs \
    && rm bin/*.bat \
    && rm tomee.tar.gz* \
    && chown -R tomee:tomee /usr/local/tomee 

# put everything in the right place with the correct permissions
#COPY $PWD/server.xml /usr/local/tomee/conf/
RUN chown -R tomee:tomee /usr/local/tomee/conf
#COPY $PWD/target/application/META-INF/ /usr/local/tomee/webapps/ROOT/META-INF/
#COPY $PWD/target/application/WEB-INF/ /usr/local/tomee/webapps/ROOT/WEB-INF/
#COPY $PWD/target/application.war /usr/local/tomee/webapps/ROOT.war
RUN chown -R tomee:tomee /usr/local/tomee/webapps/

USER tomee
EXPOSE 8080
CMD ["catalina.sh", "run"]
当然,这似乎非常违反直觉,因为 bash 命令与 Dockerfile 中运行的命令相同。然而,这正如我们所期望的那样。

附注我们已向 AWS 询问了可能导致 GPG 问题的更改,并将在收到答复后进行更新。

关于amazon-web-services - AWS 上 Dockerfile 中的一些 GPG 命令突然失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76823249/

相关文章:

amazon-web-services - 为什么 grails websockets 连接失败,但在使用 AWS ELB 时继续接收浏览器中已订阅的消息?

python - 写入dockerized MongoDB时出错

Scala解密OpenPGP(GPG)加密文件

c# - 命令行 GPG 使用 c# 解密 - 密码?

javascript - AWS Lambda 函数多次处理相同的 dynamodb 流。我错过了什么?

amazon-web-services - Cloudformation ECS集群

amazon-web-services - Aws Elasticbeanstalk cron.yaml 工作线程问题

php - 如何调试安装到在 docker beta for mac 上运行的容器的 php

angular - EACCES 权限被拒绝在 docker 中进行 angular cli ng 构建

c# - GNUPG:在删除公钥时抑制消息