Mailing List Archive

Why doesn't gpg-agent forwarding work?
Hi all,

I've tried to get this working to no avail. I've consulted past postings
to this list as well as various online references. Some people seem to
have got this to work, but most seem to have trouble. I would appreciate
any guidance or help anyone can offer.

I want my gpg-agent to be shared with another host, specifically a
Vagrant/VirtualBox virtual machine, via Unix socket forwarding, which is
a feature that arrived with OpenSSH 6.7. I can get my gpg-agent's socket
forwarded, and I can talk to it with gpg-connect-agent, and even obtain
a list of keygrips for the keys residing on the local machine. However,
the forwarded gpg-agent socket does not seem to interface with the GPG
CLI utility, i.e. running `gpg2 --use-agent --list-keys` shows nothing.

This is important because I'm in the process of developing a
deterministic build environment for a project, and many of us prefer to
use smartcards or YubiKeys, so copying our secret keys into the VM is
not an option. The ability to forward the local gpg-agent into the VM
for signing operations would be very convenient.

GPG version on host: 2.1.15 (Debian stretch)
GPG version on VM: 2.0.26 (Debian jessie)

This illustrates what I'm doing:

GPG_SOCK=$(echo "$GPG_AGENT_INFO" | cut -d: -f1)
vagrant ssh vm -- -t -A \
-R /home/vagrant/.gnupg/S.gpg-agent:$GPG_SOCK \
-o StreamLocalBindUnlink=yes \
-o ExitOnForwardFailure=yes

Setting some environment variables in the VM does not help:

GPG_AGENT_INFO=/home/vagrant/.gnupg/S.gpg-agent:0:1
GPG_SOCK=/home/vagrant/.gnupg/S.gpg-agent
GPG_TTY=/dev/pts/1

I've tried alternate/matching versions of GnuPG, pored over the manpages
and options, and tried other stuff, with no luck. Does anyone have any
idea why it is that gpg-connect-agent can speak to the forwarded socket
but not gpg? Has someone here got this working before?

thanks in advance,
Kevin
Re: Why doesn't gpg-agent forwarding work? [ In reply to ]
Hello Kevin,

> GPG version on host: 2.1.15 (Debian stretch)
> GPG version on VM: 2.0.26 (Debian jessie)

gpg 2.0.26 does the gpg operations local and not using gnupg-agent.
Starting with the 2.1.x versions gnupg uses gnupg-agent for doing all
operations. As a result you need to have 2.1.x on the remote machine. On
the local you could have actually run 2.0 however your private key if
not stored on a smartcard would be exposed using the remote socket. Find
attached a build script do build gnupg 2.1.x for Debian jessie. Try not
to replace gnupg in the system because it would break to many things.
Instead install it to a separate location.

Build dependencies are:

sudo apt-get install texinfo transfig bison flex libbz2-dev libsqlite3-dev libgnutls28-dev pkg-config libusb-1.0-0-dev

Cheers,
Thomas
Re: Why doesn't gpg-agent forwarding work? [ In reply to ]
Hey Thomas,

Thanks for the advice. But as I mentioned, I tried using GnuPG 2.1.15 on
the target machine as well (via the packages in Debian sid), and this
did not work. gpg2 is simply not speaking to the forwarded gpg-agent
socket, however gpg-connect-agent can. Any other ideas?

Kevin


On 10/16/2016 10:45 PM, Thomas Glanzmann wrote:
> Hello Kevin,
>
>> GPG version on host: 2.1.15 (Debian stretch)
>> GPG version on VM: 2.0.26 (Debian jessie)
> gpg 2.0.26 does the gpg operations local and not using gnupg-agent.
> Starting with the 2.1.x versions gnupg uses gnupg-agent for doing all
> operations. As a result you need to have 2.1.x on the remote machine. On
> the local you could have actually run 2.0 however your private key if
> not stored on a smartcard would be exposed using the remote socket. Find
> attached a build script do build gnupg 2.1.x for Debian jessie. Try not
> to replace gnupg in the system because it would break to many things.
> Instead install it to a separate location.
>
> Build dependencies are:
>
> sudo apt-get install texinfo transfig bison flex libbz2-dev libsqlite3-dev libgnutls28-dev pkg-config libusb-1.0-0-dev
>
> Cheers,
> Thomas
Re: Why doesn't gpg-agent forwarding work? [ In reply to ]
Hello Kevin,

> Thanks for the advice. But as I mentioned, I tried using GnuPG 2.1.15
> on the target machine as well (via the packages in Debian sid), and
> this did not work. gpg2 is simply not speaking to the forwarded
> gpg-agent socket, however gpg-connect-agent can. Any other ideas?

Check your configuration (gpg-agent.conf and gpg.conf). You have to put
this two files on the remote and local machine. Also Understand how gpg
2.1.x interacts with gnupg from the diagram below. Enable debugging in
the gpg agent.

Forward GPG socket
------------------
# On the server
echo 'StreamLocalBindUnlink yes' >> /etc/ssh/sshd_config
sudo /etc/init.d/ssh restart

# On the client
ssh -R /home/sithglan/.gnupg/S.gpg-agent:/home/sithglan/.gnupg/S.gpg-agent-extra gmvl.de

List secret keys
----------------
gpg-connect-agent "keyinfo --list" /bye

GPG Agent Configuration
-----------------------
.gnupg/gpg-agent.conf
pinentry-program /usr/bin/pinentry
extra-socket /home/sithglan/.gnupg/S.gpg-agent-extra
enable-ssh-support
default-cache-ttl 600
max-cache-ttl 7200
keep-tty
keep-display
# debug-level guru
# debug-all
# log-file /tmp/gpg-agent.log

Remote GPG Setup
----------------
# Achtung vorher Backup machen
rm .gnupg/secring* .gnupg/pubring* .gnupg/private-keys-v1.d/*
# For every public key
gpg2 --recv-key 0x9D106472D6D50DBA
gpg2 --recv-key 0x03BF970657E19B02

# After that private keys should be listed
gpg2 -K

cat <<EOF > .gnupg/gpg.conf
keyserver hkps://hkps.pool.sks-keyservers.net
keyserver-options no-honor-keyserver-url
cert-digest-algo SHA512
no-greeting
lock-once
default-key 1DD3BBDC897A94CD03F451B09D106472D6D50DBA
encrypt-to 1DD3BBDC897A94CD03F451B09D106472D6D50DBA
keyid-format 0xlong
use-agent
with-fingerprint
quiet
default-recipient-self
no-secmem-warning
keyserver-options auto-key-retrieve
no-auto-check-trustdb
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
EOF

GNUPG Interaction
-----------------

Here are steps and the interaction.

(1) here are the processes
[gpgme]----[gpg]====[gpg-agent]----[scdaemon]
^--- possibly by forwarded socket

(2) A client program (Mutt, in your case) asks decryption through gpgme
decrypt
[gpgme]--->[gpg]----[gpg-agent]----[scdaemon]

(3) it goes to scdaemon
decrypt
[gpgme]----[gpg]--->[gpg-agent]----[scdaemon]

decrypt
[gpgme]----[gpg]----[gpg-agent]--->[scdaemon]

(4) if the token is not authenticated yet,
scdaemon asks a user PIN back through gpg-agent
"PIN please"
[gpgme]----[gpg]----[gpg-agent]<---[scdaemon]


(5) Then, gpg-agent invokes pinentry.
[gpgme]----[gpg]----[gpg-agent]----[scdaemon]
|
[pinentry]<---/

(6) pinentry pops up GUI dialog window to user.
[gpgme]----[gpg]----[gpg-agent]----[scdaemon]
|
User <----[pinentry]----/

(7) User inputs PIN by the dialog.
[gpgme]----[gpg]----[gpg-agent]----[scdaemon]
|
User ---->[pinentry]----/
PIN

[gpgme]----[gpg]----[gpg-agent]----[scdaemon]
^
[pinentry]----/
PIN

PIN
[gpgme]----[gpg]----[gpg-agent]--->[scdaemon]

(8) scdaemon sends the pin to the token to authenticate.
PIN
[gpgme]----[gpg]----[gpg-agent]----[scdaemon]-->[token]

(9) Token is ready to decrypt, now.
scdaemon sends encrypted message to the token.
decrypt
[gpgme]----[gpg]----[gpg-agent]----[scdaemon]-->[token]

(10) token replies back by decrypted message.... to gpgme.
decrypted
[gpgme]----[gpg]----[gpg-agent]----[scdaemon]<--[token]

decrypted
[gpgme]----[gpg]----[gpg-agent]<---[scdaemon]

decrypted
[gpgme]----[gpg]<---[gpg-agent]----[scdaemon]

decrypted
[gpgme]<---[gpg]----[gpg-agent]----[scdaemon]

Cheers,
Thomas

_______________________________________________
Gnupg-users mailing list
Gnupg-users@gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-users
Re: Why doesn't gpg-agent forwarding work? [ In reply to ]
Hi Kevin,

Kevin Gallagher:
> Hi all,
>
> I've tried to get this working to no avail. I've consulted past postings
> to this list as well as various online references. Some people seem to
> have got this to work, but most seem to have trouble. I would appreciate
> any guidance or help anyone can offer.
>
> I want my gpg-agent to be shared with another host, specifically a
> Vagrant/VirtualBox virtual machine, via Unix socket forwarding, which is
> a feature that arrived with OpenSSH 6.7. I can get my gpg-agent's socket
> forwarded, and I can talk to it with gpg-connect-agent, and even obtain
> a list of keygrips for the keys residing on the local machine. However,
> the forwarded gpg-agent socket does not seem to interface with the GPG
> CLI utility, i.e. running `gpg2 --use-agent --list-keys` shows nothing.

Have you considered adding the debug flag to the command (--debug-level
expert)?
>
> This is important because I'm in the process of developing a
> deterministic build environment for a project, and many of us prefer to
> use smartcards or YubiKeys, so copying our secret keys into the VM is
> not an option. The ability to forward the local gpg-agent into the VM
> for signing operations would be very convenient.
>
> GPG version on host: 2.1.15 (Debian stretch)
> GPG version on VM: 2.0.26 (Debian jessie)

> Setting some environment variables in the VM does not help:
>
> GPG_AGENT_INFO=/home/vagrant/.gnupg/S.gpg-agent:0:1
> GPG_SOCK=/home/vagrant/.gnupg/S.gpg-agent
> GPG_TTY=/dev/pts/1

And if you'd try to add this to the VM's .bashrc file via ssh/scp
(assuming that the Vagrant's VM is headless and has a bash)

if [ -f "${HOME}/.gpg-agent-info" ]; then
. "${HOME}/.gpg-agent-info"
export GPG_AGENT_INFO
export SSH_AUTH_SOCK
export SSH_AGENT_PID
fi

Wouldn't that start the "target shell" (forcibly) with the agent being
fired up and all ready for sshing?

Cheers

Stephan
Re: Why doesn't gpg-agent forwarding work? [ In reply to ]
Hi, (update)

Stephan Beck:
> Hi Kevin,
>

>> Setting some environment variables in the VM does not help:
>>
>> GPG_AGENT_INFO=/home/vagrant/.gnupg/S.gpg-agent:0:1
>> GPG_SOCK=/home/vagrant/.gnupg/S.gpg-agent
>> GPG_TTY=/dev/pts/1
>
> And if you'd try to add this to the VM's .bashrc file via ssh/scp


No, positively not via ssh, as you reported that this, precisely, ssh
access is failing! So, just modifiying .bashrc manually.
> (assuming that the Vagrant's VM is headless and has a bash)
>
> if [ -f "${HOME}/.gpg-agent-info" ]; then
> . "${HOME}/.gpg-agent-info"
> export GPG_AGENT_INFO
> export SSH_AUTH_SOCK
> export SSH_AGENT_PID
> fi
>
> Wouldn't that start the "target shell" (forcibly) with the agent being
> fired up and all ready for sshing?
>
> Cheers
>
> Stephan
>
>
>
> _______________________________________________
> Gnupg-users mailing list
> Gnupg-users@gnupg.org
> http://lists.gnupg.org/mailman/listinfo/gnupg-users
>

_______________________________________________
Gnupg-users mailing list
Gnupg-users@gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-users
Re: Why doesn't gpg-agent forwarding work? [ In reply to ]
Ok, I figured out the cause of the problem I was having. As is indicated
in your message, one must have the corresponding public keys in the
remote keyring before the secret keys from the forwarded gpg-agent are
listed as available.

Thank you Thomas. I hope others will find this useful.


On 10/18/2016 12:58 PM, Thomas Glanzmann wrote:
> Hello Kevin,
>
>> Thanks for the advice. But as I mentioned, I tried using GnuPG 2.1.15
>> on the target machine as well (via the packages in Debian sid), and
>> this did not work. gpg2 is simply not speaking to the forwarded
>> gpg-agent socket, however gpg-connect-agent can. Any other ideas?
> Check your configuration (gpg-agent.conf and gpg.conf). You have to put
> this two files on the remote and local machine. Also Understand how gpg
> 2.1.x interacts with gnupg from the diagram below. Enable debugging in
> the gpg agent.
>
> Forward GPG socket
> ------------------
> # On the server
> echo 'StreamLocalBindUnlink yes' >> /etc/ssh/sshd_config
> sudo /etc/init.d/ssh restart
>
> # On the client
> ssh -R /home/sithglan/.gnupg/S.gpg-agent:/home/sithglan/.gnupg/S.gpg-agent-extra gmvl.de
>
> List secret keys
> ----------------
> gpg-connect-agent "keyinfo --list" /bye
>
> GPG Agent Configuration
> -----------------------
> .gnupg/gpg-agent.conf
> pinentry-program /usr/bin/pinentry
> extra-socket /home/sithglan/.gnupg/S.gpg-agent-extra
> enable-ssh-support
> default-cache-ttl 600
> max-cache-ttl 7200
> keep-tty
> keep-display
> # debug-level guru
> # debug-all
> # log-file /tmp/gpg-agent.log
>
> Remote GPG Setup
> ----------------
> # Achtung vorher Backup machen
> rm .gnupg/secring* .gnupg/pubring* .gnupg/private-keys-v1.d/*
> # For every public key
> gpg2 --recv-key 0x9D106472D6D50DBA
> gpg2 --recv-key 0x03BF970657E19B02
>
> # After that private keys should be listed
> gpg2 -K
>
> cat <<EOF > .gnupg/gpg.conf
> keyserver hkps://hkps.pool.sks-keyservers.net
> keyserver-options no-honor-keyserver-url
> cert-digest-algo SHA512
> no-greeting
> lock-once
> default-key 1DD3BBDC897A94CD03F451B09D106472D6D50DBA
> encrypt-to 1DD3BBDC897A94CD03F451B09D106472D6D50DBA
> keyid-format 0xlong
> use-agent
> with-fingerprint
> quiet
> default-recipient-self
> no-secmem-warning
> keyserver-options auto-key-retrieve
> no-auto-check-trustdb
> default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
> EOF
>
> GNUPG Interaction
> -----------------
>
> Here are steps and the interaction.
>
> (1) here are the processes
> [gpgme]----[gpg]====[gpg-agent]----[scdaemon]
> ^--- possibly by forwarded socket
>
> (2) A client program (Mutt, in your case) asks decryption through gpgme
> decrypt
> [gpgme]--->[gpg]----[gpg-agent]----[scdaemon]
>
> (3) it goes to scdaemon
> decrypt
> [gpgme]----[gpg]--->[gpg-agent]----[scdaemon]
>
> decrypt
> [gpgme]----[gpg]----[gpg-agent]--->[scdaemon]
>
> (4) if the token is not authenticated yet,
> scdaemon asks a user PIN back through gpg-agent
> "PIN please"
> [gpgme]----[gpg]----[gpg-agent]<---[scdaemon]
>
>
> (5) Then, gpg-agent invokes pinentry.
> [gpgme]----[gpg]----[gpg-agent]----[scdaemon]
> |
> [pinentry]<---/
>
> (6) pinentry pops up GUI dialog window to user.
> [gpgme]----[gpg]----[gpg-agent]----[scdaemon]
> |
> User <----[pinentry]----/
>
> (7) User inputs PIN by the dialog.
> [gpgme]----[gpg]----[gpg-agent]----[scdaemon]
> |
> User ---->[pinentry]----/
> PIN
>
> [gpgme]----[gpg]----[gpg-agent]----[scdaemon]
> ^
> [pinentry]----/
> PIN
>
> PIN
> [gpgme]----[gpg]----[gpg-agent]--->[scdaemon]
>
> (8) scdaemon sends the pin to the token to authenticate.
> PIN
> [gpgme]----[gpg]----[gpg-agent]----[scdaemon]-->[token]
>
> (9) Token is ready to decrypt, now.
> scdaemon sends encrypted message to the token.
> decrypt
> [gpgme]----[gpg]----[gpg-agent]----[scdaemon]-->[token]
>
> (10) token replies back by decrypted message.... to gpgme.
> decrypted
> [gpgme]----[gpg]----[gpg-agent]----[scdaemon]<--[token]
>
> decrypted
> [gpgme]----[gpg]----[gpg-agent]<---[scdaemon]
>
> decrypted
> [gpgme]----[gpg]<---[gpg-agent]----[scdaemon]
>
> decrypted
> [gpgme]<---[gpg]----[gpg-agent]----[scdaemon]
>
> Cheers,
> Thomas