如何在WSL2中使用FIDO兼容的Security Key作为SSH登录密钥

关于硬件部分

首先感谢pico fido项目,让我们大概可以只花十几块钱成本就用上FIDO兼容的USB Security Key,相比几百块的yubikey来说简直就是白给,一个yubikey的钱都可以自己画板子做上几十个了。

等我用的这个版本的3D打印外壳回来,一切正常后我会发布一个开源版本的硬件资料,你们想用的就自己交给嘉立创去PCB+SMT好了。不过要说一下,你如果一次性不做上上百个,自己只做PCB加SMT做10个的话,单个平均成本在60+,主要是SMT的换料费和工程费没有被足够的数量均摊,做5个更亏。

并不是我想象的工作方式

先说一个我不太满意的结论:我一开始以为这种硬件是会在本地保存私钥的,不管我走到什么地方,只要带着这个USB Security Key就可以随时把它作为私钥来登录ssh;事实上并不是如此,我们依然需要保存私钥文件,并在ssh的时候调用这个文件,但是调用这个文件的时候需要你插入并验证USB Security Key,否则只有文件是无法使用的。

相当于我们的硬件是给私钥做了一个2FA两步验证,私钥即使暴露也无所谓了,很安全,但并不像我想的方便。不过想想也是,如果只需要一个USB Security Key就等于拥有了私钥,那安全从何谈起,简直是安全性上的倒退。

勘误:

其实这种硬件key分为两种,一种是可发现,一种是不可发现,不可发现的就是我上面说的这种需要自己保存私钥文件的,可发现密钥就是保存在硬件key里的。每次使用前用ssh-add从硬件导入key给ssh agent,或者ssh-keygen -K从key导出key文件就可以了,不过pico key在使用上似乎有点问题,所以下面这部分的文章我就没法继续测试了。yubikey的这篇文章讲得其实很完整了,可以参考。

再次勘误:

pico key其实是可以通过下面的命令导入硬件里面的安全密钥的,但是必须是在管理员权限的powershell或者wsl2 terminal里才行。

ssh-add -K -S internal
ssh-keygen -K

先建立安全密钥PIN

下面我们主要说一下如何在WSL2中使用类似pico key的的FIDO兼容安全密钥,来作为SSH登录密钥。我假定你已经装好了WSL2,WSL2的默认系统是Debian或者Ubuntu。

WSL1就默认不在讨论范围了,我想应该没什么人用了,那个顶多就是个模拟器而已,不要指望什么,所以一下的WSL都是指代WSL2。

拿到硬件后首先去windows的设置--账户--登录选项中,给安全密钥创建PIN,这相当于安全密钥本身的二次验证,不过这是个固定的PIN,只是稍微增加一层防护而已。

安装OpenSSH

Windows的Powershell默认其实已经有一些openssh组件了,但并不能支持FIDO Key,先到这个Repo下载好新版本的OpenSSH组件并安装。

这个就是我们需要的全部软件了,并不需要使用USBIPD-WIN来把FIDO Key从windows usb共享到wsl2的usb。

然后检查一下系统Path的优先级,确定我们的ssh-keygen是优先调用"C:\Program Files\OpenSSH\"这个目录下的,如果不是请调整Path目录的优先级,或者干脆显式的用完整路径执行"C:\Program Files\OpenSSH\ssh-keygen.exe"。

生成新的密钥对

按照你的需求和硬件的支持情况,生成ssh密钥对,这些命令都是在powershell中执行的,不是wsl。

下面这种加密方式基本上是个FIDO Key都支持:

ssh-keygen -t ecdsa-sk -O resident -O application=ssh:YourTextHere -O verify-required

下面这种需要比较新版本firmware的yubikey才可以,有yubikey的可以试试,我这里就不管了:

ssh-keygen -t ed25519-sk -O resident -O application=ssh:YourTextHere -O verify-required

正常情况下,window会弹出对话框,让你输入刚才设定的FIDO Key的PIN,按提示触摸按键,对话框完成后key也就生成了。

如果没有指定文件名的话,一般会得到两个文件,分别是id_ecdsa和id_ecdsa.pub,分别是私钥和公钥文件。

只需要把公钥文件放到服务器上,导入到~/.ssh/authorized_keys里就完成了服务器的设置了,authorized_keys是可以保存多个公钥的,登录的时候会一次尝试验证,并不冲突。

scp id_ecdsa.pub root@yourserver.com/root/

ssh root@youserver.com

cat id_ecdsa.pu >> ~/.ssh/authorized_keys

在Powershell中使用FIDO Key登录SSH

这个时候你已经可以在powershell中使用FIDO Key登录SSH了,如果id_ecdsa密钥放在了你用户名目录的.ssh目录下,直接ssh就可以了。如果在别的路径,你也可以显式调用这个key来登录:

ssh root@youserver.com -i ~/.ssh/id_ecdsa

windows会自动弹出对话框,提示你输入密钥的PIN,触摸按键等,然后就完成登录了。

所以说,如果没有硬件key,私钥文件即使给你也没用,即使遭遇病毒木马攻击,对方也很难盗取你硬件key里的内容,安全性大大提高

Login SSH with FIDO Key

如何在WSL2中使用FIDO Key登录SSH

其实非常简单,首先你需要把私钥文件复制到WSL2的linux文件系统内,这里的linux文件系统是指除了/mnt/c/ /mnt/d这样的WSL里访问windows文件系统之外的,WSL的ubuntu自己的linux文件系统。因为ssh对私钥的文件权限是有要求的,需要设置成600。

chmod id_ecdsa 600

而这种修改,对windows文件系统下的文件是无效的,所以需要先复制到linux文件系统下。

我们刚才装的OpenSSH Windows包,还提供了一个ssh-sk-helper.exe程序作为ssh agent和硬件key之间的桥梁,在powersheel中登录的时候就会在后台隐式调用这个helper。

WSL2中的openssh客户端其实也可以使用这个helper,只需要在~/.bashrc中添加

export SSH_SK_HELPER="/mnt/c/Program Files/OpenSSH/ssh-sk-helper.exe"

然后source ~/.bashrc,或者重开一个wsl窗口就可以生效了。

接下来的使用步骤,和powershell中完全一样,就不再重复了。