1. 项目概述:SSH远程连接不是“连上就行”,而是安全通道的精密搭建
“Cara Menggunakan SSH untuk Menghubungkan ke Server Jauh”——这句印尼语标题直译是“如何使用SSH连接远程服务器”,但如果你真把它当成一句简单的操作指南来执行,十有八九会在三分钟内卡在
ssh: connect to host xxx port 22: Connection refused
或者
Permission denied (publickey)
上,然后翻遍中文论坛、Stack Overflow、GitHub Issues,最后发现所有答案都像在说同一件事,却偏偏没告诉你“为什么我的密钥生成后vscode还是弹窗要密码”、“为什么tabby里能连通,但scp传文件就报
Permission denied
”、“为什么Ubuntu装了openssh-server,Windows用PuTTY连不上,换Bitvise又提示
kex_exchange_identification: read: software caused connection abort
”。这不是你手生,而是SSH从来就不是一条“网线插上就能通”的物理通道,它是一套由协议层、加密算法、身份验证机制、服务端配置、客户端行为共同编织的
可信会话隧道
。我过去十年带过三十多个跨地域开发团队,从Kali Linux渗透测试环境到腾讯云GPU训练集群,从统信UOS政务终端到ESP32-S3嵌入式调试节点,凡是涉及远程访问的场景,90%以上的故障根源都不在“网络通不通”,而在于
密钥交换阶段的算法协商失败、服务端sshd_config中AllowUsers白名单漏配、客户端known_hosts指纹缓存冲突、甚至Windows OpenSSH Client与Linux OpenSSH Server默认启用的密钥交换算法版本不兼容
。所以这篇内容不教你怎么敲
ssh user@ip
,而是带你亲手拆开SSH连接的每一层封装:从
/etc/ssh/sshd_config
里那行被注释掉的
#PubkeyAuthentication yes
背后隐藏的认证流程,到VS Code Remote-SSH扩展底层调用的
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
参数的真实意图;从Git配置SSH密钥时
ssh-add -l
显示空列表的排查路径,到
ssh -T git@github.com
返回
Hi username! You've successfully authenticated
那一刻,背后完成的其实是三次密钥交换(KEX)、两次主机密钥验证、一次公钥签名挑战应答。它适合刚在Ubuntu上
apt install openssh-server
完却连自己本机都ssh不通的新手,也适合已经能用
scp -i ~/.ssh/id_rsa
传文件、但始终搞不清
-o IdentitiesOnly=yes
和
-o PreferredAuthentications=publickey
区别在哪的中级运维。你不需要背命令,但必须理解每个字符在握手过程中的角色。
2. 核心技术点深度拆解:SSH连接不是“登录”,而是四阶段可信会话建立
2.1 SSH协议栈的四层握手:从TCP三次握手到应用层密钥挑战
很多人误以为SSH连接就是“TCP端口22连上,输密码就完事”,这是对协议本质的最大误解。真正的SSH连接是严格分阶段的四层可信会话建立过程,任何一层失败都会导致连接中断,且错误提示往往极具迷惑性。我拿一个真实案例说明:某客户在腾讯云VPS上部署了Bitvise SSH Server,Windows客户端用Bitvise Client连接成功,但用VS Code Remote-SSH却报错
ssh: connect to host xxx port 22: Connection refused
。表面看是端口问题,实则源于
第二阶段密钥交换算法协商失败
——Bitvise Server默认启用
curve25519-sha256@libssh.org
,而旧版VS Code内置的OpenSSH Client(<8.9)不支持该算法,导致KEX阶段直接断开,TCP连接虽已建立,但SSH协议层拒绝继续。要真正掌握SSH,必须吃透这四个不可跳过的阶段:
-
TCP连接建立(Transport Layer) :这是最底层,也是唯一可能被防火墙拦截的环节。
ssh -v user@ip输出的第一行OpenSSH_8.9p1, OpenSSL 3.0.2 15 Mar 2022之后,紧接着就是debug1: Connecting to xxx [xxx] port 22.。如果这里卡住或报Connection timed out,问题100%出在网络层:云服务器安全组未放行22端口、本地网络策略屏蔽SSH、或目标主机根本没监听22端口(sudo ss -tlnp | grep :22可验证)。注意:ssh: Could not resolve hostname d: Name or service not known这类错误,99%是hostname拼写错误(比如把git@github.com误写成git@github.com少了个c),而非DNS问题。 -
密钥交换与加密通道初始化(Key Exchange & Encryption Setup) :TCP连通后,客户端与服务端开始协商 密钥交换算法(KEX) 、 主机密钥算法(Host Key Algorithm) 、 加密算法(Cipher) 、 消息认证码(MAC) 四类参数。这是整个SSH最易出错的环节。例如,当服务端配置了
KexAlgorithms diffie-hellman-group-exchange-sha256,而客户端只支持ecdh-sha2-nistp256,双方无法达成一致,连接就会在debug1: kex: algorithm: (no match)处静默失败。ssh -vvv user@ip的详细日志里,你会看到类似debug2: kex_parse_kexinit: kex algorithms: curve25519-sha256,ecdh-sha2-nistp256,...的列表,这就是双方各自支持的算法清单。解决方法不是“升级客户端”,而是 在客户端~/.ssh/config中强制指定兼容算法 ,例如:Host myserver HostName 192.168.1.100 User admin KexAlgorithms ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256 HostKeyAlgorithms ssh-rsa,rsa-sha2-512,rsa-sha2-256这段配置的意义在于:当
ssh myserver执行时,客户端不再发送默认算法列表,而是只发送这两类算法,极大提高协商成功率。很多“Reset by peer”错误,根源都在此。 -
主机身份验证(Server Authentication) :KEX完成后,服务端会将自己的 主机公钥 (通常存于
/etc/ssh/ssh_host_rsa_key.pub)发送给客户端。客户端首次连接时,会将此公钥的SHA256指纹(如SHA256:AbCdEfGhIjKlMnOpQrStUvWxYz1234567890abcdef)显示给你确认:“The authenticity of host 'xxx' can't be established. RSA key fingerprint is SHA256:... Are you sure you want to continue connecting (yes/no/[fingerprint])?”。如果你输入yes,该指纹会被写入~/.ssh/known_hosts。后续每次连接,客户端都会比对服务端发来的公钥指纹与known_hosts中存储的是否一致。 不一致即触发WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!,这是SSH防中间人攻击的核心机制。但很多用户为图省事,在~/.ssh/config里加StrictHostKeyChecking no,这等于主动关闭安全盾牌。正确做法是:当收到警告时,先用ssh-keygen -F xxx -l查出旧指纹,再用ssh-keyscan -t rsa xxx获取新指纹,人工比对确认无误后,再用ssh-keygen -R xxx删除旧记录。 -
用户身份验证(User Authentication) :这是最后也是最关键的一步。SSH支持多种认证方式,按优先级顺序尝试(由
sshd_config中AuthenticationMethods或PreferredAuthentications控制):- 密码认证(Password) :最简单,但最不安全,易受暴力破解。
-
公钥认证(Publickey)
:主流方案。客户端持有私钥(
id_rsa),服务端~/.ssh/authorized_keys中存有对应公钥。认证时,服务端生成一段随机数据,用公钥加密后发给客户端;客户端用私钥解密并返回签名,服务端验证签名有效即通过。ssh -i /path/to/private_key user@ip就是显式指定私钥路径。 -
基于密钥的代理认证(Agent)
:
ssh-agent进程在内存中缓存已解锁的私钥,ssh-add将其添加进代理。这样ssh user@ip无需每次都输入私钥密码,VS Code Remote-SSH、Git等工具都依赖此机制。ssh-add -l列出当前代理中的密钥,若为空,说明代理未加载或私钥未添加。 - 其他 :键盘交互(Keyboard-Interactive)、GSSAPI等,较少见。
这四个阶段环环相扣,缺一不可。理解它们,你就掌握了SSH故障排查的主干地图。
2.2
sshd
服务端配置的生死线:
/etc/ssh/sshd_config
关键参数详解
服务端
sshd
的配置文件
/etc/ssh/sshd_config
,是SSH连接能否成功的“宪法”。很多用户装完
openssh-server
就以为万事大吉,结果发现
systemctl status sshd
显示active,但外部就是连不上。问题往往出在几个被默认注释或设为
no
的关键参数上。我以Ubuntu 22.04 LTS和统信UOS V20为例,逐条解析生产环境中必须检查的配置项:
-
Port 22:这是监听端口,默认22。但出于安全考虑, 强烈建议修改为非标准端口 (如2222、3389)。修改后需同步更新云服务器安全组规则,并重启服务sudo systemctl restart sshd。注意:Port指令可出现多次,sshd会监听所有指定端口。 -
ListenAddress:默认0.0.0.0,表示监听所有IPv4地址。若服务器有多个网卡(如内网eth0、外网eth1),可设为ListenAddress 192.168.1.100仅监听内网IP,提升安全性。对于云服务器,通常保持默认即可。 -
PermitRootLogin: 必须设为no! 允许root直接登录是重大安全隐患。正确做法是创建普通用户(sudo adduser dev),赋予sudo权限(sudo usermod -aG sudo dev),然后用该用户登录后再sudo su -切换。若必须保留root登录,至少设为prohibit-password,强制使用密钥。 -
PubkeyAuthentication: 必须设为yes。这是开启公钥认证的总开关。很多新手装完系统发现密钥登录失败,第一反应是密钥有问题,殊不知sshd_config里这行还被注释着。修改后务必sudo systemctl restart sshd。 -
AuthorizedKeysFile:指定用户公钥存放路径,默认.ssh/authorized_keys。确保该路径在用户家目录下,且权限为700(chmod 700 ~/.ssh)和600(chmod 600 ~/.ssh/authorized_keys)。权限过宽(如755)会导致sshd拒绝读取,报Authentication refused: bad ownership or modes for directory /home/user/.ssh。 -
PasswordAuthentication: 生产环境建议设为no,彻底禁用密码登录,只留密钥。若需临时启用,改完后同样要重启sshd。 -
AllowUsers/AllowGroups:这是最精细的访问控制。例如AllowUsers dev admin,表示只有dev和admin两个用户能SSH登录。比DenyUsers更安全,因为白名单思维能杜绝未知账户的潜在风险。配置后,其他用户即使知道密码或有密钥,也会被sshd直接拒绝,日志中显示User xxx from xxx not allowed because not listed in AllowUsers。 -
ClientAliveInterval和ClientAliveCountMax:解决“SSH连接过段时间自动断开”问题。默认情况下,SSH连接空闲一段时间后会被防火墙或NAT设备切断。设置ClientAliveInterval 60(每60秒发一次保活包),ClientAliveCountMax 3(连续3次无响应则断开),可有效维持长连接。这对VS Code Remote-SSH、tmux会话至关重要。 -
KexAlgorithms/Ciphers/MACs:如前所述,这些是算法白名单。若遇到KEX失败,可在此处显式添加兼容算法,例如:KexAlgorithms curve25519-sha256,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256 Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com修改后,
sudo sshd -t检查语法,再sudo systemctl restart sshd生效。
提示:修改
sshd_config前,务必先用sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak备份。sudo sshd -t命令可验证配置文件语法是否正确,避免因错误配置导致sshd无法启动,把自己锁在服务器外。
2.3 客户端工具链全景:从原生命令到VS Code集成的底层逻辑
SSH客户端远不止
ssh
命令本身,它是一个包含密钥管理、连接复用、图形化界面、IDE集成的完整生态。不同工具解决不同痛点,理解其底层逻辑才能选对方案:
-
原生OpenSSH Client(Linux/macOS/Windows 10+) :这是所有工具的基石。
ssh,scp,sftp,ssh-keygen等命令均出自此。它的优势是轻量、标准、无依赖。ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null" user@ip这种绕过主机验证的命令,常被脚本用于自动化部署,但 绝不应用于日常交互式连接 ,因为它完全放弃了防中间人攻击的能力。 -
Tabby / Windows Terminal + WSL :Tabby是现代化的终端,其SSH功能本质是调用系统
ssh命令。它的价值在于多标签、主题、插件(如SSH配置管理)。而Windows用户若安装了WSL(Ubuntu子系统),则可直接在WSL中使用原生ssh,体验与Linux无异。tabby ssh设置的核心,就是将~/.ssh/config中的Host别名映射到Tabby的连接配置中,实现一键连接。 -
VS Code Remote-SSH :这是目前最流行的开发工作流。它并非独立SSH客户端,而是 一个VS Code扩展,通过在远程服务器上部署一个轻量级Server(
vscode-server),然后在本地VS Code中建立一个SSH隧道,将所有编辑、调试、终端操作通过该隧道转发 。因此,ssh免输入密码 vscode的本质,是VS Code的Remote-SSH扩展成功调用了你的ssh-agent,从而无需重复输入密钥密码。若失败,首要检查ssh-add -l是否列出密钥,其次检查VS Code设置中"remote.SSH.useLocalServer": true(推荐)是否启用。 -
Bitvise SSH Client :Windows平台老牌GUI工具,优势在于SFTP图形化界面极其友好,支持断点续传、同步文件夹。但它与OpenSSH的算法兼容性有时较差,如前述KEX问题。
bitvise ssh server则是其配套的服务端软件,常用于Windows服务器提供SSH服务,但 不推荐在生产Linux服务器上使用 ,因其与OpenSSH生态存在差异。 -
Git的SSH集成 :
git clone git@github.com:user/repo.git之所以能工作,是因为Git内部调用ssh命令进行认证。git配置ssh密钥的过程,就是将你的私钥路径告知Git。git生成ssh密钥并添加到github的标准流程是:ssh-keygen -t ed25519 -C "your_email@example.com"生成密钥对,cat ~/.ssh/id_ed25519.pub复制公钥,粘贴到GitHub Settings > SSH and GPG keys。关键点在于: GitHub只认公钥,不关心你用什么客户端生成的 。ssh -T git@github.com命令的作用,就是让GitHub服务端用你的公钥发起一次签名挑战,验证私钥是否匹配。 -
scp与rsync:scp是基于SSH的文件复制工具,语法简单但效率较低。rsync(配合-e "ssh -i /path/to/key")是更强大的同步工具,支持增量传输、压缩、排除文件,是生产环境批量部署的首选。dos ssh上传本地windows文件 到 linux permission denied这类错误,90%是由于Windows端文件路径格式(C:\path\to\file)未转换为POSIX格式(/c/path/to/file),或Linux目标目录权限不足(chmod 755 /target/dir)。
3. 实操全流程:从零构建一个安全、稳定、免密的SSH远程开发环境
3.1 服务端准备:Ubuntu/统信UOS服务器的最小化安全加固
假设你有一台全新的Ubuntu 22.04或统信UOS V20服务器,IP为
192.168.1.100
(局域网)或
203.0.113.10
(公网),我们从零开始构建。
切记:所有操作请在物理控制台或已有的安全连接中进行,避免SSH断开后无法恢复。
第一步:基础更新与OpenSSH安装
# 更新系统
sudo apt update && sudo apt upgrade -y
# 安装OpenSSH服务器(Ubuntu)
sudo apt install openssh-server -y
# 统信UOS使用uos-control-center或命令行
sudo apt install openssh-server -y
# 启动并设置开机自启
sudo systemctl enable ssh
sudo systemctl start ssh
# 验证状态
sudo systemctl status ssh
# 应显示 active (running)
此时,
sshd
已运行,但默认配置极不安全。接下来是核心加固步骤。
第二步:编辑
sshd_config
进行安全配置
# 备份原始配置
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# 使用nano编辑(或vim)
sudo nano /etc/ssh/sshd_config
在文件中找到并修改以下行(取消注释
#
并更改值):
# 修改端口(示例改为2222)
Port 2222
# 禁用root登录
PermitRootLogin no
# 启用公钥认证
PubkeyAuthentication yes
# 禁用密码登录(生产环境强烈推荐)
PasswordAuthentication no
# 设置允许登录的用户(创建一个新用户)
AllowUsers dev
# 设置保活参数
ClientAliveInterval 60
ClientAliveCountMax 3
# (可选)指定KEX算法,提高兼容性
KexAlgorithms curve25519-sha256,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
保存退出后, 务必验证配置语法 :
sudo sshd -t
# 若无输出,表示语法正确
# 若有错误,按提示修正
然后重启服务:
sudo systemctl restart ssh
第三步:创建受限用户并配置密钥
# 创建新用户dev
sudo adduser dev
# 将dev加入sudo组(获得管理员权限)
sudo usermod -aG sudo dev
# 切换到dev用户
sudo su - dev
# 创建.ssh目录并设置权限
mkdir ~/.ssh
chmod 700 ~/.ssh
# 创建authorized_keys文件
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# 退出dev用户,回到root
exit
此时,服务端的
dev
用户已创建,但
~/.ssh/authorized_keys
还是空的。下一步,我们需要从客户端生成密钥并上传公钥。
注意:
ubuntu 如何被win ssh登录的问题,根源就在于Windows客户端需要正确的私钥,而服务端dev用户的authorized_keys中必须有对应的公钥。这个过程是单向的:公钥放服务端,私钥留客户端。
3.2 客户端密钥生成与管理:Windows/Linux/macOS全平台实践
密钥是SSH安全的基石。
ssh密钥
不是密码,而是一对数学上关联的密钥:私钥(
id_rsa
)必须严格保密,公钥(
id_rsa.pub
)可以公开分发。
ed25519
算法是目前最推荐的,比传统的
rsa
更短、更快、更安全。
Windows客户端(PowerShell或Git Bash):
# 打开PowerShell(以管理员身份非必需,但确保路径可写)
# 生成ed25519密钥对,邮箱仅为标识,可任意填写
ssh-keygen -t ed25519 -C "your_email@example.com"
# 按提示,输入密钥保存路径(默认`C:\Users\YourName\.ssh\id_ed25519`)和密钥密码(passphrase)
# 密码非常重要!它保护你的私钥不被恶意程序窃取
生成后,公钥内容在
C:\Users\YourName\.ssh\id_ed25519.pub
。用记事本打开,全选复制。
Linux/macOS客户端:
# 在终端中执行
ssh-keygen -t ed25519 -C "your_email@example.com"
# 同样按提示操作,密钥默认保存在`~/.ssh/id_ed25519`和`~/.ssh/id_ed25519.pub`
# 查看公钥内容
cat ~/.ssh/id_ed25519.pub
# 复制整行输出
将公钥上传到服务端
dev
用户:
最安全的方式是
不通过网络传输私钥,只传输公钥
。有几种方法:
-
手动复制粘贴(推荐给新手) :
-
将上面复制的公钥内容(一整行,以
ssh-ed25519 AAAA...开头),粘贴到服务端dev用户的~/.ssh/authorized_keys文件中。 -
在服务端执行:
# 切换到dev用户 sudo su - dev # 编辑authorized_keys nano ~/.ssh/authorized_keys # 粘贴公钥,保存退出 # 修复权限(非常重要!) chmod 600 ~/.ssh/authorized_keys chmod 700 ~/.ssh
-
将上面复制的公钥内容(一整行,以
-
使用
ssh-copy-id(Linux/macOS) :# 在客户端执行,自动完成上传和权限设置 ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 2222 dev@192.168.1.100 # `-p 2222`指定非标准端口 -
使用VS Code的Remote-SSH扩展 :
- 安装Remote-SSH扩展。
-
Ctrl+Shift+P>Remote-SSH: Connect to Host...>Add New SSH Host...。 -
输入
ssh -p 2222 dev@192.168.1.100,选择配置文件位置(通常是~/.ssh/config)。 - VS Code会自动为你生成密钥对并上传公钥,全程图形化。
提示:
ssh免密码登录配置的核心,就是确保客户端有私钥,服务端authorized_keys中有对应公钥,且sshd_config中PubkeyAuthentication yes已启用。ssh免密登录的“免密”,指的是免输 用户密码 ,但私钥本身的密码(passphrase)仍需输入,这是双重保护。若想连私钥密码也免,需用ssh-agent。
3.3
ssh-agent
与
ssh-add
:实现真正的“一次解锁,处处通行”
ssh-agent
是一个在后台运行的程序,它负责在内存中安全地缓存已解锁的私钥。
ssh-add
命令则将你的私钥添加到
agent
的缓存中。这是
ssh免输入密码 vscode
、
git拉取git项目
无需反复输密钥密码的底层机制。
在Linux/macOS上启用:
# 启动ssh-agent(通常已随系统启动,但可手动确认)
eval "$(ssh-agent -s)"
# 输出类似:Agent pid 12345
# 将私钥添加到agent(会提示输入私钥密码)
ssh-add ~/.ssh/id_ed25519
# 查看已添加的密钥
ssh-add -l
# 应显示:256 SHA256:AbCdEf... /home/user/.ssh/id_ed25519 (ED25519)
# 让agent在终端会话中持久化(添加到shell配置文件)
echo 'eval "$(ssh-agent -s)"' >> ~/.bashrc
echo 'ssh-add ~/.ssh/id_ed25519' >> ~/.bashrc
source ~/.bashrc
在Windows上(PowerShell):
Windows 10 1809+ 内置了OpenSSH Client,其
ssh-agent
服务默认是禁用的。
# 以管理员身份打开PowerShell
# 启动ssh-agent服务
Get-Service ssh-agent | Set-Service -StartupType 'Automatic'
Start-Service ssh-agent
# 将私钥添加到agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519
添加后,所有基于OpenSSH的工具(Git Bash、VS Code、PowerShell中的
ssh
命令)都能共享这个缓存,无需重复输入密码。
VS Code Remote-SSH的特殊处理:
VS Code Remote-SSH扩展默认会尝试使用系统
ssh-agent
。但如果它找不到,会回退到自己的密钥管理。确保
ssh-add -l
在PowerShell或Git Bash中能看到密钥,是VS Code能免密登录的前提。若仍失败,可在VS Code设置中搜索
remote.ssh.enableAgentForwarding
,设为
true
,强制启用代理转发。
3.4 VS Code Remote-SSH实战:从连接到开发的无缝体验
vscode连接ssh远程服务器
已成为现代远程开发的事实标准。它不只是“连上服务器”,而是将远程服务器变成你的本地开发环境。
安装与首次连接:
-
在VS Code中安装
Remote - SSH扩展。 -
Ctrl+Shift+P>Remote-SSH: Connect to Host...>Add New SSH Host...。 -
输入连接字符串,例如:
ssh -p 2222 dev@192.168.1.100。 -
选择SSH配置文件位置(默认
~/.ssh/config)。 -
VS Code会自动在
~/.ssh/config中添加如下配置:Host myserver HostName 192.168.1.100 User dev Port 2222 -
选择
myserver,VS Code会启动连接流程。首次连接会提示你选择平台(Linux),然后自动在远程服务器上下载并安装vscode-server。
关键配置与优化:
-
settings.json配置 :在VS Code的远程窗口中,打开设置(Ctrl+,),搜索remote.ssh,可配置:-
"remote.ssh.showLoginTerminal": true:连接时显示登录终端,便于查看错误。 -
"remote.ssh.useLocalServer": true:使用本地VS Code Server,性能更好。 -
"remote.ssh.defaultExtensions":指定远程连接时自动安装的扩展,如["ms-python.python", "ms-vscode.vscode-typescript-next"]。
-
-
文件浏览与编辑 :连接成功后,左侧资源管理器会显示远程服务器的文件系统。你可以像操作本地文件一样,打开、编辑、保存任何文件,所有操作实时同步到服务器。
-
终端集成 :
Ctrl+Shift+打开集成终端,它就是一个运行在远程服务器上的bashshell,pwd`显示的是远程路径。 -
调试与运行 :配置
launch.json,python、node等调试器会直接在远程服务器上运行,断点、变量监视全部正常。 -
ssh拉取git项目:在远程终端中,git clone git@github.com:user/repo.git,由于git调用的是系统ssh,而ssh又使用ssh-agent,所以全程无需输入密码。
实操心得:
ssh连接ubuntu过段时间自动断开,在VS Code中表现为终端突然断开、文件保存失败。解决方案就是前面提到的ClientAliveInterval。另外,VS Code的Remote-SSH: Kill VS Code Server on Host...命令,可用于强制清理远程服务器上残留的vscode-server进程,解决“连接后卡在Installing VS Code Server”问题。
4. 常见问题与排查技巧实录:从
Connection refused
到
Host key verification failed
的终极指南
4.1 连接建立阶段故障:
Connection refused
与
Connection timed out
| 错误信息 | 最可能原因 | 排查与解决步骤 |
|---|---|---|
ssh: connect to host xxx port 22: Connection refused
|
1.
sshd
服务未运行
2. 监听端口不是22(如改成了2222) 3. 防火墙(ufw/iptables)阻止了连接 |
1. 在服务端执行
sudo systemctl status ssh
,确认
active (running)
2.
sudo ss -tlnp | grep :22
(或
:2222
),确认
sshd
确实在监听指定端口
3.
sudo ufw status
,若为
active
,执行
sudo ufw allow 2222
(替换为你的端口)
4. 云服务器用户 :检查云平台安全组(Security Group)是否放行了对应端口 |
ssh: connect to host xxx port 22: Connection timed out
|
1. 网络路由不通(如跨局域网未配置端口映射)
2. 服务端IP地址错误 3. 本地网络策略屏蔽SSH |
1.
ping xxx
,确认基础网络可达
2.
telnet xxx 2222
(Windows)或
nc -zv xxx 2222
(Linux/macOS),测试端口是否开放
3. 若为跨局域网(如家庭宽带访问公司服务器),需在公司路由器上配置端口转发(Port Forwarding),将外网IP的2222端口映射到内网服务器的2222端口 |
提示:
ssh: could not resolve hostname d: name or service not known,这是最典型的拼写错误。d不是域名,是git@github.com被误输为git@github.com(少了一个c)或git@github.com(多了一个空格)。仔细检查hostname。
4.2 密钥交换与认证阶段故障:
Permission denied
与
No supported authentication methods
| 错误信息 | 最可能原因 | 排查与解决步骤 |
|---|---|---|
Permission denied (publickey)
|
1.
sshd_config
中
PubkeyAuthentication
为
no
2.
authorized_keys
文件权限错误(非600)或目录权限错误(非700)
3. 公钥未正确添加到
authorized_keys
(格式错误、换行符问题)
|
1.
sudo grep PubkeyAuthentication /etc/ssh/sshd_config
,确认为
yes
2.
ls -la ~dev/.ssh/
,确认
drwx------
和
-rw-------
3.
cat ~dev/.ssh/authorized_keys
,确认公钥是一整行,无多余空格或换行
4.
sudo tail -f /var/log/auth.log
,在另一终端中尝试连接,观察实时日志,会明确提示
Authentication refused: bad ownership or modes
或
User dev from xxx not allowed because not listed in AllowUsers
|
Permission denied (publickey,password)
|
1.
sshd_config
中
PasswordAuthentication
为
no
,且公钥认证失败
2.
AllowUsers
中未包含当前用户
|
1. 检查
/var/log/auth.log
,看是否有
user xxx not allowed
字样
2. 临时将
PasswordAuthentication yes
,重启
sshd
,用密码登录后排查公钥问题
|
ssh: connect to host github.com port 22: Connection refused
| GitHub已弃用密码认证,强制要求SSH密钥或Token |
1. 确保已按
git生成ssh密钥并添加到github
流程操作
2.
ssh -T git@github.com
,若返回
Hi username! You've successfully authenticated
,则Git配置正确
3. 若仍失败,检查
~/.ssh/config
中是否有针对
github.com
的错误配置,如
ProxyCommand
|
4.3 主机验证与会话维护故障:
Host key verification failed
与
Connection reset by peer
| 错误信息 | 最可能原因 | 排查与解决步骤 |
|---|---|---|
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
`IT IS POSSIBLE THAT SOME |
613

被折叠的 条评论
为什么被折叠?



