背景
如果什么都不做,直接 ssh 连接远程服务器会提示输入 password。然而每次重新打一遍 password 是很麻烦的。
一种经典的解决办法是,使用 ssh-keygen 生成 public key 和 private key,然后将 public key 传输到远程服务器上,这样就可以直接 ssh 连接远程服务器了(当然应该也有别的解决方法,但是我用了这一种)。如果有进一步的安全需求,可以设置 passphrase,这样每次连接远程服务器都需要输入 passphrase 来解锁 private key(为方便叙述,以下区分 password 和 passphrase)。
当然,这样引入了一点点额外的复杂性:本地机器需要额外访问存储 private key 的文件,而非直接发送键入的 password 就可以连接远程服务器。
命令行层面上实现这些是很简单的,但是如果要在 VSCode 中实现这些,就需要一些额外的配置,比如 Remote - SSH 插件。
问题
配置完毕之后直接发送 ssh 连接请求,发现还是要输入 password?
打开日志,发现如下错误:
1 | no such identity: /home/ducati/.ssh/id_rsa: No such file or directory |
在命令行确认了一下,发现这个文件确实存在;同时,直接命令行 ssh 连接远程服务器,是不需要输入 password 的。
???
更加离谱的是,日志里显示 ssh 的 config 文件是可以正常读取的,但是
identityFile(即
/home/ducati/.ssh/id_rsa)却读取不到。两者在同一目录下,权限也是一样的。
解决
首先我尝试改权限,无脑把两个文件和父目录的权限都改成 777,问题依旧。
然后我又盯着配置文件看了好久,也重启了几次 VSCode,重装了几次插件,问题还是没有解决。
我寻思着,他认为 /home/ducati/.ssh/id_rsa
不存在,肯定是经过了文件系统调用的,那不妨直接用 strace 监测所有与
vscode-server 相关进程的文件系统调用,看看到底是哪里出了问题。
打出来的日志很长,但是里面却只有
1 | readlink("/proc/2933/cwd", "/home/ducati/.ssh", 4096) |
之类的系统调用,没有任何关于 id_rsa 的。
换言之,这说明它压根就没有在我的本地 WSL 里面读取 id_rsa 文件。那它凭什么认为这个文件不存在呢?
我的第一反应是,它是不是在另一个地方读取的?
无非就两种情况,是用了 Windows 的系统调用,或者用了远程服务器的系统调用。后者显然不可能,private key 是不会传输到远程服务器的。那么就只有前者了。
换言之,现在的情况是,我在 WSL 里用 Remote - SSH
插件的时候,它混用了 Windows 的系统调用,导致无法读取
/home/ducati/.ssh/id_rsa 这个路径。
然后我翻到了 这个。
我按照其中的格式把 IdentityFile 这个 attribute 的值换成了 Windows 的路径,然后问题一下就解决了。
至今原因不明是我自己配置错了导致 Remote-SSH 插件对于 IdentityFile 用了 Windows 的 File system,还是这个插件本身的 Bug。不过这个问题解决了,我也就先不管了。