Introduction
Given my past posts, one can say I’m a fan of the YubiKey [1]. It’s an amazing device and I use it every day - most often multiple times per day.
One struggle I’ve had with it is it’s very ‘host specific’, in the sense that the host holds the key, and running things remotely is a challenge. I spoke about some of this in the “Split SSH and Gpg with Qubes-OS” [2], but this is now through SSH (or more accurately hosted through SSH). There’s a few articles that explain how to do this, such as “How to enable SSH access using a GPG key for authentication” [3], but unfortunately it’s not entirely complete from my purposes.
My specific use case is I’m running Ubuntu on a MacBook Pro, under VMWare. Attaching a YubiKey as a shared card does not work, and I don’t want to attach it (entirely) to the VM which would prevent my host accessing it. I want a solution where both system can access the YubiKey at the same time.
The goal of this operation is two fold:
- Can I configure this to sign my commits?
- Can I configure this so that I can
ssh
into other machines (thus push my commits and also use the Yubi to control sshing, physically, into other machines.)
Step by Step Instruction(s)
The below assumes that you have a working gpg setup already. If you don’t, view the guide on “How to enable SSH access using a GPG key for authentication” [3] first, then follow the rest here when done there.
- On the DESTINATION machine, edit
/etc/ssh/sshd_config
file and add the following line:StreamLocalBindUnlink yes
- Restart the ssh server:
systemctl restart sshd
- Get the HOST based gpg sockets commands:
- Run
gpgconf --list-dirs agent-ssh-socket
- Run
gpgconf --list-dirs agent-socket
- Run
- Run the DESTINATION based gpg socket commands:
- Run
gpgconf --list-dirs agent-ssh-socket
- Run
gpgconf --list-dirs agent-socket
- Run
- Edit your
~/.ssh/config
file to include the lines (replaced with #3 and #4 steps above):
Host destination_machine_name
Hostname hostname_of_machine
RemoteForward <4.1 above> <3.1 above>
RemoteForward <4.2 above> <3.2 above>
You should have a file, similar, to what I have below:
Host myvirtualmachine
Hostname myvirtualmachine
RemoteForward /run/user/1000/gnupg/S.gpg-agent /Users/dthole/.gnupg/S.gpg-agent
RemoteForward /run/user/1000/gnupg/S.gpg-agent.ssh /Users/dthole/.gnupg/S.gpg-agent.ssh
At that point, ssh into the machine.
After you’re on the machine, you may need to fix the socket (but may not have do this). I, often, have to do this, so I put the following into a script I call fixGPG
and have it in bin. But you may need to run the below either way:
#!/bin/sh
gpg-connect-agent "scd serialno" "learn --force" /bye
gpg-connect-agent updatestartuptty /bye
You should see output similar to the below if it’s done right:
S SERIALNO ...
OK
S PROGRESS learncard k 0 0
S PROGRESS learncard k 0 0
S PROGRESS learncard k 0 0
OK
OK
At that point, verify ssh is working by typing:
ssh-add -L
You should see the public key for your card.
At this point, you should be able to run commands within the VM and it works like expected on the host. It’s important to note that you DO NOT have to run them in the sshed session. You can switch back to the virtual machine window (if running a GUI).