I’m feeling so thankful for the smart people that built tramp.el for emacs. For those who don’t know, tramp refers to “Transparent Remote Access, Multiple Protocols”, and it allows me to use the emacs running on my home laptop, to edit files running on a remote machine that I connect to via SSH. So I can edit files on my raspberry pi, or on my cloud shell machine, or on my remote host at nearlyfreespeech. All from the same emacs. It feels pretty magical at first, and then it just sort of fades into routine, like any sufficiently advanced technology. I don’t even think about it while using it.
Recently I wanted to add a requirement to use a FIDO key authentication to the ssh connection to a raspberry pi device. The server side is pretty easy – just set the proper key into ~/.ssh/authorized_keys . Generating a key is also pretty easy – follow the instructions from Yubico, or from other sources. Support for retrieving a private key from a security key, like a Yubico key, is possible in OpenSSH since version 8.2 (I think). But the OpenSSH on Windows lags a little bit. I think the feature finally worked in v8.9 on the Windows build. The “builtin” OpenSSH that gets installed alongside Powershell is v8.1p1.
PS > c:\windows\System32\OpenSSH\ssh.exe -V
OpenSSH_for_Windows_8.1p1, LibreSSL 3.0.2
Which is not sufficient. What to do?
Upgrade OpenSSH on the Windows machine, of course. You can get releases here. I installed v9.2.2.0. That allowed me to run ssh-keygen from a terminal to generate a key using type ecdsa-sk, and then store it on the Yubico key. And I could also run ssh from the terminal to connect into the rpi, after confirming my presence by touching the security key. All good. The only trick here was to insure I was using the correct version of OpenSSH. The newly installed OpenSSH did not overwrite the version in \windows\system32. Instead it appeared in program files:
PS > c:\progra~1\OpenSSH\ssh.exe -V
OpenSSH_for_Windows_9.2p1, LibreSSL 3.7.2
The next trick was persuading tramp.el in emacs to use the appropriate executable. This is done by twiddling the tramp-methods variable. For me, this worked:
(setf
(car (alist-get “sshx” tramp-methods nil nil #’equal))
‘(tramp-login-program “C:/Progra~1/OpenSSH/ssh.exe”))
And then, set up my ~/.ssh/config, and after that I can use a filespec like /sshx:rpi:/home to open a remote file, after confirming with a touch on my security key.
It’s satisfying when things work.