Reputation: 438
I have an issue in that my attempts to receive a gpg key fails when building my docker container. The command that I am providing works correctly when executed at the command line.
In /etc/systemd/system/docker.service.d/http-proxy.conf
:
[Service]
Environment="HTTP_PROXY=http://<corporate proxy>/" "HTTPS_PROXY="<corporate proxy>/" "NO_PROXY=localhost,127.0.0.1,.domain.local,.corp"
I use a build.sh
shell script to build the image:
#/bin/bash
docker build -t hgk/test-container .
The shell script is in the same location as my Dockerfile. These are the only two things in that directory.
FROM openjdk:8
ARG KEYSERV=hkp://p80.pool.sks-keyservers.net:80
ARG THEPROXY=<my corporate proxy>
# grab gosu for easy step-down from root
# (see docker-sonarqube pull request #115)
RUN set -x \
&& wget -e https_proxy=$THEPROXY -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.10/gosu-$(dpkg --print-architecture)" \
&& wget -e https_proxy=$THEPROXY-O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/1.10/gosu-$(dpkg --print-architecture).asc" \
&& export GNUPGHOME="$(mktemp -d)" \
&& gpg --version \
&& gpg -vv --keyserver $KEYSERV --keyserver-options http-proxy=$THEPROXY --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
&& gpg --list-keys \
&& gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \
&& rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc \
&& chmod +x /usr/local/bin/gosu \
&& gosu nobody true
The two wget commands work correctly and they retrieve the files. The first gpg command eventually times out:
+ mktemp -d
+ export GNUPGHOME=/tmp/tmp.LJ1EVFQmpO
+ gpg --version
gpg (GnuPG) 2.1.18
libgcrypt 1.7.6-beta
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Home: /tmp/tmp.LJlEVFQmpO
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
+ gpg -vv --keyserver hkp://p80.pool.sks-keyservers.net:80 --keyserver-options http-proxy=<corp proxy> --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4
gpg: keybox '/tmp/tmp.LJlEVFQmpO/pubring.kbx' created
gpg: no running Dirmngr - starting '/usr/bin/dirmngr'
gpg: waiting for the dirmngr to come up ... (5s)
gpg: connection to the dirmngr established
[[I am hung here - It just waits for ... something? I'll update the question if anything prints after this]]
I put the gpg --list-keys
command in the Dockerfile to see if we got past there. However, if I run it via the command line, it successfully retrieves the key:
[root@me foo]# printenv | grep proxy
[root@me foo]# gpg --keyserver hkp://p80.pool.sks-keyservers.net:80 --
keyserver-options http-proxy=<corp proxy> --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4
gpg: keyring `/root/.gnupg/pubring.gpg' created
gpg: requesting key BF357DD4 from hkp server p80.pool.sks-keyservers.net
Version: SKS 1.1.6
gpg: armor header:
Comment: Hostname: sks.okoyono.de
gpg: armor header:
gpg: pub 4096R/BF357DD4 2014-02-28 Tianon Gravi <[email protected]>
gpg: key BF357DD4: removed multiple subkey binding
gpg: key BF357DD4: removed multiple subkey binding
gpg: /tmp/tmp.DIX6yQQf25/trustdb.gpg: trustdb created
gpg: using PGP trust model
gpg: key BF357DD4: public key "Tianon Gravi <[email protected]>" imported
gpg: 1 keys cached (126 signatures)
gpg: 0 keys processed (0 validity counts cleared)
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
[root@me foo]# gpg --list-keys
/root/.gnupg/pubring.gpg
------------------------
pub 4096R/BF357DD4 2014-02-28 [expires: 2019-07-06]
uid Tianon Gravi <[email protected]>
uid Tianon Gravi <[email protected]>
uid Tianon Gravi <[email protected]>
uid Andrew Page (tianon) <[email protected]>
uid Andrew Page (tianon) <[email protected]>
uid Andrew Page (Tianon Gravi) <[email protected]>
uid Tianon Gravi (Andrew Page) <[email protected]>
sub 4096R/769826E6 2014-02-28 [expires: 2019-07-06]
I've tried different sks-keyservers (ubuntu, MIT, and other sks) with the same behavior - correct from bash, wrong from Docker.
Any thoughts/tips/suggestions?
Update: My "openjdk:8" version had not been updated in a while (since 8u121). I found I was running gpg v1.4.18. I did a docker image pull openjdk:8
which brought me up to 8u151 and gpg 2.1.18. The version of gpg on the CentOS 7 machine is 2.0.22.
Upvotes: 2
Views: 2548
Reputation: 38682
Your systemd unit file's environment variables are not passed into a container when building Docker images. Instead, make use of the --build-arg
parameter for passing the proxy values:
docker build --build-arg=HTTP_PROXY=http://<corporate proxy>/ --build-arg=HTTPS_PROXY=http://<corporate proxy>/ -t hgk/test-container .
You should not bake runtime options like proxy variables into the Dockerfile, always pass configuration through environment variables (or this build argument parameter).
Additional hint: most applications rely on http_proxy
and https_proxy
-- while most environment variables are indeed all-caps, the proxy variables have a more wide-spread lower-case usage.
Upvotes: 1
Reputation: 438
My solution to the problem (whether it is the right solution or not is up for debate) was to add the http_proxy
and https_proxy
environment variables to the Dockerfile.
FROM openjdk:8
ARG KEYSERV=hkp://p80.pool.sks-keyservers.net:80
ARG THEPROXY=<my corporate proxy>
ENV http_proxy $THEPROXY
ENV https_proxy $THEPROXY
# grab gosu for easy step-down from root
# (see docker-sonarqube pull request #115)
RUN set -x \
&& wget -e https_proxy=$THEPROXY -O /usr/local/bin/gosu
"https://github.com/tianon/gosu/releases/download/1.10/gosu-$(dpkg --print-architecture)" \
&& wget -e https_proxy=$THEPROXY-O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/1.10/gosu-$(dpkg --print-architecture).asc" \
&& export GNUPGHOME="$(mktemp -d)" \
&& gpg --version \
&& gpg -vv --keyserver $KEYSERV --keyserver-options http-proxy=$THEPROXY --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
&& gpg --list-keys \
&& gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \
&& rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc \
&& chmod +x /usr/local/bin/gosu \
&& gosu nobody true
My interpretation of this fix is that gpg
spins up dirmngr
. dirmngr "is a server for managing and downloading certificate revocation lists (CRLs) for X.509 certificates and for downloading the certificates themselves." This hints at some form of network connectivity being necessary. Reading the [dirmngr options][2] page, there is a --http-proxy
argument that does not seem to get passed to the startup arguments for dirmngr
.
Somehow, adding the http_proxy
to the environment allows dirmngr to do it's job successfully.
I'm not sure if this is a bug (there's an --honor-http-proxy
option that appears to be set to 0 by default in the gnupg source code, so I'm not sure why it's picking up the http_proxy
, but my solution is working and meets my needs. I'll try to read the source code a little more in detail this weekend, but this isn't a high priority any more for me and my team.
Upvotes: 0