an adventure using ssh with github

A strange man with too much hair holding the type of Yubico key I use

I have been taking a long side trip away from coding in an attempt to switch my GitHub source code repos from HTTPS to SSH. This began when I switched to using a Yubico 5 Series key ( https://www.yubico.com/products/yubikey-5-overview/ ) for two-factor authentication when I was using the web front-end to GitHub. But first, how I came to own this product.

I’d picked the key up when I subscribed some number of years back to ArsTechnica to stop the incessant ads on their website. I’d been using an ad blocker, but I visit the site so much and I was beginning to feel guilty not paying my way to read their content. When Ars offered a special deal that included the Yubico key as well as a general discount for one year’s usage, I signed up. The key arrived a few weeks after I signed up. The key then sat around on my desk, unused, for some considerable time.

Then GitHub, in 2021, started to enforce two-factor on everyone. GitHub offered a number of two-factor methods, one of which used the Yubico key. I plugged the key into a USB-A port, went through GitHub’s documented process, and in short order I was using the Yubico key to validate my GitHub logins. I was still using command line git to push changes from my local machine up to GitHub, and that continued to work for a while until very recently. Then apparently the full changes finally caught up with everything and I couldn’t push up from the command line anymore. Unfortunately I couldn’t find out from documentation how to get git to use the Yubico key.

Enter GitHub Desktop for Linux ( https://github.com/shiftkey/desktop/ ).

GitHub Desktop for Linux works with the Yubico key and allows me to push changes in any local repo up to my GitHub account. It works with everything I create locally except git tags. I’ve tried every way I know to coerce GitHub Desktop to push up the tag, but to no avail. That’s when I finally went into deeper research into using SSH with the Yubico key.

There’s plenty of documentation about creating an SSH pair with the Yubico key and then copying the public part into your GitHub account on GitHub itself, so I won’t go into that. However, I will document what I did and the results.

Creating SSH Keys using the Yubico Key

Because the Yubico key is now in the middle of my work flow, I needed to create a separate SSH key pair based on it. Here’s how I created my unique key pair.

~ ssh-keygen -t ed25519-sk -C "myname@gmail.com"
Generating public/private ed25519-sk key pair.
You may need to touch your authenticator to authorize key generation.
Enter file in which to save the key (/home/mint/.ssh/id_ed25519_sk): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/mint/.ssh/id_ed25519_sk
Your public key has been saved in /home/mint/.ssh/id_ed25519_sk.pub
The key fingerprint is:
SHA256:...
The key's randomart image is:
+[ED25519-SK 256]-+
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
+----[SHA256]-----+

Note the command in line 1 above. You’ll need to substitute your email address for myname@gmail.com before running the full command. You’ll also need to have the Yubico key plugged in and ready to touch it for the key to be generated. I had to try this twice because I didn’t reach the key fast enough to satisfy the software. Note that I entered no passphrase when called for. I took the file name defaults in lines 7 and 8, a decision that would come to bite me in the rear later on (although I didn’t know it would at the time). Here’s what my ~/.ssh folder held when it finished.

.
-rw------- 1 mint mint 626 Jan 28 21:15 id_ed25519_sk
-rw-r--r-- 1 mint mint 189 Jan 28 21:15 id_ed25519_sk.pub
-rw-r--r-- 1 mint mint 888 Aug  1 13:58 known_hosts

Copying and Testing the SSH Key

The mechanism for copying the public part of the SSH key into your GitHub account is documented here ( https://github.com/settings/keys ). There’s nothing out of the ordinary and the directions are clear enough to leave as an exercise to the student. It’s when I tried to test the setup I ran into problems.

The command for testing your SSH setup with GitHub is ssh -vT git@github.com, where -vT is verbose testing. Turns out that verbose in this case is debug testing. Whatever. When the command was first run the test failed. I’m going to show some output, but I’m only going to show the important parts; there’s some considerable trimming ahead.

...
debug1: Offering public key: /home/mint/.ssh/id_ed25519 ED25519-SK SHA256:... authenticator agent
debug1: Server accepts key: /home/mint/.ssh/id_ed25519 ED25519-SK SHA256:... authenticator agent
sign_and_send_pubkey: signing failed for ED25519-SK "/home/mint/.ssh/id_ed25519" from agent: agent refused operation
...

You’ll note that ssh is trying to ask for id_ed25519, not id_ed25519_sk, the file name defaults from key generation. When I copied both key files to remove the _sk portion and re-ran the test, it passed and I’m now able to hopefully work from the command line. Here’s a successful run. Note that ellipses (…) indicate redacted data.

~ ssh -vT git@github.com
OpenSSH_8.9p1 Ubuntu-3ubuntu0.1, OpenSSL 3.0.2 15 Mar 2022
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: include /etc/ssh/ssh_config.d/*.conf matched no files
debug1: /etc/ssh/ssh_config line 21: Applying options for *
debug1: Connecting to github.com [140.82.113.3] port 22.
debug1: Connection established.
debug1: identity file /home/mint/.ssh/id_rsa type -1
debug1: identity file /home/mint/.ssh/id_rsa-cert type -1
debug1: identity file /home/mint/.ssh/id_ecdsa type -1
debug1: identity file /home/mint/.ssh/id_ecdsa-cert type -1
debug1: identity file /home/mint/.ssh/id_ecdsa_sk type -1
debug1: identity file /home/mint/.ssh/id_ecdsa_sk-cert type -1
debug1: identity file /home/mint/.ssh/id_ed25519 type 12
debug1: identity file /home/mint/.ssh/id_ed25519-cert type -1
debug1: identity file /home/mint/.ssh/id_ed25519_sk type 12
debug1: identity file /home/mint/.ssh/id_ed25519_sk-cert type -1
debug1: identity file /home/mint/.ssh/id_xmss type -1
debug1: identity file /home/mint/.ssh/id_xmss-cert type -1
debug1: identity file /home/mint/.ssh/id_dsa type -1
debug1: identity file /home/mint/.ssh/id_dsa-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.1
debug1: Remote protocol version 2.0, remote software version babeld-877a45b1
debug1: compat_banner: no match: babeld-877a45b1
debug1: Authenticating to github.com:22 as 'git'
debug1: load_hostkeys: fopen /home/mint/.ssh/known_hosts2: No such file or directory
debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts: No such file or directory
debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts2: No such file or directory
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: curve25519-sha256
debug1: kex: host key algorithm: ecdsa-sha2-nistp256
debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: SSH2_MSG_KEX_ECDH_REPLY received
debug1: Server host key: ecdsa-sha2-nistp256 SHA256:...
debug1: load_hostkeys: fopen /home/mint/.ssh/known_hosts2: No such file or directory
debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts: No such file or directory
debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts2: No such file or directory
debug1: Host 'github.com' is known and matches the ECDSA host key.
debug1: Found key in /home/mint/.ssh/known_hosts:3
debug1: rekey out after 134217728 blocks
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: rekey in after 134217728 blocks
debug1: get_agent_identities: bound agent to hostkey
debug1: get_agent_identities: agent returned 1 keys
debug1: Will attempt key: /home/mint/.ssh/id_ed25519 ED25519-SK SHA256:... authenticator agent
debug1: Will attempt key: /home/mint/.ssh/id_rsa 
debug1: Will attempt key: /home/mint/.ssh/id_ecdsa 
debug1: Will attempt key: /home/mint/.ssh/id_ecdsa_sk 
debug1: Will attempt key: /home/mint/.ssh/id_ed25519_sk ED25519-SK SHA256:... authenticator
debug1: Will attempt key: /home/mint/.ssh/id_xmss 
debug1: Will attempt key: /home/mint/.ssh/id_dsa 
debug1: SSH2_MSG_EXT_INFO received
debug1: kex_input_ext_info: server-sig-algs=...
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Offering public key: /home/mint/.ssh/id_ed25519 ED25519-SK SHA256:... authenticator agent
debug1: Server accepts key: /home/mint/.ssh/id_ed25519 ED25519-SK SHA256:... authenticator agent
Authenticated to github.com ([140.82.113.3]:22) using "publickey".
debug1: channel 0: new [client-session]
debug1: Entering interactive session.
debug1: pledge: filesystem
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug1: client_input_hostkeys: searching /home/mint/.ssh/known_hosts for github.com / (none)
debug1: client_input_hostkeys: searching /home/mint/.ssh/known_hosts2 for github.com / (none)
debug1: client_input_hostkeys: hostkeys file /home/mint/.ssh/known_hosts2 does not exist
debug1: client_input_hostkeys: host key found matching a different name/address, skipping UserKnownHostsFile update
debug1: Sending environment.
debug1: channel 0: setting env LANG = "en_US.UTF-8"
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
Hi wbeebe! You've successfully authenticated, but GitHub does not provide shell access.
debug1: channel 0: free: client-session, nchannels 1
Transferred: sent 2252, received 2456 bytes, in 0.1 seconds
Bytes per second: sent 18841.5, received 20548.3
debug1: Exit status 1

To Be Continued…