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:

  1. Can I configure this to sign my commits?
  2. 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.

  1. On the DESTINATION machine, edit /etc/ssh/sshd_config file and add the following line: StreamLocalBindUnlink yes
  2. Restart the ssh server: systemctl restart sshd
  3. Get the HOST based gpg sockets commands:
    1. Run gpgconf --list-dirs agent-ssh-socket
    2. Run gpgconf --list-dirs agent-socket
  4. Run the DESTINATION based gpg socket commands:
    1. Run gpgconf --list-dirs agent-ssh-socket
    2. Run gpgconf --list-dirs agent-socket
  5. 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).

References

  1. Why Yubikey?
  2. Split SSH and Gpg with Qubes-OS
  3. How to enable SSH access using a GPG key for authentication

David Thole

David Thole
Senior Software Architect, Developer, Instructor. Reads/studies a lot and enjoys all things technology

Local Artificial Intelligence Tools

# IntroductionI was in a recent meeting when the presenter of the meeting spoke about running LLMs in the cloud, and how expensive it can...… Continue reading

Effective prompting with AI

Published on January 09, 2024

Creating Flashcards with Generative AI

Published on January 02, 2024