不知道你有没有经历过这个场景:刚在 VMware 里装好 Ubuntu,兴致勃勃打开 Finalshell 准备体验一下远程命令行操作,结果新建会话、输入密码、回车,屏幕上没有出现期待已久的 welcome to Ubuntu,而是又弹出一个密码输入框。再输一次,又弹出来;换大小写、换密码组合、甚至把安装 Ubuntu 时设置的密码背了一遍又一遍,还是弹。最后你怀疑是自己密码记错了,跑到虚拟机里登录,发现密码明明是对的。
这个场景我调试过不下五十次——不夸张,几乎每个刚接触 Linux 虚拟机的人都栽在这。问题本身不难,但坑点特别多:服务端没装 SSH、配置文件被覆盖、网络模式选错、Finalshell 客户端自己缓存了旧密码,每一环都能让"密码"像一个幽灵一样反复出现。这篇文章我按真实排查顺序把各种典型情况拆一遍,从服务端到客户端、从原理到操作,尽量一次性把你的问题解决干净。
1. 这个"输密码死循环"到底卡在哪一环
1.1 先分清:你输入的是 SSH 密码,不是开机登录密码
很多人第一步就搞混了。Ubuntu 安装向导里设置的那个密码,在系统层面是当前用户的登录密码,SSH 远程登录时用的"密码"其实也是同一个——它最终是去 /etc/shadow 文件里做密码验证,这一点没什么特殊。特殊的地方在于,你的虚拟机上跑的可能不是标准安装镜像,而是某些预置环境、模板或者云镜像(cloud image),这种环境下系统里有一个默认用户,密码可能是随机生成的,也可能从来没被设置过,甚至文档里明确写了"请通过控制台重置密码后再登录"。
这里就出现了一个很经典的错位:你以为你输入的是虚拟机开机时那个密码,但 SSH 服务端那边根本拿不到匹配的密码,于是每次都冷酷地返回"password incorrect",客户端就继续弹窗让你重试。判断方法很简单:在虚拟机本机界面打开终端,用你记忆中的用户名和密码执行一次 su - 或者直接登录桌面,看看能不能进。能进,说明系统和密码没问题,问题在 SSH 服务侧;不能进,那就是密码记忆有问题,直接在虚拟机里用 sudo passwd 用户名 重置一下再说。
还有一个新手特别容易踩的坑:用 root 去连。Ubuntu 默认 root 账号是锁定的,安装时设置的那个用户是普通用户,即使你安装时把它命名为 root 或者感觉"管理员就是 root",SSH 时也必须用安装时创建的那个用户名,而不是直接输 root 加密码。我一直建议刚入门的人:先老老实实用安装时创建的用户(比如 ubuntu、dev、test 这种)做 SSH 登录,等能连通了,再研究怎么切 root、改配置。
1.2 "一直提示输密码"的四种典型表现与真正病因
我把这些年见过的问题归成四类,你可以先对上号,再往下看具体解决办法。
第一类是最容易让人疑惑的:Finalshell 弹密码框,输完密码后过了一两秒又弹出来,中间偶尔夹杂一段英文提示 Permission denied, please try again。这种属于认证层失败,服务端能收到你的连接请求,但密码或用户名不对,或者服务端明确禁止密码认证。大多数人的问题都出在这。
第二类:密码框弹出来,但你还没输完或者刚回车,直接显示 Connection refused。这说明网络能通,但目标机器的 22 端口根本没有 SSH 服务在监听。很多精简版 Ubuntu、或者装桌面版时没选 OpenSSH 组件的环境都会这样——系统是好的,但压根没有"接待访客"的服务程序,自然谈不上验证密码。
第三类:一直卡在 connecting... 或者提示 connect timed out,密码框压根不出现,或者出现了但每次都是超时。这是网络层不通,和密码一点关系都没有。虚拟机 IP 填错了、VMware 网络模式不对、虚拟机网卡没起来,都会这样。
第四类属于 Finalshell 客户端自己的"小脾气":某个会话之前保存过错误密码或者错误认证方式,之后你每次双击连接,它都用旧参数去连,失败后重新弹出密码框,但你以为它让你输入新密码,其实它在反复用旧密码尝试。这种最坑,因为你在密码框里怎么改都没用。解决办法是把会话删掉重新建一个,或者在会话属性里重新选择密码认证方式并清空旧密码。我自己就犯过这个错,当时折腾了半个多小时,最后删会话重连立马就通了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从虚拟机到 Finalshell:三步搭建可用连接
2.1 第一步:确保 Ubuntu 里 SSH 服务真的存在且在运行
绝大多数 Ubuntu 桌面版安装完以后,默认是不带 OpenSSH Server 的——注意,是服务器组件,不是客户端。Finalshell 连接时要求的正是服务端。你可以先打开终端验证一下:
bash复制dpkg -l | grep openssh-server
systemctl status ssh
第一条命令如果什么都没有返回,说明压根没安装;第二条命令如果提示 Unit ssh.service could not be found,同样说明没装。此时直接安装并启动:
bash复制sudo apt update
sudo apt install openssh-server -y
sudo systemctl enable --now ssh
这里解释一下为什么要加 enable --now 两个参数:enable 是让 SSH 服务开机自启,防止你重启虚拟机后又连不上;--now 是立即启动服务,不用等重启。很多教程只说 systemctl start ssh,结果虚拟机重启一次,服务又没了,又要去控制台手动开,非常烦人。安装完后再执行一次:
bash复制systemctl status ssh
看到绿色的 active (running),或者提示服务正在运行,这一步就算过了。顺手再用一条命令确认端口已经监听:
bash复制ss -tlnp | grep :22
只要能看到类似 LISTEN 0 128 0.0.0.0:22 的输出,说明 SSH 服务已经正常挂在 22 端口了。这时候在虚拟机本机执行 ssh 用户名@localhost,输入密码,如果再本机都连不上,问题一定在服务端或密码侧,和 Finalshell 没关系。
2.2 第二步:用 IP、日志把"网络层"和"认证层"分开
很多人拿到一台虚拟机,第一反应是看 VMware 界面右上角的 IP 信息,但那个 IP 可能早就变了,或者显示的是内网 DHCP 分配的地址,并不一定是 Finalshell 能直接连的那个。正确做法是在 Ubuntu 终端里执行:
bash复制ip addr show
找到你的网卡(通常是 ens33、ens160 或 eth0),看 inet 那一行。比如 inet 192.168.80.130/24,那 Finalshell 的主机地址就填 192.168.80.130。如果你看到多个网卡的多个 IP,不确定用哪个,就用排除法:把疑似的 IP 逐个填进 Finalshell 试,能弹密码框的说明网络通。
这里还得看你选了哪种 VMware 网络模式。如果选了 NAT 模式,虚拟机通过宿主机共享上网,IP 一般是 192.168.x.x 段的;如果选了桥接模式,虚拟机像一台独立电脑一样直接接入局域网,IP 可能是 192.168.1.x 或 192.168.31.x。判断规则其实很简单:在 Windows 的 cmd 里 ping 虚拟机的IP 能通,那 Finalshell 一定能找到它;ping 不同,就去第二步查网络原因。
还有一个非常实用的自检方法,在 Ubuntu 虚拟机里看认证日志:
bash复制sudo tail -f /var/log/auth.log
当你从 Finalshell 发起连接时,日志里会实时出现新的记录。如果出现 Failed password for ubuntu from 192.168.x.x,说明网络通了、SSH 服务也正常,纯粹是密码或用户名认证失败;如果半天日志纹丝不动,那连接请求根本没到服务端,问题在网络层。这一招能把问题范围缩小一半,强烈建议你用。
2.3 第三步:正确填写 Finalshell 会话信息
Finalshell 本身不复杂,但细节上有些地方容易被忽略。
主机地址只填 IP,不要带 ssh://、不要带 https://、也不要带端口号——除非你改了 SSH 默认端口,否则 22 不用填。端口号在"端口"输入框里维护,默认是 22。用户名要填你在 Ubuntu 安装时创建的那个用户,比如 ubuntu、akira,不是 root,不是虚拟机名称,也不是"管理员"这种模糊概念。
认证方式这块尤为重要:在"认证"下拉菜单里,如果你要用密码登录,就选"密码",然后填写密码;如果你之前在这个会话上试过密钥登录又失败了,即使你现在切回密码,Finalshell 可能还优先尝试密钥。我的习惯是:新建会话时第一件事就是检查认证方式是不是"密码",并把旧缓存密码清空。Finalshell 在纯密码认证模式下,密码输入框不回显字符,也不显示位数,很多人输完密码看到一片空白以为自己没输进去,其实已经输了。如果密码是复制粘贴过来的,注意结尾不要带空格,我见过太多人从记事本复制密码时把后面的换行符也带进去了。
填完之后点连接,首次连接会提示确认服务器指纹(fingerprint),直接点接受或确认即可。这一步是正常的,不是密码弹窗。接下来如果又出现本文开头那个"输密码死循环",大概率就是下一章要说的配置问题——你密码正确、网络也通,但服务端拒绝密码登录。
3. 密码明明正确却被拒绝:藏在配置文件里的真相
3.1 主配置文件与 conf.d 的覆盖关系,改完不生效的根源
如果你在 Ubuntu 里已经把密码确认过无数遍,Finalshell 还是提示 Permission denied,那八成是 SSH 服务端根本没有开启密码认证。网上绝大多数教程会告诉你去修改 /etc/ssh/sshd_config 这个主配置文件,找到 PasswordAuthentication 改成 yes,然后重启服务生效。问题是,这个方法在较新版本 Ubuntu 上经常失效,原因在于:从 Ubuntu 20.04 开始,OpenSSH 的主配置文件底部有一条 Include 指令,会去加载 /etc/ssh/sshd_config.d/ 目录下的所有 .conf 文件,而这些文件后面的设置会覆盖掉主配置里的同名项。
用命令看就很直白:
bash复制grep -n "Include" /etc/ssh/sshd_config
ls -l /etc/ssh/sshd_config.d/
常见情况是目录里躺着一个 60-cloudimg-settings.conf 或类似的文件,里面明确写着 PasswordAuthentication no。这时候无论你在主配置文件里怎么改成 yes,重启之后还是 no,因为 Include 的文件加载顺序更靠后,优先级更高。正确做法是统一修改:主配置和 conf.d 下的配置文件都改成 yes,然后重启服务。或者,如果你确定不需要保留那些默认覆盖项,直接把对应文件里那一行改成 yes 也行。
改完配置后不要忘了测试语法并重启:
bash复制sudo sshd -t
sudo systemctl restart ssh
sshd -t 这一步可以检查配置语法,如果语法错误,服务重启会失败,反而把你锁在外面。另外一个容易被忽视的点是:MaxAuthTries 默认允许尝试 6 次,如果前面输错太多次,再连接就会出现 Maximum authentication attempts exceeded 的提示,并在一小段时间内拒绝所有认证请求。很多人此时以为问题更严重了,其实只需要等几十秒,或者干脆去虚拟机里重启一下 ssh 服务。
3.2 云镜像与 root 登录的默认策略
为什么 Ubuntu 的云镜像、官方模板默认会禁用密码认证?因为云服务器的安全模型是"密钥优先"——公网环境里密码暴力破解是常态,所以镜像默认把你的密钥登录作为唯一入口。你在本地装虚拟机偶尔也会踩到这个雷,特别是你下载的所谓"Ubuntu 镜像"其实是云镜像(cloud image)而不是桌面版官方 ISO 的时候。这种镜像默认用户是 ubuntu,登录方式要么是密钥要么是 cloud-init 注入的临时密码,密码验证默认直接关闭。
还有一处策略需要留意:PermitRootLogin。Ubuntu 默认这项值是 prohibit-password,意思是 root 用户只能通过密钥登录,不能通过密码登录。所以你如果用 root 去连 Finalshell,输入密码永远是失败,即使密码没问题。解决方案有两种:一是老老实实改用普通用户登录(我更推荐这个,安全习惯好);二是强行修改 sshd_config 里的 PermitRootLogin yes 并重启服务。我个人的建议是别开 root 密码登录,尤其是学 Linux 早期阶段,养成用普通用户加 sudo 的习惯,能少踩非常多权限类坑。
另外,云镜像还有一个特点:会把默认网卡名改成 ens5、ens160 之类,而且刚启动时 IP 可能是 DHCP 临时分配的,过一段时间重启后 IP 会变。你在 Finalshell 里保存了旧 IP,下次就连不上了。遇到这情况就去虚拟机执行 ip addr show 看最新 IP,而不是一顿重装配置。
3.3 用 auth.log 精准定位被拒绝的具体原因
排查密码被拒问题,不要靠猜,直接看日志。Ubuntu 的 SSH 认证日志默认写到 /var/log/auth.log,使用 systemd 的系统也可以用 sudo journalctl -u ssh -f 实时跟踪。一边开这个日志,一边在 Finalshell 里发起连接,日志会立刻给出答案。
常见的日志记录有几种。
Failed password for invalid user xxx from IP——用户不存在。你填的用户名在系统里没这个账号,快速检查方法是 getent passwd 用户名。
Failed password for ubuntu from IP port 22 ssh2——用户存在但密码不对。此时可以去虚拟机里用 sudo passwd ubuntu 重新设置一个新密码,然后立刻在 Finalshell 重试。注意,Linux 修改密码对密码强度校验较宽松(如果你用普通用户 + passwd 命令强制改的话),但如果你是 sudo passwd 用户名 这样以 root 身份改的,可以随便设一个简单密码,比如 123456 都行,先连上再谈安全。
Connection closed by authenticating user IP port 22 [preauth]——客户端在认证阶段主动断开了。这种通常是客户端那边密码弹窗被取消,或者认证超时,也有可能是客户端配置的加密算法与服务端不匹配。Finalshell 的软件设置里有一个"安全"或"SSH 优化"的选项,可以把加密策略调整为兼容模式,应对一些老版本远程环境的算法协商问题。
还有一种情况比较隐蔽:日志里显示一堆 Bad protocol version identification,这说明你连到的端口上根本不是 SSH 服务。比如你虚拟机里某个网站占用了 22 端口,或者你 Finalshell 里端口写错写成 8022 之类的,服务端可能会返回一段 HTTP 头,SSH 客户端解析不了,最终表现为不断让你重试密码。
4. 虚拟机网络模式、防火墙与认证缓慢的隐形坑
4.1 VMware 的三种网络模式怎么选才是正确姿势
网络层排查在 SSH 连接问题里占了很大比重,但很多人喜欢一股脑归结为"密码错"。VMware 虚拟机默认网络模式是 NAT,这个模式下虚拟机通过宿主机共享上网,宿主机能直接访问虚拟机,虚拟机能访问外网,但局域网内其他电脑访问不了这台虚机。如果你只是在 Windows 上开 Finalshell 连虚拟机,NAT 完全够用,不需要改模式。
桥接模式下,虚拟机会像一台独立的电脑一样,从你的路由器重新获取一个局域网 IP。优点是拓扑干净、其他设备也能访问;缺点是你如果换了一个 Wi-Fi、或者公司网络做了设备数量限制,虚拟机可能拿不到 IP,或者拿到了却上不了网。很多人在家能连、到公司连不上,十有八九是网络环境变了而桥接模式没跟着变。如果你只是学习用途,别纠结,直接用 NAT 最省心。
还有一个被称作"仅主机模式"的网络选项,它只允许宿主机和虚拟机互相通信,虚拟机上不了外网。如果你在这个模式下想从 Finalshell 连接,IP 一般是一个 192.168.xxx.1 段的地址,也能连通。但它有一个隐藏坑:不能上网时,Ubuntu 的 apt 源不可用,系统时间也可能不对,复杂一点的安装操作会非常痛苦。所以我的建议是,只要你不是在做纯隔离测试,网络模式首选 NAT。
如果你换了网络模式或者重启了路由器,虚拟机 IP 变了,别在 Finalshell 里反复试旧 IP。直接用 Ubuntu 里的 ip addr show 确认一次,然后更新会话的主机地址,基本就能连上。
4.2 UFW 防火墙与端口监听的自检
Ubuntu 自带 UFW(Uncomplicated Firewall),默认状态是"未启用",但有些精简镜像、或者你自己安装过程中开启了防火墙,那 22 端口默认是放行的还是遮蔽的就不好说了。检查方式:
bash复制sudo ufw status
如果输出 Status: active,而且规则里没有允许 OpenSSH,那么即使 SSH 服务正常,外部的连接请求也会被防火墙丢弃,Finalshell 的表现可能是超时,也可能是一直弹密码框然后卡死。直接放行 SSH:
bash复制sudo ufw allow OpenSSH
这里的 OpenSSH 是 UFW 预置的应用程序规则,对应 /etc/ufw/applications.d/openssh-server,等价于 sudo ufw allow 22/tcp。如果你把 SSH 端口改成了 2222,那就要改成对应的端口号。开启防火墙之后,重启 UFW 让规则生效:
bash复制sudo ufw enable
sudo ufw reload
这里再补充一个容易混淆的点:SSH 服务监听地址和防火墙策略如果同时有问题,优先级是"先经过防火墙,再触达服务"。所以如果 sudo ufw status 显示的是 Status: inactive,但你还是连不上,那就基本排除防火墙因素,回到 sshd 服务状态和网络层去查。反过来,如果你在虚拟机里 ssh 用户名@localhost 能通,但 Finalshell 连接超时,那就是纯网络层或防火墙问题,跟密码、SSH 配置没有关系。
4.3 一种容易被误认为"密码错误"的性能问题
最后这个坑非常隐蔽,尤其发生在配置很低的虚拟机上。SSH 登录时,服务端需要对密码做加盐哈希运算,这个过程虽然只占用极短时间,但在 CPU 虚拟化较弱的机器、或者 VM 只分配了 1 核 512MB 内存的情况下,认证响应可能慢到让客户端以为"没反应",进而弹回密码框重试。你反复输正确密码,它反复超时,就像密码总是不对一样。
这种问题和算法协商也有关。SSH 连接建立时,客户端和服务端要协商密钥交换算法、主机密钥算法、加密算法,低配虚拟机如果启用了非常耗 CPU 的算法,协商阶段就能拖好几秒。我实测过一个 1 核 1G 的虚拟机,ssh localhost 本机连接能通但明显感觉卡顿,Finalshell 也经常出现"输完密码卡顿后返回密码框"。缓解办法:在 VMware 虚拟机设置里把 CPU 至少给到 2 核、内存 2GB 以上;然后在 Finalshell 连接设置里,如果提供 SSH 算法选择,选一个较快的策略或者直接尝试"兼容模式"。
还有一个关联因素:如果你用无线网络,或者宿主机休眠后恢复网络,Finalshell 与虚机之间的连接偶尔会进入半开状态,表现为弹密码框但认证迟迟不完成。这种时候不要死磕,把 Finalshell 这个会话关掉重开,大概率就恢复正常了。很多所谓"密码一直错误"的问题,其实就是一次网络闪断引发的假象。
5. 常见报错速查表与一劳永逸的密钥登录
5.1 常见现象、原因、解法对照表
这几年我收集到的 SSH 连接问题五花八门,但绝大多数都能归类。下面这个表基本覆盖了你可能遇到的 90% 场景,可以直接对照。
| 现象 | 最常见原因 | 对症排查方向 |
|---|---|---|
| 连接超时,密码框不出现 | 虚拟机 IP 填错 / VMware 网络模式不匹配 | 在虚机内 ip addr show 确认 IP,改 NAT 模式再试 |
提示 no route to host |
网段隔离 / 虚拟机没连上宿主网络 | 检查 VM 网络适配器是否启用,ping 网关 |
提示 connection refused |
SSH 服务未安装 / 未启动 / 端口不是 22 | dpkg -l | grep openssh-server、systemctl status ssh |
密码一输就 Permission denied |
用户名错 / 密码错 / 认证方式不对 | 用 sudo passwd 用户名 重置密码,确认用户名大小写 |
手动改 sshd_config 无效 |
conf.d 下的覆盖文件还是 no |
检查 /etc/ssh/sshd_config.d/*.conf,把密码认证都改成 yes |
| 用 root 登录永远失败 | PermitRootLogin 不允许密码 |
改用普通用户登录,或修改配置(不推荐) |
连几次后提示 Maximum authentication attempts exceeded |
密码尝试次数达到上限 | 等 30 秒到 1 分钟再试,清理错误会话缓存 |
| 密码内含特殊字符总失败 | 复制粘贴带了空格/换行,或中文输入法 | 手动在密码框输入,必要时开启密码显示辅助功能 |
| 之前能连,现在不行 | 虚拟机动了 IP / 重装系统 / 改了密码 | ip addr show 重新获取地址,重新验证账号 |
| 弹密码框但日志没记录 | 连到了非 SSH 服务的端口 | 检查 Finalshell 端口号,ss -tlnp 看真实监听端口 |
| 密码正确但连接后无响应 | 虚拟机性能不足 / 网络闪断 | 增加 VM 配置,断开会话重连,检查 auth.log |
这张表看着长,但实际排查逻辑就是一个二分法:先确认网络层通不通,再确认服务端活没活,最后才是密码和配置。我见过太多人一上来就重装系统、重置密码,折腾半天发现只是 Finalshell 里旧 IP 没改。
5.2 用密钥登录彻底绕开密码往返
如果你已经被密码问题折腾烦了,或者打算长期维护这台虚拟环境,我建议干脆上密钥登录。密钥登录的本质是:客户端持有私钥,服务端保存公钥,连接时服务端用公钥验证客户端的私钥签名,整个过程不涉及密码输入。
在 Finalshell 里操作很简单:顶部菜单找到"工具"或"密钥管理",选择"生成密钥",它会生成一对公钥和私钥,私钥保存在客户端,公钥需要复制到 Ubuntu 虚拟机里。在 Ubuntu 终端执行:
bash复制mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "ssh-rsa AAAA...你的公钥..." >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
这里权限检查是重点:.ssh 目录必须是 700,authorized_keys 文件必须是 600,权限过于开放时 SSH 服务端会直接忽略这个文件。然后回到 Finalshell,编辑会话的认证方式为"公钥",加载刚才生成的私钥文件,再次连接时就不用输密码了。
如果你习惯在命令行环境操作,也可以直接在 Ubuntu 虚拟机里用 ssh-keygen -t rsa -b 4096 生成密钥对,把公钥用 ssh-copy-id 推到目标机器上。密钥登录还有一个好处:即使你把 SSH 服务端的密码认证关掉(PasswordAuthentication no),密钥登录照样不受影响。但注意,关密码认证前一定要先确认密钥能正常登录,否则你会把自己锁在服务器外面,到时候又得回到控制台去改配置。
我实际用下来,密钥登录最大的感受是"省心"。尤其是同一台虚拟机要反复重连、换网络环境,密码模式下的各种奇奇怪怪问题在密钥模式下基本消失了。唯一要注意的是私钥文件别乱放,别放进网盘或发给别人,私钥泄露等同于把服务器密码交出去了。
最后再分享一个小技巧:如果你不确定当前问题出在哪一层,先在 Ubuntu 虚拟机里执行 ssh 用户名@localhost 自己连自己,能通说明 SSH 服务和密码都没问题;然后在 Windows 命令行里 ping 虚拟机IP,能通说明网络层没问题;再到 Finalshell 里尝试,如果还失败,就去看 /var/log/auth.log。用这个顺序做二分定位,95% 的问题十分钟内都能找到症结。我个人这几年的体会是,SSH 连接失败这件事,绝大多数时候不是"密码错了",而是"SSH 服务没装好"或者"网络根本没通",先把这两件事排除掉,再去跟密码较劲,才能少做很多无用功。
