gpgp key request fails in dockerfile but not bash - linux

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.
I am behind a firewall; I have the proxy settings detailed below for this.
Host: CentOS 7.4; Docker version 17.09.0-ce, build afdb6d4
No environment variables for proxies are set for the account being used.
The Docker service has the environment variables for the proxies set according to Docker:
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 <tianon#debian.org>
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 <tianon#tianon.xyz>" 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 <tianon#tianon.xyz>
uid Tianon Gravi <tianon#debian.org>
uid Tianon Gravi <tianon#dockerproject.org>
uid Andrew Page (tianon) <andrew#infosiftr.com>
uid Andrew Page (tianon) <andrew#vitalroute.com>
uid Andrew Page (Tianon Gravi) <admwiggin#gmail.com>
uid Tianon Gravi (Andrew Page) <tianon#infosiftr.com>
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.

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.

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.

Related

unable to addsign for rpm

I generated
gpg --gen-key
and downloaded repo to create a local repository. I am trying to
rpm --addsign <path to rpm file>
Example:
rpm --addsign foo.rpm
foo.rpm:
error: Could not exec gpg: No such file or directory
when I checked:
# rpm --checksig foo.rpm
foo.rpm: digests SIGNATURES NOT OK
I am pretty sure that I have followed the procedure correctly, but not sure why is it showing this.
Can anyone suggest?
Regards,
Tayto
Something on your machine is non-standard.
You can put in your ~/.rpmmacros file:
%_signature gpg
%_gpg_path /home/foo/.gnupg
%_gpg_name Your Company
%_gpgbin /usr/bin/gpg2
%__gpg_sign_cmd %{__gpg} gpg --force-v3-sigs --batch --verbose --no-armor --passphrase-fd 3 --no-secmem-warning -u "%{_gpg_name}" -sbo %{__signature_filename} --digest-algo sha256 %{__plaintext_filename}'
You probably need only one of those lines. I would bet on %_gpg_path, but it can be any other, which needs to be altered.
And do not forget to:
rpm --import your.public.gpg
Otherwise --checksig will not work.

Signing rpm without passphrase

I am trying to disable having any password when I sign , or at least to send it with the signing command.
gpg --list-keys
/root/.gnupg/pubring.gpg
------------------------
pub 2048R/B40C2563 2017-04-11 [expires: 2022-04-10]
uid XXXXX <office#XXXX>
sub 2048R/42A9A452 2017-04-11 [expires: 2022-04-10]
I have gpg (GnuPG) 2.0.27 and libgcrypt 1.5.4
cat ~/.rpmmacros
%_signature gpg
%_gpg_path /root/.gnupg
%_gpg_name xxxxxxx
%_gpgbin /usr/bin/gpg2
%_no-protection
When I run ( rpm --addsign xxxxxxxxxx.rpm ) I am having popup for password
I found a solution with keygrip that is not working for me
gpg2 --with-keygrip
gpg: invalid option "--with-keygrip"
These are rpm options:
rpm --
--addsign --delsign --eval --help --initdb --query --rebuilddb --setugids --upgrade --version
--checksig --erase --freshen --import --install --querytags --setperms --showrc --verify
I was able to resolve it by adding --passphrase-file /path/to/passphrase-file under %__gpg_sign_cmd macro in .rpmmacros(or whatever you have) file.
Below is %__gpg_sign_cmd macro after modification:
%__gpg_sign_cmd %{__gpg} gpg --force-v3-sigs --batch --no-verbose --no-armor --passphrase-file /path/passphrase_file --no-secmem-warning -u %{_gpg_name} -sbo %{__signature_filename} --digest-algo sha256 %{__plaintext_filename}'
It is no possible. But many people use for unattended signing OBS-signd:
https://github.com/openSUSE/obs-sign
https://en.opensuse.org/openSUSE:Build_Service_Signer

Save passphrase for gpg or gpg2

There are answers I've found on Stack Overflow, Ask Ubuntu and Stack Exchange but none works for me.
I need to set up crontab in a Linux box with these:
$ lsb_release -a
Ubuntu 14.04.5 LTS
$ gpg --version
gpg (GnuPG) 1.4.16
$ gpg2 --version
gpg (GnuPG) 2.0.22
$ gpg-agent --version
gpg-agent (GnuPG) 2.0.22
I'm execute the bash command from Node.js
exec(`gpg --passphrase-file <path>passphrase.txt -d ${encryptedFile} > ${decryptedFile}`)
I need to set up the gpg/gpg2 command so it won't prompt for passphrase. I've tried these inside my exec():
gpg2 --batch --yes --no-tty
gpg --batch --yes
gpg2 --passphrase <passphrase>
with and without -d
const passphrase = fs.readFileSync(<passphrase-file>, (err, data)=>{})
`gpg --passphrase ${passphrase}...`
None of them works, even though:
$ gpg --import pubkey.txt
gpg: key ######: "Name <name#email>" not changed
gpg: Total number processed: 1
gpg: unchanged: 1
$ gpg --import privkey.txt
gpg: key ######: already in secret keyring
gpg: Total number processed: 1
gpg: secret keys read: 1
gpg: secret keys unchanged: 1
I've also added keys for gpg2.

gpg: Sorry, no terminal at all requested - can't get input

When decrypting I get following error:
$ eyaml decrypt -s 'ENC and the key goes on here'
.gnupg --quiet --no-secmem-warning --no-permission-warning --no-tty --yes --decrypt)
failed with: gpg: Sorry, no terminal at all requested - can't get input
I have checked my keys, everything is in order. At this point I am out of options.
If you configured Automatic Git commit signing with GPG on macOS and you see this error comment out no-tty in ~/.gnupg/gpg.conf as suggested by Fahl-Design.
This will also allow you to generate new GPG keys following the GitHub instructions for new keys.
You need to remove the option --no-tty
--no-tty
Make sure that the TTY (terminal) is never used for any output. This option is needed in some cases because GnuPG sometimes
prints warnings to the TTY even if --batch is used.
For those who are encountering this error from scripts that are running with no TTY available, adding --batch to the GPG command line, or batch to a line in ~/.gnupg/gpg.conf can make the problem go away.
I had to update my git email so that it matched the email on my gpg key and the primary email on my Github.
$ git config --global user.email "myemailaddress#gmail.com"

gpg decryption giving error in LINUX "can't query passphrase in batch mode"

Hi im using gpg to decrypt a file in linux, im using
shell_exec("gpg --batch --passphrase-file $passphrase_file -d $encrypted_file");
to decrypt the file, but im getting the following errors.
gpg: gpg-agent is not available in this session
gpg: can't query passphrase in batch mode
gpg: Invalid passphrase; please try again ...
gpg: can't query passphrase in batch mode
gpg: Invalid passphrase; please try again ...
gpg: can't query passphrase in batch mode
This error makes it appear that the commaand doesnt like to be run using shell_exec (similar to how sudo/ssh warns about needing a tyy when run with shell_exec)::
gpg: gpg-agent is not available in this session
What happens if u run it directly from the shell prompt?
Also, make sure your not in safe mode:
shell_exec() (functional equivalent of backticks)
This function is disabled when PHP is running in safe mode.
Check with phpinfo()
check that the function is not disabled:
$ grep 'disable_functions' /etc/php.ini
Edit:
Also, try using putenv to point GNUPGHOME to your .gnupg folder.
It could be that the php script is being run as the httpd user and the gpg is expecting the 'user' user for your site.
I ran into a similar problem calling gpg from cron.
The command works fine when run from the command line or from a shell script. Running the command from cron fails with the same errors you're getting.
Two resources I found were a good gpg cheetsheet
And this answer on serverfault
I was able to get it to work after generating a gpg key.
gpg --gen-key
And then encrypt with:
gpg -e -r name#domain.tld backup_file.tgz
In order to decrypt gpg encrypted files using relevant passphrase file and running it through an applicative context, use the following formula:
gpg --no-tty --no-use-agent --yes --passphrase-file <pass-phrase-file>
--output <decrypted-file-path> --decrypt <encrypted-file-path>
example:
$ cd /home/app/gpg_example
$ ls -la
-rwxr-xr-x 3 user root 1000 Jan 1 00:00 secret_passphrase.txt
-rwxr-xr-x 3 user root 7000 Jan 1 00:00 encrypted-file.tar.gpg
$ gpg --no-tty --no-use-agent --yes --passphrase-file secret_passphrase.txt
--output decrypted-file.tar --decrypt encrypted-file.tar.gpg
$ ls -la
-rwxr-xr-x 3 user root 1000 Jan 1 00:00 secret_passphrase.txt
-rwxr-xr-x 3 user root 7000 Jan 1 00:00 encrypted-file.tar.gpg
-rwxr-xr-x 3 user root 6970 Jan 1 00:00 decrypted-file.tar # <= that's decrypted file.

Resources