ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

VS Code Remote-SSH免密登录:从原理到配置的完全指南

2026/9/18 3:00:26 拓冰建站 浏览量
VS Code Remote-SSH免密登录:从原理到配置的完全指南 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 opensshDebian/Ubuntu系列sudo apt update sudo apt install openssh-client2.3 确认本地SSH密钥是否已存在很多人之前配过GitHub的SSH免密那本地其实已经有密钥了没必要重新生成。查看方式ls -la ~/.ssh/看到id_ed25519和id_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_emailexample.com的一长串就是你的公钥。3. 把公钥放到远程机器三种方式任选公钥放不到远程机器上免密就是空谈。根据你手头的条件从最简单的开始选。3.1 最省事的方式ssh-copy-idLinux和macOS用户基本都有ssh-copy-id这个工具一条命令把公钥推过去并自动追加到authorized_keysssh-copy-id -i ~/.ssh/id_ed25519.pub userremote_host执行后会要求输入一次远程机器的密码输入后工具会自动在远程创建~/.ssh目录如果没有、把公钥追加到authorized_keys、并设置正确的权限。整个过程只需一次密码。3.2 Windows用户的替代方案Windows自带的OpenSSH客户端通常没有ssh-copy-id命令但有两个办法办法一用PowerShell管道手工写入type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh userremote_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必须是700authorized_keys必须是600。权限太宽松的话OpenSSH会认为文件不安全直接忽略这个文件导致免密失效。3.3 放完后先手动验证一次无论用哪种方式放完公钥后先别急着动VS Code在终端里手测一下ssh userremote_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\configmacOS/Linux是~/.ssh/config。没有这个文件就手动新建一个。一个最小可用的配置示例Host my-server HostName 192.168.1.100 Port 22 User dev IdentityFile ~/.ssh/id_ed25519各字段含义Host你在VS Code里看到的主机别名可以自定义比如my-web-server、nas方便记忆HostName实际连接的IP地址或域名PortSSH端口默认22改了端口就填对应值User远程登录用户名IdentityFile指定使用哪个私钥文件。本地有多对密钥时建议显式指定避免SSH默认顺序找不到对的私钥如果远程机器还有跳板需求config里还可以配ProxyJump但那个属于进阶玩法后面单独说。4.3 在VS Code中连接并观察过程配置好后VS Code左下角有个绿色的图标Remote Window按钮点它会弹出远程连接菜单选择Connect to Host再选刚才配置的my-serverVS 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 BashGit 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_ed25519Git Bash风格或者C:\Users\你的用户名\.ssh\id_ed25519部分场景支持但最稳妥的做法是写成~/.ssh/id_ed25519让SSH客户端自己解析。第三看SSH日志。在VS Code的输出面板里选Remote - SSH频道能看详细的连接日志。如果日志里出现Offering public key、Authentications that can continue: publickey这类信息说明服务器在要求公钥认证但本地没提供对的公钥如果出现Permission denied (publickey,password)说明公钥认证失败后回落到密码认证——这时候优先怀疑authorized_keys内容或权限有问题。5. 免密登录的原理与权限细节为什么有时候全对却连不上很多人在免密配置上栽跟头不是公钥没放对而是踩了SSH权限检查的隐藏雷区。这节把原理和细节说透。5.1 SSH密钥认证的完整流程一次标准的SSH密钥认证流程是这样的客户端发起连接告诉服务器自己有哪些公钥通过SSH_MSG_REQUEST_PUBKEY消息试探服务器检查公钥是否在目标用户的authorized_keys里如果在就用这个公钥加密一段随机质询数据发回客户端客户端拿到质询数据用本地私钥解密再把解密结果发回服务器服务器验证解密结果正确认证通过建立会话这就是为什么公钥文件比私钥文件更公开的原因公钥只是用来加密质询数据的真正的身份验证靠的是持有对应私钥这一事实。把公钥随便发到GitHub、服务器上都没问题但私钥一旦泄露就等于把家门钥匙交给了别人。5.2 权限检查OpenSSH的洁癖OpenSSH服务端对目录权限有严格要求任何一步权限过度开放都会导致authorized_keys被忽略。常见权限要求如下路径要求权限用户家目录~不能对组和其他用户开放写权限不能是777或755~/.ssh目录700只有本人可读写执行~/.ssh/authorized_keys600只有本人可读写~/.ssh/私钥文件600只有本人可读写父目录的所有者必须是你本人或root如果你用ssh-copy-id推的公钥这些权限工具会自动设好但如果你是用echo或scp手工放过去的很可能忽略了权限问题。排查命令ls -ld ~ ~/.ssh ~/.ssh/authorized_keys看到形如drwx------目录和-rw-------文件就符合要求。如果权限不对用这两条修正chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys如果家目录权限也有问题还需要chmod 755 ~注意这里的~是远程机器上你登录用户的家目录不是本地路径。很多人习惯性在自己电脑上执行chmod结果改了个寂寞。5.3 远程机器的SELinux或防火墙也可能拦截Linux服务器开启了SELinuxCentOS、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里直到重启电脑或手动移除。macOSeval $(ssh-agent -s) ssh-add ~/.ssh/id_ed25519macOS的Agent可以由Keychain管理加--apple-use-keychain参数新版可以把passphrase存入钥匙串重启后都不需要重新添加ssh-add --apple-use-keychain ~/.ssh/id_ed25519Linuxeval $(ssh-agent -s) ssh-add ~/.ssh/id_ed25519桌面版Linux更推荐用keychain或gnome-keyring这类工具管理能免去每次手动ssh-add的麻烦。6.2 没有passphrase的话Agent还有用吗有用。即使私钥没有passphraseSSH Agent依然是一个推荐实践。原因是很多SSH连接场景比如从开发机跳板到内网服务器需要多次转发身份。SSH Agent Forwarding转发可以把本地Agent的socket转发到远程让你在远程机器上执行git clone、scp到其他机器时也能直接用本地私钥认证而不用把私钥文件拷到远程。不过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 3ServerAliveInterval 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_cloudVS 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 userhost能否登录确认username密钥认证ssh -v userhost看日志检查authorized_keysvscode-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填入远程端口号比如3000VS 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-web、staging-db、home-nas。这样每次开远程都不需要记IP、记端口、记用户名选择主机名即可。另外建议定期清理authorized_keys文件里的废弃公钥。离职的同事、换掉的电脑、临时的测试密钥不清理的话等于给旧设备留了后门。同样是免密安全性和便利性要平衡——权限收敛、私钥保护、定时审计这些才是免密登录能够长期稳定使用的底气。在配置过程中如果遇到问题按这篇文章提到的顺序排查公钥放没放对、权限对不对、SSH Agent有没有缓存的旧密钥、VS Code的vscode-server需不需要重建。90%的问题都出在这四个环节里。剩下的10%打开SSH日志看Authentication那段信息一条条对着排查基本都能找到答案。