drduh / YubiKey-Guide

Guide to using YubiKey for GnuPG and SSH

Home Page:http://drduh.github.io/YubiKey-Guide/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Agent Forwarding

cboettig opened this issue · comments

This is a fantastic guide, thanks!

The only area that I couldn't successfully follow was regarding the configuration in the section on agent forwarding to use my gpg (and ssh authentication) on remote machines. IIUC, your guide suggests this should work merely by including the -A flag in the ssh command. Following the gpg wiki I found I had to look up my local extra socket, gpgconf --list-dirs agent-extra-socket, look up my remote socket, gpgconf --list-dirs agent-socket, and add RemoteForward <remote socket> <extra-socket> to my ~/.ssh/config, and also add extra-socket (and fix my pinentry-program line) in ~/.gnupg/gpg-agent.conf. On the remote host, I had to import my public key first, and add StreamLocalBindUnlink yes in /etc/ssh/sshd_config and re-load the config (something you cover in the previous section but seemingly only for some Windows-only tool). After that I could decrypt from a remote host.

Not sure if there is a way to get this to work without needing root access on the remote machine.
(In my experiment I also needed to reboot the remote machine first, though probably that could be avoided by using some appropriate service reload commands.... Also would need further steps to enable the ssh from the remote machine, probably similar to what you already document for the local machine(?)

Is there a better way than the above, e.g. that lets you get this to work with just ForwardAgent yes and not mucking around for sockets? Is this something you would consider extending in the guide, or would entertain a PR for?

Just a follow-up on this that while following the above steps (i.e. setting socket with RemoteForward instead ofForwardAgent) I can decrypt from the remote machine, I have not actually managed to get ssh forwarding to work from the remote machine (error suggests it cannot find an id_rsa key, which it is looking for on the remote host rather than calling back to the yubikey). Advice or suggestions for this would be much appreciated!

Should be both options enabled.
my command line

ssh -i ~pathtokeyforthishost -A -l username \
-R /home/username/.gnupg/S.gpg-agent:/Users/username/.gnupg/S.gpg-agent \
-R /run/user/1000/gnupg/S.gpg-agent:/Users/username/.gnupg/S.gpg-agent

-A - enables agent forwarding
-R /home/username/.gnupg/S.gpg-agent:/Users/username/.gnupg/S.gpg-agent - this is for general linux boxes, e.g. ubuntu 16, centos, etc.
-R /run/user/1000/gnupg/S.gpg-agent:/Users/username/.gnupg/S.gpg-agent - this is for ubuntu1804,
where 1000 is the uid of the username

Whoa there. That's a complicated long set of command line args. I definitely don't have to use the -R flag for my forwarding to work, only -A.

I have StreamLocalBindUnlink yes set in my remote machines' /etc/ssh/sshd_config file.

My .bashrc on my remote machine calls gpgconf --create-socketdir .

My gpg-agent.conf conf file (remote and local):

enable-ssh-support
pinentry-program /usr/bin/pinentry-curses
default-cache-ttl 60
max-cache-ttl 120
extra-socket /run/user/1000/gnupg/S.gpg-agent.extra

~/.ssh/config:

host XXXX
    ForwardAgent yes
    hostname XXXX
    RemoteForward /run/user/1000/gnupg/S.gpg-agent /run/user/1000/gnupg/S.gpg-agent.extra

gpg.conf file has the following option:
use-agent

Edit: forgot my ~/.ssh/config file

StreamLocalBindUnlink parameter is set at my end (remote machine) as well. But as part of a "user_data" script

# sshd_config, based on https://wiki.gnupg.org/AgentForwarding
# StreamLocalBindUnlink yes
echo 'StreamLocalBindUnlink yes' | tee -a /etc/ssh/sshd_config
systemctl restart ssh

Regarding the extra-socket option - I reckon that's something I will try when I have time (usually this means never but who knows).
The plan is to enable this feature on both ends and ssh into a remote box without -R switches.

Thanks both @netflash and @taigrr for the help, this clarified much that in retrospect maybe should have been obvious.

  • With -A option (or the use of ForwardAgent yes in the relevant ~/.ssh/config section) I can indeed ssh from the remote host to other machines as claimed. This enables the ssh agent functionality, it does nothing about GPG functionality. (Perhaps this was already obvious to someone who frequently uses standard ssh-agent forwarding)
  • The RemoteForward is required to use encrypt and signing and other GPG functionality. I also learned that binding to the local machine's extra socket (S.gpg-agent.extra) blocks access to things like gpg --list-card and gpg --edit-card from the remote host, and is thus appears to be a sensible extra security measure.

On the remote host, I didn't need to create or have any ~/.gnupg/gpg.conf or ~/.gnupg/gpg-agent.conf created.

I did need to go to the remote machine to both configure the extra socket and import the public key, and also either set /etc/ssh/ssd_config with 'StreamLocalBindUnlink yes or manually delete the socket on the remote host. I still think it would be nice if the guide documented the GPG Agent forwarding of sockets.

This is all quite nice as I can now perform common tasks like signing and pushing commits to github from a remote machine using only the keys from my Yubikey, and can avoid having private ssh keys in a local ~/.ssh.

commented

@Wheest wrote that section in 4e23c63 FYI - it's not something I use, so PRs are welcome.

Apologies if my section was lacking.

Looking at my own setup, I have the following lines in my local ~/.ssh.config for some remote machine

     RemoteForward /run/user/1000/gnupg/S.gpg-agent /run/user/1000/gnupg/S.gpg-agent.extra
     ForwardAgent yes

You can see how to get those sockets in this blog post. Steps 4 and 5 of the blog post are pertinent too, and something I forgot to include.

Let me know if this works for your setups, and if so we can integrate the steps of the blog post as PR. idk what the policy on citing is for the linked blog post, if we should add it to the "links" section at the end or inline?

Thanks @Wheest , I agree it would be nice to include both the bit about RemoteFroward and about finding the sockets, as well as steps 4 & 5 like you say. (May also be worth noting that a non-root user who can't edit /etc/ssh/sshd_conf can alternatively manually remove the socket on the remote host, e.g. rm /run/user/1000/gnupg/S.gpg-agent.)

Though that post doesn't mention it, it may be necessary to also modify the local gpg-agent.conf to include:

enable-ssh-support
extra-socket /run/user/1000/gnupg/S.gpg-agent.extra

(or whatever the reported extra-socket address is)? Or is that not necessary?

I updated my comment above so it is complete. It now contains all the necessary options for full agent forwarding to work.

Have added some of this information into the following pull request, further feedback and amendments needed before it should be merged. Thanks all for your comments thus far.

@cboettig regarding the case of a non-root user being able edit /etc/ssh/sshd_config. You say that running rm /run/user/1000/gnupg/S.gpg-agent works? Could you please confirm if this works for you, even after your session has closed and has been reopened?

The Agent Forwarding page on gnupg wiki seems to corroborate with the line:

Into /etc/ssh/sshd_config to enable automatic removal of stale sockets when connecting to the remote machine. Otherwise you will first have to remove the socket on the remote machine before forwarding works.

But it would be good to have a second opinion.

@taigrr, thanks for the comment update. I don't recall having to edit gpg-agent.conf for either machine when I setup. It seems that for some folk it might be necessary. Have added it as a "just in case" at the end of the section.

@Wheest yes, I can confirm that deleting the socket on the remote machine, logging out, and logging back in works (if being rather annoying) if you can'y edit /etc/ssh/sshd_conf. It may be worth noting this appears to be not necessary if you just want ssh agent ability (since the RemoteForward isn't necessary), but is needed for signing and standard GPG to work.

Also, I've found I cannot get ssh fowarding to work as documented in the guide by using the public key as the identify file -- this just throws an error that the key is in the wrong format. So far, I've had to extract a private ssh key with gpg --export-ssh-key, though I feel this should not be necessary since it's not mentioned?? any insight on that one?

Hey @cboettig, thanks for the suggestions on the PR.

I'm afraid that I'm not too sure RE that particular issue.

For another project I've spun up a new server, and haven't been able to get agent forwarding running yet, according to my instructions. I'll append anything I find while doing that to my PR.

EDIT:

Aye, have added some things I've tried. Still haven't managed to get forwarding working on my new remote machine. Keep getting the error Warning: remote port forwarding failed for listen path /home/ec2-user/.gnupg/S.gpg-agent.

@Wheest what is your .ssh/config for RemoteForward? The port path for your remote machine looks like it might be incorrect, is that really the path that gpgconf --list-dirs agent-socket shows when run on your remote machine?

Re my confusion on needing a private key, gpg --export-ssh-key $KEYID is indeed exporting my public key and not my private key, and it does seem to work fine with ssh. However, some clients (e.g. RStudio IDE's built-in git GUI) still complain that this key is in the wrong format, though the commands run fine from the terminal. Probably related to the IDE not respecting some of the agent env var settings?

Heads up that SSH-forwarding can be an inherently dangerous thing to set up: https://matrix.org/blog/2019/05/08/post-mortem-and-remediations-for-apr-11-security-incident#ssh-agent-forwarding-should-be-disabled

This is a good point, and I reckon it should be added to the guide. Users will view this guide as vetted security advice, important to keep standards up

commented

@Wheest @anoadragon453 - thanks for the heads up, would you mind sending a pull request to add a warning?

@Wheest @anoadragon453 - thanks for the heads up, would you mind sending a pull request to add a warning?

Just FTR, this is done; seeing how https://github.com/drduh/YubiKey-Guide#remote-machines-agent-forwarding (now) starts with "Note SSH Agent Forwarding can add additional risk - proceed with caution!* and links to that matrix.org article.

I had Agent Forwarding with a YubiKey working nicely for months, and for some reason I haven't been able to figure out, it recently broke... ssh-add -l now fails on me with error connecting to agent: Connection refused instead of showing ... cardno: ... on the remote machine just like it does on the local machine when agent forwarding works. I'll update the Troubleshooting section if I can figure it out - tips welcome! 😄

@vorburger You could try to refresh stubs. I have 2 yubikeys with the same info on them and when I change them it helps to make it work:

gpg-connect-agent killagent /bye && gpg-connect-agent /bye && gpg-connect-agent \"learn --force\" /bye && gpg2 --with-subkey-fingerprint --keyid-format long -k && gpg2 --with-subkey-fingerprint --keyid-format long -K && gpg2 --card-status

@AlexanderBartash thanks! In my case, the problem was a confusion on my end re. SSH_AUTH_SOCK - I've raised a bunch of PRs to help clarify what I learnt while figuring this out for others in the future; see also this in my repo.