拓冰建站拓冰建站
首页 / 资讯中心 / 正文

VS Code Remote-SSH 连接 Ubuntu 免密登录配置指南

在 Windows 上写代码、在 Ubuntu 上跑环境这个组合我用了好几年最开始那阵子我是靠 Samba 共享目录加手动同步文件过日子的改一个配置要来回切窗口跑个脚本还得复制粘贴到终端里效率低到让人怀疑人生。后来换成 VS Code 远程连接 Ubuntu再把免密登录配好整个工作流才算真正顺起来——本地 Windows 保留顺手的外设和熟悉的窗口管理Ubuntu 那边负责提供 Linux 原生编译环境、Docker、Python 生态和各种只有 Linux 才跑得舒服的依赖两边各干各的活中间靠一条 SSH 隧道连起来。这篇文章聊的就是这套方案从零到能用的完整过程VS Code 远程连 Ubuntu然后配置免密登录让你每次打开都不用手打密码。适合刚装完 Ubuntu 的新手也适合已经在用远程连接、但每次连接还在输密码、想把这步优化掉的同学。下面按准备、配置、实操、踩坑四个层面拆开讲能抄的地方我直接给命令和配置。1. 整套方案的思路与组件分工1.1 为什么选 Remote-SSH 而不是别的远程方式远程开发的方案其实不少VNC、RDP 这类图形化远程桌面走的是把整个桌面搬过来的路线带宽吃得多拖动窗口有延迟共享目录走的是文件同步的路线环境还是本地的遇到 Linux 专属依赖就抓瞎还有一种是把代码放本地用 SFTP 上传改一次传一次版本一乱就分不清哪边是最新的。Remote-SSH 的思路和它们都不一样它把 VS Code 拆成两半界面部分跑在你的 Windows 上负责渲染、输入、快捷键后端服务部分跑在 Ubuntu 上负责文件读写、终端执行、语言服务、调试器。你看到的文件树其实是 Ubuntu 上的真实文件你在编辑框里敲的每一行都会直接落到目标机器的磁盘上。这样带来的好处很实在。第一文件只有一份不存在本地和远程不同步的问题第二扩展可以分端安装像 Python、C/C、Go 这类需要在目标平台跑语言服务的扩展会装在远程端真正利用 Ubuntu 的编译器和解释器第三终端是原生的 Linux shellapt、make、gcc、docker 全都能直接用不用担心 Windows 上那些路径转义和换行符的破事。代价也有连接要稳定网络一抖就可能掉线首次连接需要在远程端下载服务端组件如果机器访问外网不方便这一步会卡住。但总体来说只要 SSH 通了这套方案是我试过的性价比最高的组合。1.2 三块拼图SSH 服务、密钥对、VS Code 插件整套流程拆开看只有三块内容理清楚它们的关系后面出问题就知道该往哪儿查。组件所在位置作用出问题的典型表现openssh-serverUbuntu监听 22 端口接受连接请求端口拒绝、连接超时密钥对私钥在 Windows公钥在 Ubuntu免密登录的凭证每次连接仍提示输密码Remote-SSH 插件Windows 的 VS Code建立隧道、拉起远程服务卡在正在打开远程SSH 服务是地基密钥对是钥匙插件是门。地基没打好门装不上钥匙配错了每次进门都得敲门让人开。很多人配免密失败问题往往不在插件而在公钥权限或者 sshd 配置上所以后面我会把 Ubuntu 端的细节讲透。提示如果你现在连 SSH 都连不上先别管免密先把最基础的用户名密码登录打通再回头来配密钥。一步一步来出问题才好定位。1.3 开始之前需要确认的几件事动手前先花两分钟把这几个前提确认掉能省掉后面一半的排查时间。第一Ubuntu 得有一个能登录的账号并且知道密码后面要用它做一次密码登录来下发公钥。第二两台机器要在能互相访问的网络里同一局域网最省事跨网段就要看路由和端口映射了。第三要拿到 Ubuntu 的 IP 地址用ip addr或者hostname -I都能查记住那个形如 192.168.x.x 的地址。第四Windows 这边的 PowerShell 或者终端能正常使用后面生成密钥要用到。还有一点容易被忽略确认 Ubuntu 那台机器的系统时间是不是准的。SSH 握手对时间不敏感但有些认证机制会受影响而且时间乱掉通常意味着别的地方也有问题顺手看一眼没坏处。2. Ubuntu 端 SSH 服务的安装与调优2.1 装 openssh-server 并确认它在跑Ubuntu 桌面版默认只装了客户端服务端要手动装。登陆 Ubuntu打开终端执行sudo apt update sudo apt install -y openssh-server装完之后看服务状态systemctl status ssh正常的输出里会有active (running)字样。如果显示的是inactive或者根本找不到这个服务先看看是不是装失败了。顺手记一下这个服务名在 Ubuntu 上叫ssh不是sshd重启命令是sudo systemctl restart ssh别敲错了。再看一眼端口监听情况ss -tlnp | grep :22有输出说明 22 端口已经处于监听状态。如果你的 Ubuntu 是用虚拟机装的这里还有一个大坑虚拟机的网络模式如果是 NAT宿主机访问虚拟机需要做端口转发或者干脆改成桥接模式让虚拟机在局域网里有一个独立 IP省掉一堆麻烦。我早期用 NAT 模式折腾了半天端口映射后来改用桥接世界一下就清净了。2.2 sshd_config 里真正值得改的几个参数配置文件在/etc/ssh/sshd_config改之前先备份sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak这个文件里参数很多但大多数默认值就够用真正值得关注的是下面这几个。第一个是PubkeyAuthentication免密登录靠它默认是 yes确认一下别被注释掉或者改成 no。第二个是PasswordAuthentication配免密的时候先保持 yes因为你要用一次密码登录把公钥送上去。等免密验证通过之后可以按需决定要不要关掉但关掉之前一定要确认密钥登录确实能用否则会把自己锁在门外。第三个是AuthorizedKeysFile它决定去哪里找公钥默认值是.ssh/authorized_keys一般不用动但如果你看到有人把它改成别的路径公钥就得放到对应位置去。第四个是PermitRootLogin不建议用 root 直接连日常用普通账号需要提权的时候 sudo 就行。改完之后一定要先做语法检查再重启服务这一步千万别省sudo sshd -t没有输出就是配置没问题有输出会告诉你哪一行出了什么错。然后sudo systemctl restart ssh注意sshd -t这个检查必须养成习惯。配置文件写错一个字母重启服务就失败如果你这时候又刚好把当前连接关了那就只能去物理机前面敲键盘了。2.3 网络连通性和防火墙别漏掉服务跑起来了不代表外面能连进来。先在 Ubuntu 上看防火墙状态sudo ufw status如果显示Status: active那就要放行 22 端口sudo ufw allow 22/tcp如果显示Status: inactive那这一层就不用管了。不过云主机的情况不太一样云服务商那边通常还有一层安全组或者网络访问控制需要去控制台里手动放行 22 端口这个在本地虚拟机上不存在但用云主机的人经常忘掉。验证连通性最直接的办法是在 Windows 上 ping 一下ping 192.168.x.x能通说明网络层没问题。ping 不通的话先检查两台机器是不是在同一个网段再用ip addr核对一下 IP 有没有看错。有些网络环境会屏蔽 ICMPping 不通但 SSH 能连所以 ping 通不通只是一个参考最终还是要靠 SSH 连接来验证。3. 免密登录的原理与完整配置3.1 非对称加密到底谁在验谁免密登录用的是非对称加密一对密钥私钥和公钥。私钥留在你自己的 Windows 上绝对不能外传公钥放到 Ubuntu 上谁都能看不保密。登录的时候Ubuntu 拿你留在它那儿的公钥出一道只有对应私钥才能答对的题你的 Windows 用私钥算出答案发回去对上了就放你进来全程密码不出场。用一个不太严谨但好记的类比公钥像是一把锁你把它挂在 Ubuntu 的门上私钥是唯一能开这把锁的钥匙一直揣在自己兜里。别人拿到锁也开不了门因为钥匙不在他手上。所以整个流程的关键就两件事一把好钥匙和一把挂对位置的锁。注意私钥文件的权限必须是只有你自己能读。在 Linux 上 SSH 会强制检查这一点权限太开放会直接拒绝使用。Windows 这边相对宽松但也不能随便丢在共享目录里。3.2 在 Windows 端生成密钥对打开 PowerShell先看看有没有现成的密钥ls ~/.ssh如果没有id_rsa或者id_ed25519这类文件就生成一个。现在推荐用 ed25519比传统的 RSA 更短、更快安全性也不差ssh-keygen -t ed25519 -C your_emailexample.com执行后会问你保存路径直接回车用默认值就行会生成在C:\Users\你的用户名\.ssh\下面。然后会问你设不设密码短语这里就是免密和更安全的取舍点了。设了密码短语私钥被偷走也用不了但每次连接都要输一遍那免密的意义就打了折扣除非你配合 ssh-agent 把密码缓存在内存里。不设的话私钥文件本身就是唯一凭证谁拿到谁能登所以文件权限和电脑本身的安全性就更重要。我个人的做法是自己的开发机、只有自己用不设如果是共用电脑或者安全要求高的场景设上然后用代理来缓存。生成完之后ls ~/.ssh应该能看到两个文件一个是id_ed25519私钥一个是id_ed25519.pub公钥。认准带.pub后缀的那个那是要送到 Ubuntu 上去的。3.3 把公钥送上去并锁死权限送公钥最省事的办法是ssh-copy-id但 Windows 上这个命令不一定有所以我一般用更通用的方式。先在 PowerShell 里把公钥内容打出来cat ~/.ssh/id_ed25519.pub复制那一整行输出注意从头到尾别漏字符也别多空格。然后 SSH 登录到 Ubuntu在目标账号下执行mkdir -p ~/.ssh chmod 700 ~/.ssh vi ~/.ssh/authorized_keys把刚才复制的那行公钥粘贴进去保存退出。然后权限收紧chmod 600 ~/.ssh/authorized_keys这里三个权限数字要记牢.ssh目录是 700只允许所有者读写执行authorized_keys是 600只允许所有者读写。权限不对是免密失败最常见的原因之一SSH 会认为这个文件不可信直接跳过公钥认证回退到密码。如果 Ubuntu 上装了 ssh-copy-id 而在 Windows 上又想偷懒也可以在 PowerShell 里用一条管道命令type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh user192.168.x.x mkdir -p ~/.ssh cat ~/.ssh/authorized_keys这条命令的意思是把本地公钥内容通过 SSH 管道送过去追加到远程的 authorized_keys 里。第一次执行会要求输密码输完之后公钥就到位了。不过追加操作不会自动帮你处理权限所以传完还是要登上去确认一下 chmod 有没有做对。验证免密是否生效直接在 Windows 上连一次ssh user192.168.x.x如果这次没有提示输密码就进去了说明配置成功。如果还要密码就用-v参数看详细日志ssh -v user192.168.x.x日志里会明确告诉你公钥认证是成功还是被拒绝了被拒绝的原因通常也会写出来顺着找基本都能定位。3.4 写一份能长期用的 ssh config每次连接都要敲一长串ssh user192.168.x.x时间长了也烦而且 VS Code 远程连接同样要用到这个信息。解决办法是在 Windows 上写一个 config 文件路径是C:\Users\你的用户名\.ssh\config没有就新建一个Host dev-ubuntu HostName 192.168.x.x User yourname Port 22 IdentityFile ~/.ssh/id_ed25519 ServerAliveInterval 30 ServerAliveCountMax 6配好之后连接只需要ssh dev-ubuntu这里有两个参数值得单独说。ServerAliveInterval是每隔 30 秒给服务器发一个保活包ServerAliveCountMax是连续 6 次没回应才断开算下来大概三分钟没有任何响应才会判定掉线。这两个参数对于防止长时间空闲被防火墙掐断连接特别有用尤其是那种一挂机就被断开的环境加上之后稳定很多。提示config 里给主机起一个好记的别名很重要VS Code 的 Remote-SSH 会直接读取这个文件别名会出现在它的主机列表里点一下就连接不用记 IP。4. VS Code 侧的连接与远程环境4.1 插件安装和第一次连接在 Windows 的 VS Code 里打开扩展面板搜索 Remote-SSH安装 Microsoft 官方那个。装完之后左侧活动栏会多出一个远程连接的图标点开鼠标悬停在 SSH 那一栏上能看到加号和齿轮图标。一般不需要手动添加主机因为插件会读取你刚写的 ssh config 文件。点齿轮进入设置或者直接点刷新配置好的主机别名就会出现。鼠标移到主机名右边点那个新建窗口连接的图标VS Code 就会开始连接过程。首次连接会弹出一堆东西询问远程主机的操作系统类型选 Linux询问是否信任这个主机选继续然后它会在远程端下载并安装一个 VS Code Server这一步需要远程机器能访问下载源网络好的话几十秒就完事。连接成功后左下角的状态栏会出现类似SSH: dev-ubuntu的字样这时候打开文件夹看到的就是 Ubuntu 上的真实目录结构了。终端菜单里打开新终端跑的是远程的 shelluname -a会显示 Linux 内核信息确认一下没连错机器。4.2 首次连接在远程端做了什么了解这一步能帮你排查很多连接卡住的问题。VS Code 不是凭空变出远程能力的它会在远程机器上做这么几件事第一检查~/.vscode-server目录如果不存在或者版本对不上就从服务器下载对应的服务端程序第二解压并启动一个 node 进程第三本地和远程之间建立一个端口转发把通信跑在 SSH 隧道里。所以卡在正在打开远程这类提示时方向就很清楚了要么是远程端下载失败要么是服务端进程起不来要么是隧道建立不了。用ps aux | grep vscode在远程端看进程有没有起来看~/.vscode-server目录里有没有内容基本就能判断卡在哪一环。如果远程机器网络受限下载服务端会一直失败。这种时候可以在本地的 VS Code 设置里找到 Remote-SSH 的相关选项配置一个能访问的下载地址或者在能联网的机器上把服务端包提前下好手动放到对应的目录里。虽然麻烦但比一直卡着强。4.3 远程端扩展和本地扩展要分开看连接远程之后扩展面板会分成两块本地安装的和远程安装的。这个设计很有讲究因为不是所有扩展都适合装在远程。Python、C/C、Go、Rust 这类语言支持扩展需要在远程装因为它们要调用目标平台上的解释器、编译器和调试器装在本地没用。主题、图标、快捷键、大部分纯界面类的扩展装在本地就行装了远程反而浪费资源。还有个别的扩展支持在两边都装按需选择。实操里最常遇到的坑是本地看着扩展都在连上远程发现代码没有语法高亮、没有补全。这时候去扩展面板看看远程那一栏是不是空的把语言扩展在远程端重新装一遍就好了。判断的标准很简单——需要执行目标平台程序的装远程只影响界面外观的装本地。5. 踩坑实录与排查速查表5.1 连接类问题的定位顺序连不上是最常见的问题别一上来就瞎改配置按下面的顺序查基本三步内能定位。现象可能原因排查方法Connection refusedSSH 服务没跑或端口不对systemctl status ssh确认 22 端口监听Connection timed out网络不通或被防火墙拦ping 测试检查 ufw 和云安全组Permission denied用户名或认证方式不对用-v看日志确认公钥是否被接受一直提示输密码免密没生效检查权限 700/600 和公钥内容是否完整卡在打开远程服务端下载失败看远程~/.vscode-server目录这里有几个我自己踩过的细节。公钥粘贴的时候如果是从网页或者聊天工具复制的末尾可能带上了换行或者空格粘进去就废了所以一定要用纯文本编辑器打开公钥文件直接复制内容。还有一种情况是authorized_keys里有多行内容某一行格式错了会导致整个文件解析出问题建议一行一行确认。另外ssh-copy-id在 Windows 上的缺失确实是个小麻烦但用管道命令能绕过前面给过写法。5.2 免密失效类问题怎么查明明配过了隔几天又开始要密码这种情况我遇到过好几次原因基本集中在三类。第一类是权限被改回去了。有时候是脚本、有时候是手动操作把.ssh目录或者authorized_keys的权限放宽了SSH 一检查不通过就回退到密码认证。用ls -ld ~/.ssh和ls -l ~/.ssh/authorized_keys确认权限不对就 chmod 回来。第二类是换了电脑或者重装系统生成了一套新的密钥但公钥没同步到远程或者远程authorized_keys里还是旧的那把。这种要靠ssh -v的日志确认它会告诉你用了哪个私钥文件、公钥是哪个指纹。第三类是 ssh-agent 里加载了错误的密钥。Windows 的 OpenSSH 如果启用了 agent 服务可能会优先使用 agent 里的密钥而你 config 里指定的又是另一个两者对不上就失败。可以清一下 agent 里的密钥或者明确指定 IdentityFile。注意SSH 的日志非常诚实几乎所有的认证失败都会在-v的输出里留下线索。别猜先看日志。5.3 让远程体验更顺手的几个设置连接稳定之后还有一些小调整能让日常用起来舒服很多。文件保存时的自动上传、终端里的中文显示、远程端的编码格式这些都是容易被忽略但影响体验的点。终端中文乱码通常是远程的 locale 没设置好或者终端编码不对。可以在 Ubuntu 上确认一下locale的输出把需要的语言环境装齐再把默认编码设成 UTF-8。这属于远程环境本身的配置不是 VS Code 的问题但会直接影响你写代码时看注释的心情。再一个是把常用的端口转发配好。如果你在远程跑了个 Web 服务或者数据库VS Code 能自动检测到端口并提示转发也在面板里手动加转发规则就行。这样一来本地浏览器就能直接访问远程服务的页面调试前端的时候特别方便不用再去折腾网络配置。最后说个我自己的习惯把 ssh config 里的主机别名起得短一点、有意义一点比如dev、test、prod分开然后在 VS Code 里按别名连接。时间长了你会发现这套组合拳打顺了之后本地和远程的界限会变得很模糊你只需要关心代码本身剩下的交给 SSH 和 VS Code 去处理就行了。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门