VS Code Remote-SSH免密登录:从原理到配置的完全指南
2026/9/18 3:00:17 网站建设 项目流程

1. 为什么Remote-SSH能解决"每次输密码"这个老大难

先说个真实场景:我日常要在公司的跳板机、家里的NAS、云上的开发服务器之间来回切,每台机器的密码策略还不一样,有的要求12位起步、有的三个月强制换一次。刚开始用VS Code的Remote-SSH插件时,每次连接都要敲一遍密码,一天下来光输密码就得十几次。后来实在受不了,花了一个下午把SSH密钥认证彻底搞定,从那以后所有远程开发都是秒开,输入密码这件事彻底消失在我工作流里。

Remote-SSH的原理很简单:VS Code在本地跑一个客户端,通过SSH协议连到远程机器,然后在远程机器上启动一个服务器端组件(vscode-server),本地编辑器界面和远程文件系统通过这个通道同步。你本地装插件、敲快捷键、看代码,实际执行和编译都在远程机器上完成。这个机制天生就是为密码认证设计的——每次建立连接都需要身份验证,如果走密码,那就是一次一输。

免密登录的本质,就是把"密码认证"换成"密钥认证"。

密钥认证用的是非对称加密:本地生成一对密钥(公钥+私钥),把公钥放到远程机器的~/.ssh/authorized_keys文件里。连接时,远程机器用公钥加密一段随机数据发给本地,本地用私钥解密后回传,远程验证通过就算登录成功。整个过程不需要在网络上传输密码,安全性比密码认证更高,也彻底绕开了"每次敲密码"的痛点。

这篇文章就围绕这件事展开:密钥怎么生成、公钥怎么放过去、VS Code里怎么配、踩了哪些坑,以及几个能让体验更顺滑的进阶操作。适合被Remote-SSH输密码折磨过的人,也适合刚接触SSH密钥认证、想在VS Code里直接落地的新手。

2. 准备工作:搞清楚你的SSH客户端环境

动手之前,先确认本地环境里有没有可用的SSH工具。Windows、macOS、Linux三套系统的检查方式不太一样,但目标一致:能执行ssh命令,能找到~/.ssh目录。

2.1 Windows环境:OpenSSH客户端要装好

Windows 10 1809之后的版本基本都自带OpenSSH客户端,但老系统、精简版系统可能会有缺失。判断方法很简单:打开PowerShell或CMD,输入:

ssh -V

能输出版本号(比如OpenSSH_for_Windows_8.1p1, LibreSSL 3.0.2)就说明没问题。如果提示"不是内部或外部命令",需要自己去"设置 → 应用 → 可选功能"里添加OpenSSH客户端,或者用winget安装:

winget install Microsoft.OpenSSH.Beta

提示:Windows下安装完后,记得重开一个终端窗口,让PATH环境变量生效。

2.2 macOS和Linux:基本都是自带的

macOS和主流Linux发行版默认都带OpenSSH客户端,直接验证就行:

ssh -V

如果哪台机器意外没装(比如精简版Linux服务器),macOS可以用Homebrew装:

brew install openssh

Debian/Ubuntu系列:

sudo apt update && sudo apt install openssh-client

2.3 确认本地SSH密钥是否已存在

很多人之前配过GitHub的SSH免密,那本地其实已经有密钥了,没必要重新生成。查看方式:

ls -la ~/.ssh/

看到id_ed25519id_ed25519.pub这类文件就说明已有密钥对。id_ed25519是私钥(绝对不能外传),id_ed25519.pub是公钥(可以放到任何远程机器上)。

如果目录不存在或者为空,才需要重新生成一对密钥。生成命令推荐用ed25519算法:

ssh-keygen -t ed25519 -C "your_email_or_comment"

执行后会问两个问题:保存路径(直接回车用默认的~/.ssh/id_ed25519)和密码短语(passphrase)。

这里有个常见的认知误区:passphrase和服务器密码是两回事。passphrase是给私钥文件本身加密用的,相当于私钥的"开机密码"。如果设了passphrase,每次使用私钥时还要输入一次,等于免密登录只免了远程机器密码,没免本地私钥密码。但VS Code的Remote-SSH和系统SSH Agent配合后,可以做到只在首次解锁私钥时输一次,后续全程免密。

我的建议是:本地电脑是个人设备、没有物理安全顾虑的话,passphrase可以直接留空;如果是公司电脑或公用机器,建议设置passphrase,然后配合SSH Agent用(后面讲)。

生成完成后,查看公钥内容:

cat ~/.ssh/id_ed25519.pub

形如ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAxxxxx your_email@example.com的一长串就是你的公钥。

3. 把公钥放到远程机器:三种方式任选

公钥放不到远程机器上,免密就是空谈。根据你手头的条件,从最简单的开始选。

3.1 最省事的方式:ssh-copy-id

Linux和macOS用户基本都有ssh-copy-id这个工具,一条命令把公钥推过去并自动追加到authorized_keys

ssh-copy-id -i ~/.ssh/id_ed25519.pub user@remote_host

执行后会要求输入一次远程机器的密码,输入后工具会自动在远程创建~/.ssh目录(如果没有)、把公钥追加到authorized_keys、并设置正确的权限。整个过程只需一次密码。

3.2 Windows用户的替代方案

Windows自带的OpenSSH客户端通常没有ssh-copy-id命令,但有两个办法:

办法一:用PowerShell管道手工写入

type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh user@remote_host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

这个命令会先读取本地公钥内容,通过管道传给远程的ssh命令,远程端执行mkdir -p ~/.ssh创建目录、用cat >>追加到authorized_keys

办法二:直接在远程机器上手工编辑

如果远程机器有网页终端(云服务商控制台自带的那种)或者你能通过其他方式登录,直接登录远程机器,执行:

mkdir -p ~/.ssh chmod 700 ~/.ssh echo "ssh-ed25519 AAAA...你的公钥内容..." >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys

注意权限:~/.ssh必须是700,authorized_keys必须是600。权限太宽松的话,OpenSSH会认为文件不安全,直接忽略这个文件,导致免密失效。

3.3 放完后先手动验证一次

无论用哪种方式,放完公钥后先别急着动VS Code,在终端里手测一下:

ssh user@remote_host

如果直接进到远程机器的shell而没要密码,说明密钥认证已经生效。如果还是要密码,先别继续往下走,去检查权限和文件路径。

注意:远程机器的~是指你登录用户的家目录。如果你登录的是root,那就是/root/.ssh/authorized_keys;如果登录的是普通用户dev,那就是/home/dev/.ssh/authorized_keys。放错用户目录是免密失效的头号原因。

4. 在VS Code里配置并验证免密连接

命令行SSH免密验证通过后,VS Code Remote-SSH基本就水到渠成了。这个插件并不自己实现SSH协议,而是复用你本机的OpenSSH客户端,所以命令行能免密,VS Code就一定能免密。

4.1 安装Remote-SSH插件

VS Code扩展市场搜索"Remote - SSH",认准微软官方发布的(发布者为Microsoft),安装量千万级那个。装完会提示重载窗口,照做就行。

4.2 配置SSH Config文件

Remote-SSH插件会读取SSH Config文件里的主机信息。在VS Code里按F1,输入Remote-SSH: Open SSH Configuration File,选择配置文件打开。

Windows路径一般是C:\Users\你的用户名\.ssh\config,macOS/Linux是~/.ssh/config。没有这个文件就手动新建一个。

一个最小可用的配置示例:

Host my-server HostName 192.168.1.100 Port 22 User dev IdentityFile ~/.ssh/id_ed25519

各字段含义:

  • Host:你在VS Code里看到的主机别名,可以自定义,比如my-web-servernas,方便记忆
  • HostName:实际连接的IP地址或域名
  • Port:SSH端口,默认22,改了端口就填对应值
  • User:远程登录用户名
  • IdentityFile:指定使用哪个私钥文件。本地有多对密钥时建议显式指定,避免SSH默认顺序找不到对的私钥

如果远程机器还有跳板需求,config里还可以配ProxyJump,但那个属于进阶玩法,后面单独说。

4.3 在VS Code中连接并观察过程

配置好后,VS Code左下角有个绿色的><图标(Remote Window按钮),点它会弹出远程连接菜单,选择Connect to Host,再选刚才配置的my-server,VS Code会新开一个窗口开始连接。

第一次连接远程机器时,VS Code需要往远程下载并解压vscode-server组件,这取决于网速,通常需要几十秒到几分钟不等。左下角状态栏会显示下载进度,底部输出面板能看详细日志。

连接成功后,左下角会变成SSH: my-server,左下角的绿色图标也变成远程状态。此时打开的文件、终端都是远程机器上的,本地和远程由一条安全通道连通。

关键验证点:整个连接过程没有弹出任何密码输入框的话,说明VS Code已经通过SSH Config里的IdentityFile找到了本地私钥、完成了密钥认证,免密登录正式生效。

4.4 常见失败点:VS Code提示输入密码但命令行免密正常

这个问题很多人遇到过:命令行ssh已经免密了,VS Code连接还是弹密码框。排查思路如下:

第一,确认VS Code用的SSH客户端和命令行是同一个。Windows下如果装了Git Bash,Git Bash自带的ssh和系统OpenSSH可能是两套密钥目录。VS Code的Remote-SSH默认调用的也是系统ssh,但如果你在VS Code设置里改了remote.SSH.path指向了别的ssh程序,那走的可能就是另一套配置。检查方法:VS Code设置里搜remote.SSH.path,留空表示用系统默认。

第二,确认IdentityFile路径写对了。Windows下config文件里的路径要写成/c/Users/你的用户名/.ssh/id_ed25519(Git Bash风格)或者C:\Users\你的用户名\.ssh\id_ed25519(部分场景支持),但最稳妥的做法是写成~/.ssh/id_ed25519,让SSH客户端自己解析。

第三,看SSH日志。在VS Code的输出面板里选"Remote - SSH"频道,能看详细的连接日志。如果日志里出现Offering public keyAuthentications that can continue: publickey这类信息,说明服务器在要求公钥认证但本地没提供对的公钥;如果出现Permission denied (publickey,password),说明公钥认证失败后回落到密码认证——这时候优先怀疑authorized_keys内容或权限有问题。

5. 免密登录的原理与权限细节:为什么有时候"全对"却连不上

很多人在免密配置上栽跟头,不是公钥没放对,而是踩了SSH权限检查的隐藏雷区。这节把原理和细节说透。

5.1 SSH密钥认证的完整流程

一次标准的SSH密钥认证,流程是这样的:

  1. 客户端发起连接,告诉服务器自己有哪些公钥(通过SSH_MSG_REQUEST_PUBKEY消息试探)
  2. 服务器检查公钥是否在目标用户的authorized_keys里,如果在,就用这个公钥加密一段随机质询数据发回客户端
  3. 客户端拿到质询数据,用本地私钥解密,再把解密结果发回服务器
  4. 服务器验证解密结果正确,认证通过,建立会话

这就是为什么公钥文件比私钥文件更"公开"的原因:公钥只是用来加密质询数据的,真正的身份验证靠的是持有对应私钥这一事实。把公钥随便发到GitHub、服务器上都没问题,但私钥一旦泄露,就等于把家门钥匙交给了别人。

5.2 权限检查:OpenSSH的"洁癖"

OpenSSH服务端对目录权限有严格要求,任何一步权限"过度开放"都会导致authorized_keys被忽略。常见权限要求如下:

路径要求权限
用户家目录~不能对组和其他用户开放写权限(不能是777或755)
~/.ssh目录700(只有本人可读写执行)
~/.ssh/authorized_keys600(只有本人可读写)
~/.ssh/私钥文件600(只有本人可读写)
父目录的所有者必须是你本人或root

如果你用ssh-copy-id推的公钥,这些权限工具会自动设好;但如果你是用echoscp手工放过去的,很可能忽略了权限问题。

排查命令:

ls -ld ~ ~/.ssh ~/.ssh/authorized_keys

看到形如drwx------(目录)和-rw-------(文件)就符合要求。如果权限不对,用这两条修正:

chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys

如果家目录权限也有问题,还需要:

chmod 755 ~

注意:这里的~是远程机器上你登录用户的家目录,不是本地路径。很多人习惯性在自己电脑上执行chmod,结果改了个寂寞。

5.3 远程机器的SELinux或防火墙也可能拦截

Linux服务器开启了SELinux(CentOS、RHEL、龙蜥等系统常见)时,即使文件权限全对,SELinux策略也可能拒绝SSHD读取新添加的authorized_keys。

如果免密失效且权限都正确,可以试试:

restorecon -R -v ~/.ssh

这条命令会恢复.ssh目录的SELinux上下文。运气好的话,一条命令就解决问题。

另外,云服务器安全组和系统防火墙(firewalld/ufw)也要确认放行SSH端口。有时候公钥认证是成功的,但连接被防火墙拦在半路,表现也是"连不上"或者"要密码",容易误导排查方向。

6. SSH Agent与passphrase:本地私钥加密上了怎么办

如果生成密钥时给私钥设置了passphrase,那么每次使用私钥时,SSH客户端都会要求输入这个passphrase。VS Code连接远程机器时也一样——虽然远程密码免了,但本地私钥还等着解锁,等于没免干净。

解决办法是用SSH Agent把私钥"暂存"在内存里,解锁一次后,后续所有SSH连接都从Agent里直接取私钥,不再反复问passphrase。

6.1 启动SSH Agent并添加私钥

Windows:

# 启动SSH Agent服务(如果未运行) Get-Service ssh-agent | Set-Service -StartupType Automatic Start-Service ssh-agent # 将私钥添加到Agent ssh-add $env:USERPROFILE\.ssh\id_ed25519

执行ssh-add时会要求输入一次passphrase,输入后私钥就一直驻留在Agent里,直到重启电脑或手动移除。

macOS:

eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519

macOS的Agent可以由Keychain管理,加--apple-use-keychain参数(新版)可以把passphrase存入钥匙串,重启后都不需要重新添加:

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Linux:

eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519

桌面版Linux更推荐用keychaingnome-keyring这类工具管理,能免去每次手动ssh-add的麻烦。

6.2 没有passphrase的话,Agent还有用吗

有用。即使私钥没有passphrase,SSH Agent依然是一个推荐实践。原因是:很多SSH连接场景(比如从开发机跳板到内网服务器)需要多次转发身份。SSH Agent Forwarding(转发)可以把本地Agent的socket转发到远程,让你在远程机器上执行git clonescp到其他机器时,也能直接用本地私钥认证,而不用把私钥文件拷到远程。

不过Agent Forwarding要谨慎使用——它相当于把本地的"免密能力"开放给了远程机器。如果远程机器被入侵,攻击者可以借用你的Agent去连接所有配置了对应公钥的机器。我的习惯是:个人开发用的可信内网机器才开Agent Forwarding,公网服务器绝对不开。

7. 高频坑汇总:Remote-SSH免密配置中我踩过的雷

这节把实际使用中遇到的典型问题和排查思路整理成清单,每一条都是真实踩过的。看完之后,大部分免密问题你都能自行定位。

7.1 连上之后又掉线:SSH保活机制

远程开发经常有这种场景:代码写到一半去倒杯咖啡,回来发现VS Code已经断线重连了,或者终端卡在那儿不动。这是因为SSH连接在长时间没有数据交互后,会被网络设备(NAT网关、云防火墙)判定为超时连接而掐断。

解决办法是在SSH Config里加保活参数:

Host my-server HostName 192.168.1.100 User dev IdentityFile ~/.ssh/id_ed25519 ServerAliveInterval 60 ServerAliveCountMax 3

ServerAliveInterval 60表示每60秒客户端主动向服务器发一个保活心跳包;ServerAliveCountMax 3表示连续3次心跳无响应才断开。设置后,长时间挂机、断网恢复后的自动重连都会稳定不少。

7.2 多台机器要用不同的密钥或配置

工作中有几台不同的服务器,有的内网、有的公网、有的需要指定特定私钥。SSH Config支持为每个主机单独指定所有参数:

Host office HostName 192.168.1.10 User dev Port 22 IdentityFile ~/.ssh/id_ed25519_office Host cloud HostName 47.98.xx.xx User root Port 22022 IdentityFile ~/.ssh/id_rsa_cloud

VS Code Remote-SSH连接时,插件会读取整个config文件,你在连接菜单里选择哪个Host,就走哪套配置。一台开发机同时管理多个远程环境非常方便。

7.3 跳板机场景:ProxyJump

公司内部网络常见的拓扑是:本地只能直连跳板机,内网开发服务器要通过跳板机才能访问。SSH原生支持跳转代理:

Host jump HostName 跳板机IP User yourname IdentityFile ~/.ssh/id_ed25519 Host inner-server HostName 10.0.1.50 User dev IdentityFile ~/.ssh/id_ed25519 ProxyJump jump

配置后,VS Code连接inner-server时,SSH客户端会自动先连上jump,再通过jump转发连接到内网服务器。整个过程免密,VS Code里显示也是直接连上内网目标。

7.4 "Could not establish connection to" 的通用排查清单

如果VS Code连接远程机器失败,按以下顺序逐一排查:

检查项验证方法常见修复
网络可达性ping 远程IP检查防火墙/安全组
SSH端口telnet 远程IP 22检查sshd是否监听
用户名ssh user@host能否登录确认username
密钥认证ssh -v user@host看日志检查authorized_keys
vscode-server查看远程 ~/.vscode-server删除后重新连接
磁盘空间df -h清理远程磁盘
系统时间date对比时间偏移过大可能影响某些认证

其中vscode-server损坏或版本不一致是VS Code特有的大坑。插件更新、远端环境异常、磁盘空间满了,都可能让~/.vscode-server处于半损坏状态。遇到连接报错但命令行SSH正常的情况,先删掉远程的~/.vscode-server目录再重连,让VS Code重新部署一次,往往能直接解决。

7.5 公钥变更后不生效的坑

有时候你重新生成了密钥对,把新公钥放到了远程,但连接还是用的旧公钥。这是因为SSH Agent里缓存了旧的私钥。检查方式:

ssh-add -l

如果列表里显示的是旧密钥信息,先清除再添加:

ssh-add -D ssh-add ~/.ssh/id_ed25519

对于VS Code来说,重启一次窗口或彻底退出重开,确保SSH Agent状态重新加载。

8. 进阶:把Remote-SSH免密用得更顺手

免密登录搞定后,远程开发的体验还能再上一层楼。这节分享几个我日常依赖的进阶配置。

8.1 直接通过VS Code打开远程文件夹

连接上远程主机后,VS Code左上角的资源管理器会显示远程文件系统。点"打开文件夹",输入远程绝对路径(比如/home/dev/project),就能像操作本地项目一样浏览、编辑远程代码。配合免密,整个过程没有一次密码输入,打开速度取决于网络和文件数量。

8.2 远程终端:用VS Code的集成终端操作远程机器

连接成功后按Ctrl+`打开终端,这个终端直接运行在远程机器上。免密的好处在这里体现得淋漓尽致:你可以一次开三个终端,一个跑web服务、一个跑数据库客户端、一个敲Shell命令,全部都在远程机器上,本地只需要一个VS Code窗口。

配合Remote-SSH: Open Folder打开的项目目录,终端默认就切到项目路径下,省去了每次cd的麻烦。

8.3 端口转发:让本地浏览器访问远程服务

远程机器上跑了个Web服务(比如开发服务器监听在0.0.0.0:3000),本地浏览器想访问怎么办?Remote-SSH自带端口转发功能。

VS Code里按F1,输入Remote-SSH: Forward Port from Active Host,填入远程端口号(比如3000),VS Code会在本地随机开一个端口(或直接映射),然后提供http://localhost:3000让你访问。配合免密和SSH隧道,本地调试远程服务完全不需要手动起隧道命令。

8.4 远程机器离线安装vscode-server(离线环境)

部分内网服务器无法访问外网,VS Code第一次连接时会卡在"下载vscode-server"这一步。这种情况需要手动把vscode-server的压缩包拷到远程机器上。

操作思路:先在本地或一台能联网的机器上,从VS Code的更新服务器下载对应版本的vscode-server-linux-x64.tar.gz,然后scp到远程,解压到~/.vscode-server/bin/<commit-id>/目录。具体版本号可以从VS Code的Help → About里看到Commit ID,也可以从连接日志里找到它尝试下载的URL。

这个方法略繁琐,但确实是离线内网环境使用Remote-SSH的标准解法。前提是本地到远程的SSH通道本身就是通的——免密配好之后,整个文件传输过程也彻底免密,可以说是一环套一环的收益。

9. 从免密到更高效:我的长期使用体会

把Remote-SSH免密配好之后,收益是持续性的,不只是省了输密码那几秒钟。最直观的变化是:远程开发从一个"需要专门准备"的事,变成了跟本地开发一样自然的事。打开VS Code、选主机、进项目,一气呵成。

我个人的习惯是把常用的主机都写进~/.ssh/config,每台主机一个语义清晰的别名,比如pro-webstaging-dbhome-nas。这样每次开远程都不需要记IP、记端口、记用户名,选择主机名即可。

另外,建议定期清理authorized_keys文件里的废弃公钥。离职的同事、换掉的电脑、临时的测试密钥,不清理的话等于给旧设备留了后门。同样是免密,安全性和便利性要平衡——权限收敛、私钥保护、定时审计,这些才是免密登录能够长期稳定使用的底气。

在配置过程中如果遇到问题,按这篇文章提到的顺序排查:公钥放没放对、权限对不对、SSH Agent有没有缓存的旧密钥、VS Code的vscode-server需不需要重建。90%的问题都出在这四个环节里。剩下的10%,打开SSH日志看Authentication那段信息,一条条对着排查,基本都能找到答案。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询