Windows + PuTTY + TigerVNC + GRUB 完整实战教程
不用重装系统,不用删除实例,从无法 SSH 登录到恢复 Ubuntu 管理权限
版本:V2.0|2026 年 10 月|达邦开发
适用对象:Oracle Cloud Infrastructure(OCI)Ubuntu 云服务器用户
写在前面:为什么要写这份教程?
如果你正在使用 Oracle Cloud 的 Always Free 永久免费服务器,突然发现原来的 SSH 私钥丢失了,执行:
ssh ubuntu@你的服务器IP
却出现:
Permission denied (publickey).

此时可能会面临三个问题:
- 找不到创建服务器时下载的 SSH 私钥。
- 想通过 Oracle Cloud 控制台登录,却发现 Ubuntu 要求输入密码,而自己从来没有设置过密码。
- 不敢删除实例重新创建,因为 Oracle 免费服务器容量有限,重新创建未必能成功。
这也是我实际遇到的问题。
我使用 Windows,通过 Oracle Cloud 的 VNC 控制台,成功进入 Ubuntu 的 GRUB 引导程序,并在两台不同配置的 OCI 服务器上完成了 root 维护模式访问和密码恢复。
这两台服务器存在明显差异:
| 对比项 | 实例 A | 实例 B |
|---|---|---|
| GRUB 版本 | 2.12 | 2.06 |
| 系统分区 | gpt16 | gpt1 |
| 内核路径 | /vmlinuz-... | /boot/vmlinuz-... |
| 根分区 UUID | 各自不同 | 各自不同 |
| 恢复结果 | 成功进入 root 并重置密码 | 成功进入 root 并重置密码 |
最终发现,真正关键的不是反复尝试重启,而是正确连接 VNC,并读取当前实例自己的 GRUB 配置,使用真实启动参数进入维护环境。
本文按照新手能照着做的顺序编写,不要求读者提前掌握 GRUB 或 Linux 系统恢复知识。
使用前请注意
本教程仅适用于你本人或你已获得明确管理授权的服务器。
需要能够登录 OCI 控制台,并对目标实例拥有控制台连接和重新引导权限。
操作可能需要重启服务器,导致网站或业务暂时中断。涉及重要生产数据的实例,应先确认备份。
本教程主要针对 Windows 操作端和 OCI 的 Ubuntu x86_64 实例,其他系统、ARM 实例、加密磁盘、特殊分区或自定义镜像需要单独判断。
本教程不提供任何绕过 Oracle Cloud 平台账号认证的方法,也不保证所有实例都能使用 GRUB 恢复。
第一章:先确认是不是 SSH 密钥问题
步骤 1:测试服务器是否能连接
在 Windows 中按 Win + R,输入:
powershell
回车,打开 PowerShell。
输入:
ssh ubuntu@<你的公网IP>
如果显示:
Permission denied (publickey).
通常代表:
- 已经联系到服务器上的 SSH 服务。
- 服务器没有接受当前提供的 SSH 密钥。
- 可能是密钥丢失、使用了错误的密钥,或者用户名不正确。
请注意,这与网络连接超时不一样。
如果显示:
Connection timed out
或者:
Connection refused
应先检查服务器运行状态、SSH 服务、安全规则和公网 IP,而不是直接执行密码恢复。
步骤 2:先寻找原来的私钥
如果原来的私钥还在,根本不需要进行后面的复杂操作。
在 PowerShell 执行:
Get-ChildItem "$env:USERPROFILE\.ssh"
也可以检查 Windows 的下载目录。
常见私钥文件可能叫:
ssh-key-2024-xx-xx.key
id_rsa
id_ed25519
oracle.key
如果使用过 WSL,还要检查 Linux 下的:
ls -lah ~/.ssh/
找到疑似私钥后,可以尝试:
ssh -o IdentitiesOnly=yes -i "你的私钥完整路径" ubuntu@<公网IP>
如果成功登录,到这里就结束。
不要把私钥上传到网络论坛、技术群或发给陌生人。
第二章:准备需要的软件
本次恢复使用三个工具。


| 工具 | 作用 | 是否必须 |
|---|---|---|
| PuTTY / Plink | 建立 Oracle 控制台的 SSH 隧道 | Windows 方案需要 |
| PuTTYgen | 生成或转换 .ppk 私钥 | 根据密钥格式决定 |
| TigerVNC Viewer | 显示远程服务器的启动和控制台画面 | VNC 方案需要 |
步骤 3:安装 PuTTY
打开 Windows PowerShell:
winget install --id PuTTY.PuTTY -e
安装完成后,重新打开 PowerShell。
验证:
& "C:\Program Files\PuTTY\plink.exe" -V
如果显示 Plink 版本号,说明安装成功。
如果直接执行:
plink.exe -V
出现找不到命令,可以在当前 PowerShell 中执行:
$env:Path += ";C:\Program Files\PuTTY"
再试一次。
注意,plink.exe 是 PuTTY 安装包中的命令行工具,不是 Windows 自带命令。
官方下载地址:
https://www.chiark.greenend.org.uk/~sgtatham/putty
步骤 4:安装 TigerVNC Viewer
访问:
https://github.com/TigerVNC/tigervnc/releases
选择适合 Windows 的 TigerVNC Viewer 安装程序。
安装后,找到 TigerVNC Viewer。
现在先不用打开,后面建立 SSH 隧道后才需要使用。
无需在 Oracle 云服务器内部安装 TigerVNC Server。 我们使用的是 Oracle 平台提供的实例 VNC 控制台,不是自己安装的远程桌面服务。
第三章:在 Oracle Cloud 创建控制台连接
步骤 5:进入目标实例
登录:
打开:
计算(Compute) → 实例(Instances)
选择无法 SSH 登录的目标服务器。
首先核对:
- 实例名称。
- 系统类型。
- 公网 IP。
- 当前运行状态。
- 所在区域。
不要直接选择第一台看到的实例,尤其当账户下有多台服务器时。
步骤 6:找到控制台连接
在实例详情页面中寻找:
操作系统管理 → 控制台连接
不同版本的 Oracle UI,也可能将其放在实例资源列表中。
找到:
创建本地连接
启动 Cloud Shell 连接
这里需要理解一个区别。
Cloud Shell 连接并不等于已经取得 Ubuntu 系统权限。
Cloud Shell 进入串行控制台后,仍可能看到:
ubuntu login:
Password:
Oracle Ubuntu 云镜像通常默认没有设置可供直接输入的系统密码,所以仅仅创建 Cloud Shell 连接,不能解决原密码丢失问题。
本教程选择另一条已实测的路线:使用 Windows + Plink + TigerVNC。
步骤 7:创建控制台 RSA 密钥
在 Windows PowerShell 执行:
ssh-keygen -t rsa -b 4096 -f "$env:USERPROFILE\.ssh\oci-console-rsa"
系统会创建:
oci-console-rsa
oci-console-rsa.pub
前者是私钥,后者是公钥。
回到 Oracle「创建控制台连接」,选择:
上传公共密钥文件 (.pub)
上传:
C:\Users\你的用户名\.ssh\oci-console-rsa.pub
点击创建。
等待控制台连接的状态显示:
活动 / Active
为什么使用 RSA?
在本次实测中,上传 Ed25519 公钥到 Oracle 控制台连接时出现:
Invalid ssh public key type "ssh-ed25519"
改成 RSA 公钥后成功创建了连接。
注意,这是控制台连接密钥的兼容性问题,不代表 Ubuntu 普通 SSH 登录不能使用 Ed25519。
步骤 8:将 RSA 私钥转换为 PPK
Windows Plink 通常使用 PuTTY 私钥格式 .ppk。
打开安装好的 PuTTYgen:
- 点击
Load。 - 文件类型选
All Files。 - 打开
oci-console-rsa私钥。 - 点击
Save private key。 - 保存为
oci-console-rsa.ppk。
现在应该有:
oci-console-rsa
oci-console-rsa.pub
oci-console-rsa.ppk

三者的作用分别是:
oci-console-rsa:OpenSSH 格式私钥。oci-console-rsa.pub:上传 Oracle 的公钥。oci-console-rsa.ppk:Windows Plink 用的私钥。
如果 PuTTYgen 提示设置私钥口令,建议设置并安全保存。后续 Plink 连接可能要求输入这个口令。
千万不要把 .pub 当成私钥,也不要把 .ppk 上传到 Oracle 的公钥上传框。
第四章:使用 Windows 建立 VNC 控制台连接
这一章是新手最容易卡住的部分。

步骤 9:复制 Oracle 官方连接命令
回到 Oracle 控制台连接列表。
在状态为「活动」的那一行,点击右侧三个点 ⋮。
选择:
复制 Windows 的 VNC 连接
把命令先粘贴到记事本。
Oracle 生成的命令一般包含:
Start-Job { ... }
sleep 5
plink.exe ...
其本质是建立两段 SSH 隧道:
Windows
↓ TCP 443
Oracle 控制台代理
↓
本地 5905 隧道
↓
第二段 SSH 连接
↓
本地 VNC 5900
↓
TigerVNC
Oracle 会自动生成属于你这台服务器的实例标识。
一定使用你自己的 Oracle 控制台生成的连接标识,不要复制其他人的 OCID。
步骤 10:检查私钥路径
Oracle 原始命令可能使用:
$env:homedrive$env:homepath\oci\console.ppk
这个路径不一定存在。
执行:
Test-Path "$env:USERPROFILE\.ssh\oci-console-rsa.ppk"
正常应该显示:
True
如果显示 False,说明路径不对,请重新检查文件位置。
步骤 11:建立第一段 SSH 隧道
为了方便排查,我们不要直接运行 Oracle 的后台任务,而是分开执行两段命令。
新开一个 PowerShell 窗口。
首先,根据 Oracle 自动生成的命令,填写以下三个变量:
$key = "$env:USERPROFILE\.ssh\oci-console-rsa.ppk"
$console = "这里填写你的 instanceconsoleconnection OCID"
$instance = "这里填写你的 instance OCID"
例如,两种 OCID 的格式分别是:
ocid1.instanceconsoleconnection.oc1....
ocid1.instance.oc1....
然后执行:
plink.exe -v -i $key -N -ssh -P 443 `
-l $console `
-L "5905:${instance}:5905" `
instance-console.<你的OCI区域>.oci.oraclecloud.com
其中最后一行的服务器地址,也必须使用 Oracle 自动生成命令中的实际地址。
例如韩国春川区域的地址是:
instance-console.ap-chuncheon-1.oci.oraclecloud.com
如果连接成功,可以看到:
Offer of public key accepted
Access granted
Local port 5905 forwarding to ...
不要关闭这个 PowerShell 窗口。
如果首次连接时要求确认远端 SSH 主机指纹,请核对指纹来源后再接受,不能盲目输入 y。
步骤 12:验证第一段隧道
再打开一个 PowerShell 窗口:
Get-NetTCPConnection -LocalPort 5905 -State Listen
正常应该有监听记录。
如果没有输出,说明第一段隧道没有正确建立。
请回到第一个窗口,检查报错。
步骤 13:建立第二段 SSH 隧道
保持第一段窗口运行。
在第二个 PowerShell 中执行:
$key = "$env:USERPROFILE\.ssh\oci-console-rsa.ppk"
$instance = "这里填写与第一段相同的 instance OCID"
然后执行:
plink.exe -v -i $key -N -ssh -P 5905 `
-l $instance `
-L 5900:localhost:5900 `
localhost
成功后应该看到:
Offer of public key accepted
Access granted
Local port 5900 forwarding to localhost:5900
这个窗口也不要关闭。
步骤 14:测试 VNC 本地端口
打开第三个 PowerShell:
Test-NetConnection 127.0.0.1 -Port 5900
如果输出:
TcpTestSucceeded : True
说明本地端口可以连接。
但这只能证明本地 TCP 端口可连接,不能单独证明远端 VNC 图像已经能正常传输。
步骤 15:打开 TigerVNC
运行 TigerVNC Viewer。
在服务器地址中填写:
127.0.0.1::5900
注意这里是两个英文冒号。
点击 Connect。
如果一切正常,你可能会看到:
Ubuntu 24.04.1 LTS
instance-xxxxx login:

这表示 VNC 已经成功显示 Ubuntu 的本机控制台。
此时还没有恢复系统密码,不用在这里不断尝试猜测密码。
第五章:进入 GRUB 启动程序
接下来,我们需要让 Ubuntu 临时进入维护模式。
步骤 16:正常重新引导服务器
保持两个 Plink 窗口和 TigerVNC 打开。
返回 OCI 实例详情。
点击:
操作 → 重新引导
这里「重新引导」就是 Reboot。
选择正常重新引导,不要选择「终止实例」,也不要误点「替换引导卷」。
重启会中断实例正在运行的服务,重要系统请先完成备份或安排停机窗口。
步骤 17:观察 UEFI 启动画面
TigerVNC 会显示服务器启动过程。
常见画面之一:
TianoCore
Loading Boot0004 "Ubuntu"
这说明服务器正在启动 Ubuntu。
此时可以尝试按 Esc,或轻按方向下键,以中断 GRUB 自动启动。
某些情况下,过早按 Esc 会进入 UEFI 固件设置页面:
Device Manager
Boot Manager
Boot Maintenance Manager
Continue
Reset
这不是 GRUB。
如果进入这个页面:
- 用方向键选择
Boot Manager。 - 按 Enter。
- 选择 Ubuntu 启动项。
- 再尝试在 GRUB 阶段中断自动启动。
不要修改固件的磁盘启动顺序。
步骤 18:识别 GRUB 的两种界面
第一种是正常的 GRUB 菜单:
GNU GRUB
* Ubuntu
Advanced options for Ubuntu
如果看到这个菜单,可以选中 Ubuntu 并按 e 编辑启动参数。

第二种是 GRUB 命令行:
GNU GRUB version 2.xx
grub>
我们两台服务器的成功恢复,主要使用了第二种方式。
如果你也看到 grub>,可以直接继续第六章。
不要急着输入:
normal
因为它可能直接按默认配置启动 Ubuntu,又回到需要密码的登录页面。
第六章:从 GRUB 找到自己服务器的启动参数
这一章最重要。
这里教你一种通用思路,解决不同实例使用不同磁盘分区、内核版本和 UUID 的问题。
步骤 19:查看 GRUB 当前参数
在:
grub>
后面输入:
set
按 Enter。
重点寻找:
prefix=(hd0,gptX)/...
root=hd0,gptX
其中 gptX 的 X 可能是 1、15、16,也可能是其他数字。
这是当前服务器自己的分区信息。
然后执行:
ls
可能看到:
(proc) (memdisk) (hd0) (hd0,gpt1)
也可能看到:
(proc) (memdisk) (hd0) (hd0,gpt16) ...
不要把别人服务器的 gpt16 当成自己服务器的分区。
步骤 20:查看分区目录
以实际 root 变量为准。
假设它是:
(hd0,gpt1)
输入:
ls (hd0,gpt1)/
如果看到:
bin/ boot/ dev/ etc/ home/ usr/ var/
说明这是 Linux 根目录的有力线索。
继续:
ls (hd0,gpt1)/boot/
如果当前是:
(hd0,gpt16)
则需要按该分区实际文件布局查看。
可能直接执行:
ls (hd0,gpt16)/
就能找到内核文件。
步骤 21:找到内核和 initrd
常见内核文件:
vmlinuz-5.15.0-1081-oracle
vmlinuz-7.0.0-1013-oracle
常见 initrd 文件:
initrd.img-5.15.0-1081-oracle
initrd.img-7.0.0-1013-oracle
这些只是我们两次实测遇到的版本。
你的服务器可能使用其他版本。
内核文件和对应的 initrd 应使用同一版本。
步骤 22:开启 GRUB 分页
由于 TigerVNC 不是普通的滚动终端,输出过长时很容易看不到前面的内容。
在 grub> 输入:
set pager=1
验证:
echo $pager
应输出:
1
之后执行:
cat $prefix/grub.cfg
当看到:
--MORE--
说明分页已经生效。
操作方式:
Space:下一屏。Enter:往下显示一行。
不要一直长按空格,否则可能错过关键配置。
步骤 23:找到启动项
翻阅配置,直到看到:
### BEGIN /etc/grub.d/10_linux ###
继续往下,找第一条默认 Ubuntu 启动项。
通常类似:
menuentry 'Ubuntu' ...
其后会有:
linux /boot/vmlinuz-版本 root=UUID=实际UUID ro ...
以及:
initrd /boot/initrd.img-版本
有些服务器的路径不是 /boot/vmlinuz,而是直接 /vmlinuz。
必须以当前配置实际写的路径为准。
如果 GRUB 把一行长命令自动折成两行,那只是屏幕宽度不够,并不意味着原命令中有换行。
现在记录三个关键信息:
| 要记录的内容 | 示例 |
|---|---|
| 内核路径 | /boot/vmlinuz-版本 |
| 根分区 UUID | xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx |
| initrd 路径 | /boot/initrd.img-版本 |
这三项记录准确后,才能进入下一步。
第七章:进入 Ubuntu root 维护模式
这一章提供两种实例布局的已验证示例。
请根据自己在第六章读到的配置填写,不要把示例直接当作通用命令。
场景 A:内核位于 /boot 目录
第二台实测服务器就是这种结构。
GRUB 分区类似:
(hd0,gpt1)
内核:
/boot/vmlinuz-5.15.0-1081-oracle
initrd:
/boot/initrd.img-5.15.0-1081-oracle
在 grub> 依次执行:
第一条:
set root=(hd0,gpt1)
第二条:
linux /boot/vmlinuz-5.15.0-1081-oracle root=UUID=你自己查到的UUID rw init=/bin/bash console=tty1
第三条:
initrd /boot/initrd.img-5.15.0-1081-oracle
第四条:
boot
注意第二条中的 root=UUID= 必须替换为真实值,中间不能留中文占位文字。
在本次实测中,这一组结构成功进入了维护模式。
场景 B:内核位于分区根目录
第一台实测服务器属于这种结构。
GRUB 分区类似:
(hd0,gpt16)
内核:
/vmlinuz-7.0.0-1013-oracle
initrd:
/initrd.img-7.0.0-1013-oracle
对应命令:
set root=(hd0,gpt16)
linux /vmlinuz-7.0.0-1013-oracle root=UUID=你自己查到的UUID rw init=/bin/bash console=tty1
initrd /initrd.img-7.0.0-1013-oracle
boot
同样需要替换为自己实例的真实 UUID 和内核版本。
为什么要使用这些参数?
linux:指定要启动的 Linux 内核。root=UUID=...:告诉 Linux 真正的系统根分区在哪里。rw:允许以读写方式挂载根文件系统。init=/bin/bash:使用 Bash 作为初始进程,进入维护环境。console=tty1:让控制台输出适合当前的 VNC 场景。initrd:加载与内核匹配的初始内存盘。boot:开始启动。
对于具有特殊存储、加密磁盘或其他必需内核参数的实例,需要保留原启动配置中的相应参数,不能无条件简化成以上示例。
步骤 24:确认是否成功
成功时会看到 Ubuntu 启动日志,最终出现:
root@(none):/#
或者:
root@主机名:/#
有时也会显示:
bash: cannot set terminal process group
bash: no job control in this shell
这类信息在 init=/bin/bash 环境中可能出现,不一定代表启动失败。
关键是能否看到 root shell,并正常执行命令。
注意:这是操作系统恢复 Shell,并不代表普通 Ubuntu 服务已经启动。此时不要运行需要 systemd、完整网络或后台服务的普通业务命令。
第八章:重置 Ubuntu 登录密码
步骤 25:将系统挂载为可写
进入 root shell 后,执行:
mount -o remount,rw /
确认:
findmnt -no OPTIONS /
输出中应包含 rw。
如果挂载失败或文件系统报错,先停止操作,不能强行继续写入。
步骤 26:确认 Ubuntu 用户
执行:
id ubuntu
如果显示用户 UID、GID 等信息,说明存在 ubuntu 用户。
如果没有这个用户,应检查镜像类型,不能盲目执行后续命令。
步骤 27:重设密码
执行:
passwd ubuntu
屏幕出现:
New password:
输入新密码,按 Enter。
然后:
Retype new password:
再次输入。
Linux 输入密码时通常不会显示任何字符或星号,这是正常现象。
成功后会显示:
passwd: password updated successfully
到这里,Ubuntu 的本机控制台登录密码已经恢复。
但注意:
设置 Ubuntu 密码,不等于自动开启 SSH 密码登录。
如果原服务器 SSH 配置只允许公钥认证,普通 SSH 仍然需要下一章的新密钥。
第九章:恢复正常 SSH 密钥登录
这一步建议在维护模式中完成,再重新启动服务器。
步骤 28:Windows 生成新的 SSH 密钥
在 Windows PowerShell 执行:
ssh-keygen -t ed25519 -f "$env:USERPROFILE\.ssh\oci-ssh-recovery"
生成:
oci-ssh-recovery
oci-ssh-recovery.pub
其中:
oci-ssh-recovery:新私钥。oci-ssh-recovery.pub:新公钥。
这把密钥用于正常 Ubuntu SSH 登录,与前面建立 Oracle VNC 控制台连接的 RSA 密钥是两回事。
读取公钥:
Get-Content "$env:USERPROFILE\.ssh\oci-ssh-recovery.pub"
复制完整的一行,通常以:
ssh-ed25519 AAAA...
开头。
步骤 29:在 Ubuntu 维护环境中创建授权目录
在 TigerVNC 的 root shell 执行:
install -d -m 700 -o ubuntu -g ubuntu /home/ubuntu/.ssh
该命令用于创建 SSH 目录并设置所属用户与权限。
如果 .ssh 已存在,也应保留其中原有文件,不要删除。
步骤 30:添加新公钥
执行:
cat >> /home/ubuntu/.ssh/authorized_keys
按 Enter。
然后输入完整的新公钥,输入完成后按 Enter,再按 Ctrl + D 结束输入。
这里有一个实际操作时很容易遇到的问题:
TigerVNC 的文本控制台不一定支持 Windows 剪贴板直接粘贴。
不要以为 Ctrl+V 没有反应就代表密钥有问题。
如果无法可靠粘贴,可以使用 VNC 客户端支持的键盘输入方式,或在后续恢复本机密码登录后,通过能够正常传输文本的授权终端完成公钥配置。
不要把私钥内容输入服务器,也不要使用不可信的在线剪贴板服务传输密码或私钥。
步骤 31:设置授权文件权限
执行:
chown ubuntu:ubuntu /home/ubuntu/.ssh/authorized_keys
chmod 600 /home/ubuntu/.ssh/authorized_keys
chmod 700 /home/ubuntu/.ssh
检查:
ls -lah /home/ubuntu/.ssh/
确认:
authorized_keys
存在,且由 ubuntu 用户拥有。
注意:使用的是追加方式,原有密钥仍然保留。
如果希望删除旧密钥,应该在恢复并验证新的 SSH 登录后单独处理,避免再次把自己锁在系统外。
第十章:安全重启并验证恢复结果
步骤 32:同步磁盘写入
在 root 维护 Shell 执行:
sync
这一步很重要,因为当前处于特殊的维护环境。
步骤 33:重新启动
由于使用了 init=/bin/bash,完整的 systemd 服务没有启动,普通 systemctl reboot 未必可用。
本次实测路线可以在文件写入完成后使用:
/sbin/reboot -f
这属于强制重启方式,可能带来文件系统一致性风险,所以必须确保密码和密钥写入已经完成,并先执行 sync。
对于重要生产系统,优先考虑当前环境是否存在更安全的正常退出和重启方法。
步骤 34:验证系统控制台密码
Ubuntu 正常启动后,TigerVNC 可能重新显示:
主机名 login:
输入:
ubuntu
然后输入新密码。
如果能够成功登录,说明本机登录权限恢复成功。
步骤 35:测试正常 SSH
在 Windows PowerShell 中运行:
ssh -o IdentitiesOnly=yes -i "$env:USERPROFILE\.ssh\oci-ssh-recovery" ubuntu@<你的服务器公网IP>
如果成功进入 Ubuntu shell,说明 SSH 密钥恢复也完成了。
建议立即执行:
whoami
确认当前用户为:
ubuntu
再检查:
sudo systemctl status ssh
确认 SSH 服务运行状态。
最后测试需要的 sudo 权限,检查原来的业务服务是否正常。
当控制台密码和新 SSH 密钥都验证成功后,才算真正完成恢复。
第十一章:多台服务器操作时,防止 VNC 端口冲突
这也是第二台服务器实测遇到的关键教训。
如果你还保留着第一台服务器的 Plink 连接,就不要直接为第二台重复使用本地 5905 和 5900。
因为可能出现本地端口已被占用,甚至 VNC 显示的不是你以为的那台实例。
可以分配不同端口:
| 端口 | 服务器 A | 服务器 B |
|---|---|---|
| 第一段本地 SSH 隧道 | 5905 | 5915 |
| 第二段本地 VNC 隧道 | 5900 | 5910 |
第二台的第一段命令,将本地监听端口改为 5915:
-L "5915:${instance}:5905"
注意右侧远端仍是 Oracle 原始命令指定的 5905。
第二段改成:
plink.exe -v -i $key -N -ssh -P 5915 `
-l $instance `
-L 5910:localhost:5900 `
localhost
TigerVNC 则连接:
127.0.0.1::5910
多实例环境下,务必先确认 VNC 里显示的主机名确实属于目标服务器,避免重启或修改错误实例。
第十二章:常见问题与解决方法
Q1:执行 Plink,提示找不到 plink.exe
报错:
plink.exe is not recognized
原因通常是没有安装 PuTTY,或者安装路径未加入 PATH。
重新安装 PuTTY,或者使用它的完整路径执行即可。
Q2:Connection refused
如果第二段 SSH 隧道出现:
Network error: Connection refused
优先检查第一段隧道是否成功。
执行:
Get-NetTCPConnection -LocalPort 5905 -State Listen
如果没有监听,第二段通常无法连接。
如果已监听,进一步查看第一段 Plink 的 -v 日志,判断远端连接和认证是否真正正常。
Q3:Test-NetConnection 返回 True,但 VNC 仍然连不上
TcpTestSucceeded : True 只能证明本地 TCP 端口可以连接。
还需要检查:
- 第一段 SSH 是否认证成功。
- 第二段 SSH 是否认证成功。
- VNC 端口是否属于正确的实例。
- TigerVNC 是否使用正确的本地地址。
- 两个 Plink 窗口是否还在运行。
Q4:Oracle 显示 Invalid ssh public key type
例如:
Invalid ssh public key type "ssh-ed25519"
本次操作中,改用 RSA 4096 位公钥成功解决。
建议区分 Oracle 控制台连接密钥与普通服务器 SSH 登录密钥,不要混为一谈。
Q5:进入 Cloud Shell 后要求 Ubuntu 密码
说明你连接到了 Ubuntu 控制台,但还没有获得系统登录权限。
OCI 的控制台连接密钥只用于连接控制台,不会自动修改 Ubuntu 用户密码。
如果原本没有设置密码,需要按照本文通过 GRUB 恢复。
Q6:为什么一直看不到 GRUB 菜单?
因为有些 OCI Ubuntu 镜像默认设置:
set timeout_style=hidden
set timeout=0
会直接启动默认系统。
可以尝试在启动过程中中断 GRUB。
如果进入:
grub>
不需要非得恢复可视化菜单,可以按照本文直接读取启动配置、手动加载内核进入维护 Shell。
Q7:输入 normal 后直接进入 login
这是正常启动逻辑的一种表现。
normal 会尝试恢复 GRUB 的正常启动流程,但如果配置为零等待,就可能直接启动 Ubuntu。
此时重新进入 grub>,使用手动引导方法,不必重复依赖 normal。
Q8:为什么别人的 gpt16 在我这里找不到?
报错:
error: disk 'hd0,gpt16' not found
说明你自己的磁盘分区和对方不同。
使用:
ls
以及:
set
查找当前机器的真实分区。
不要继续使用别人的磁盘路径。
Q9:如何查看很长的 GRUB 配置?
输入:
set pager=1
再输入:
cat $prefix/grub.cfg
看到 --MORE-- 后,可以用空格翻页、Enter 逐行查看。
重点找 10_linux 段中默认启动项的 linux 和 initrd。
Q10:怎么确认 Linux 内核版本?
使用:
ls (hd0,gptX)/boot/
或查看实际分区根目录。
然后从 grub.cfg 中确定默认启动项正在使用的版本。
不要盲目选择版本号最大的内核。
Q11:执行 linux 命令报 file not found
通常是:
- 路径写错。
- 分区选错。
- 内核文件名写错。
- 当前分区存在
/boot目录,但实际内核路径却不包含/boot,或者相反。
重新执行:
ls $root/
并检查配置中的准确内核路径。
Q12:密码重置了,为什么 SSH 还提示 publickey?
因为 SSH 密码认证和系统本机密码是两回事。
默认的 Ubuntu 云服务器通常主要使用 SSH 公钥认证。
必须确认新的公钥已经正确加入:
/home/ubuntu/.ssh/authorized_keys
并且 SSH 服务、用户、目录权限都正确。
不建议为了恢复方便,长期打开公网 SSH 密码认证。
Q13:如果没有办法进入 grub> 怎么办?
可以考虑 Oracle 官方的启动卷恢复方案:
- 备份启动卷。
- 准备可用的辅助 Linux 实例。
- 停止原实例。
- 分离原启动卷。
- 挂载到辅助实例。
- 修改原系统的
authorized_keys。 - 安全卸载并重新挂回原实例。
- 启动原实例,验证 SSH。
这是一条备选路线,不是本文两台实测服务器使用的最终方案。
执行之前必须核对资源配额、可用性域、启动卷附件方式和数据保护要求。
对于 Oracle Always Free 用户,不能为了恢复而随意删除实例重新创建。
第十三章:恢复成功后的安全检查
建议按照以下清单逐项确认。
可以通过新密码登录 Ubuntu 本机控制台。
可以通过新 SSH 私钥正常登录服务器。
`/home/ubuntu/.ssh/authorized_keys` 权限正确。
已确认 SSH 服务运行正常。
已确认网站、数据库及其他服务正常运行。
没有无意开启长期公网 SSH 密码认证。
已备份新的私钥。
已验证备用 SSH 密钥可以登录。
已核对 Oracle Cloud 里的实例名称和公网 IP。
不再需要 VNC 时,已关闭 Plink 隧道。
已清理不再需要的临时控制台连接。
已完成重要数据和配置备份。
建议至少保存两份独立的 SSH 私钥备份,例如一份放在本机安全存储,一份放在受保护的加密备份中。
不要将私钥直接提交到 GitHub 仓库,也不要明文保存在网盘共享目录。
第十四章:最重要的五个经验
经验一:不要把 OCI 控制台连接密钥当成 Ubuntu 登录密钥。
它们用于不同的认证环节,不能直接互相替代。
经验二:看到 Access granted,不代表 Ubuntu 已经成功登录。
这只说明 SSH 隧道相应阶段的认证成功。
经验三:不要死磕 GRUB 可视化菜单。
有些实例会隐藏菜单。只要能进入 grub>,就可以进一步检查手动引导是否可行。
经验四:每台实例都必须重新读取内核、根分区和 UUID。
第一台成功的命令,不能直接照搬到第二台。
经验五:先恢复本机控制台权限,再恢复普通 SSH。
设置密码和安装 SSH 公钥是两件独立的事,都验证成功,才代表恢复流程真正结束。
参考资料
- Oracle 官方:Troubleshooting Instances Using Instance Console Connections https://docs.oracle.com/en-us/iaas/Content/Compute/References/serialconsole.htm
- Oracle 官方:Troubleshooting the SSH Connection https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/troubleshooting-ssh-connection.htm
- Oracle 官方:Linux Boot Volume Recovery https://docs.oracle.com/en-us/iaas/Content/Block/Tasks/recoveringlinuxbootvolume.htm
- Ubuntu 社区:LostPassword https://help.ubuntu.com/community/LostPassword
- GNU GRUB 官方手册 https://www.gnu.org/software/grub/manual/grub/
- TigerVNC 官方项目 https://github.com/TigerVNC/tigervnc
结语
Oracle Cloud 免费服务器真正宝贵的,不只是它的免费计算资源,还有里面长期积累的网站、程序、配置和数据。
丢失 SSH 密钥,确实会让新手觉得服务器已经无法挽回。
但在仍然拥有 Oracle Cloud 控制台权限、系统启动卷正常、能够访问 GRUB 的情况下,依然可能通过维护模式恢复登录权限。
这份教程不是简单拼接网上命令,而是根据两台不同配置的 OCI 实例实际恢复经历整理。
最值得记住的一句话是:不要复制别人的启动参数,要学会从自己的服务器里找到正确参数。
文档版本:2.0
实测验证:两台 OCI Ubuntu 实例
维护:达邦开发
最后更新:2026 年 10 月
技术恢复具有风险;使用者应先确认资产授权、数据备份及业务中断影响。不同系统配置下的结果可能不同。