在远程维护 Windows 主机时,常见方案包括 RustDesk、AnyDesk、直接暴露 RDP、VPN,以及通过 SSH 隧道转发 RDP。
其中一种兼顾安全性、清晰度和使用便利性的方案是:
FRP 负责把远程 Windows 的 SSH 服务映射到公网
SSH 负责建立加密端口转发
RDP 负责提供远程图形桌面
Linux 上使用 KRDC 作为客户端
这种结构不需要把 Windows 的 RDP 端口直接暴露到公网,同时仍然可以获得原生 RDP 较高的画质、较低的带宽占用和良好的剪贴板体验。
一、整体结构
假设存在三台设备:
本地 Linux 工作站
公网中转服务器
远程 Windows 主机
远程 Windows 位于内网,没有公网 IP。Windows 上运行 FRP 客户端,主动连接公网中转服务器上的 FRP 服务端。
FRP 已经建立了一条 SSH 映射:
公网中转服务器:45222
↓
远程 Windows:22
因此,在 Linux 上可以通过下面的方式登录远程 Windows:
ssh -p 45222 remoteuser@gateway.example.net
这里连接的虽然是公网中转服务器的地址和端口,但最终进入的是远程 Windows 的 OpenSSH 服务。
在此基础上,再增加一层 SSH 本地端口转发:
Linux 本机 127.0.0.1:14389
↓
SSH 加密隧道
↓
远程 Windows 127.0.0.1:3389
最终链路如下:
KRDC
↓
Linux 127.0.0.1:14389
↓
SSH 本地端口转发
↓
公网中转服务器:45222
↓
FRP
↓
Windows OpenSSH
↓
Windows 127.0.0.1:3389
↓
Windows Remote Desktop Services
需要特别注意:
FRP 映射的仍然只是 SSH,并没有把 RDP 直接暴露到公网。
RDP 流量被封装在 SSH 连接中,由 Windows 的 SSH 服务在远端连接本机的 3389 端口。
二、为什么选择 RDP over SSH
直接将 Windows 的 3389 端口映射到公网虽然简单,但长期使用并不理想。
即使将公网端口改成其他数字,也无法消除以下风险:
- 自动化端口扫描;
- 用户名和密码爆破;
- RDP 服务直接暴露;
- 防火墙配置错误;
- 公网端口被遗忘;
- Windows 服务漏洞带来的攻击面。
通过 SSH 隧道后,公网只保留一个 SSH 入口:
公网可见:
gateway.example.net:45222
公网不可直接访问:
Windows:3389
Linux 上的临时 RDP 入口还可以只绑定回环地址:
127.0.0.1:14389
这意味着只有本机程序可以访问,局域网内其他设备也无法直接连接该端口。
三、Windows 端需要具备的条件
远程 Windows 需要满足以下条件:
- 使用支持 RDP 服务端的 Windows 版本;
- OpenSSH Server 正常运行;
- FRP 客户端可以自动连接公网服务器;
- Remote Desktop Services 已启用;
rdp-tcp监听器存在;- TCP 3389 正在监听。
通常可作为 RDP 服务端的版本包括:
Windows 专业版
Windows 企业版
Windows 教育版
Windows 家庭版一般只能作为 RDP 客户端,不能直接接受标准微软 RDP 登录。
四、通过 SSH 检查 Windows 的 RDP 状态
通过 SSH 登录 Windows 后,默认可能进入 cmd.exe:
remoteuser@WIN-REMOTE C:\Users\remoteuser>
此时 PowerShell 命令不能直接执行。
先输入:
powershell
提示符变成:
PS C:\Users\remoteuser>
之后再进行检查。
1. 检查 Windows 版本
Get-CimInstance Win32_OperatingSystem |
Select-Object Caption, Version, OSArchitecture
2. 检查 RDP 服务
Get-Service TermService |
Select-Object Status, StartType, Name
正常运行时应显示:
Status : Running
Name : TermService
3. 检查远程桌面开关
Get-ItemProperty `
'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' `
-Name fDenyTSConnections |
Select-Object fDenyTSConnections
结果含义:
0:允许远程桌面
1:禁止远程桌面
4. 检查 RDP 监听器
qwinsta
正常情况下应出现:
rdp-tcp 65536 侦听
如果输出中只有:
services
console
而没有 rdp-tcp,说明 RDP 监听器没有建立。
5. 检查 3389 端口
Get-NetTCPConnection `
-LocalPort 3389 `
-State Listen `
-ErrorAction SilentlyContinue |
Select-Object LocalAddress, LocalPort, State, OwningProcess
正常状态通常会出现:
0.0.0.0 3389 Listen
:: 3389 Listen
6. 从 Windows 本机测试 RDP
Test-NetConnection 127.0.0.1 -Port 3389 |
Select-Object ComputerName, RemotePort, TcpTestSucceeded
只有出现下面的结果,SSH 隧道才可能成功:
TcpTestSucceeded : True
五、启用 Windows RDP
如果 RDP 原本关闭,可以在管理员 PowerShell 中执行:
Set-ItemProperty `
-Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' `
-Name fDenyTSConnections `
-Value 0
Start-Service TermService
还可以检查 RDP-Tcp 监听器配置:
$rdpPath =
'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp'
Get-ItemProperty $rdpPath |
Select-Object PortNumber,
fEnableWinStation,
fLogonDisabled,
UserAuthentication
常见有效值为:
PortNumber 3389
fEnableWinStation 1
fLogonDisabled 0
需要注意,修改监听器注册表后,正在运行的 TermService 不一定立即重新加载配置。
可能出现这样的状态:
TermService 已经运行
fDenyTSConnections 已经是 0
但 rdp-tcp 仍不存在
3389 仍未监听
如果远程主机正在运行重要计算任务,不应为了恢复 RDP 而强行重启。应优先保护任务,等待合适的维护窗口。
某些情况下,只有 Windows 完整重启后,RDP-Tcp 监听器才会重新建立。
六、在 Linux 上建立 SSH 隧道
假设公网 SSH 入口为:
gateway.example.net:45222
Windows SSH 用户为:
remoteuser
Linux 本地临时 RDP 端口为:
14389
执行:
ssh -N \
-L 127.0.0.1:14389:127.0.0.1:3389 \
-p 45222 \
-o ExitOnForwardFailure=yes \
-o ServerAliveInterval=60 \
-o ServerAliveCountMax=3 \
remoteuser@gateway.example.net
执行成功后,终端不会返回 Shell 提示符,也通常没有任何输出。这是正常状态。
该终端需要保持打开。
七、SSH 本地端口转发的参数含义
核心参数是:
-L 127.0.0.1:14389:127.0.0.1:3389
格式为:
-L 本地监听地址:本地监听端口:远程目标地址:远程目标端口
本例表示:
在 Linux 本机监听 127.0.0.1:14389
收到连接后,通过 SSH 发送到远程 Windows
再由 Windows 的 SSH 服务连接 Windows 本机的 127.0.0.1:3389
其中两个 127.0.0.1 分别属于不同的主机:
第一个 127.0.0.1:Linux 本机
第二个 127.0.0.1:远程 Windows
-N
不打开远程命令行,只维持端口转发
ExitOnForwardFailure=yes
如果本地端口无法监听,例如端口已经被占用,SSH 会立即退出。
否则可能出现 SSH 看起来正常运行,但实际端口转发没有建立的情况。
ServerAliveInterval=60
每隔一段时间发送 SSH 保活消息,降低连接被中间设备因空闲而断开的概率。
ServerAliveCountMax=3
连续多次保活失败后结束连接,避免产生已经失效但仍然残留的隧道进程。
八、普通 SSH 和 RDP 隧道可以同时使用
同一个公网 SSH 端口可以同时接受多个独立 TCP 连接。
例如:
连接 A:普通 SSH 管理
连接 B:RDP SSH 隧道
连接 C:SFTP 文件传输
普通 SSH:
ssh -p 45222 remoteuser@gateway.example.net
RDP 隧道:
ssh -N \
-L 127.0.0.1:14389:127.0.0.1:3389 \
-p 45222 \
remoteuser@gateway.example.net
两者是不同的 SSH 会话,不会互相冲突。
关闭其中一个连接,也不会自动关闭另一个连接。
九、检查 Linux 本地隧道
1. 查看监听状态
ss -lntp | grep ':14389'
正常情况下会看到:
LISTEN 0 128 127.0.0.1:14389 0.0.0.0:* users:(("ssh",pid=12345,fd=4))
这说明 Linux 本地的 SSH 进程已经监听端口。
2. 使用 netcat 测试
nc -vz 127.0.0.1 14389
成功时会显示:
Connection to 127.0.0.1 14389 port [tcp/*] succeeded
但这里有一个容易误解的地方。
nc 成功只说明:
Linux 本地能够连接到 SSH 创建的监听端口
它不能单独证明:
远程 Windows 的 3389 一定正常
完整判断应同时满足:
Linux 14389 正在监听
Windows 3389 正在监听
Windows 本机测试 3389 为 True
qwinsta 中存在 rdp-tcp 侦听
十、在 KRDC 中连接
在 KDE Plasma 中打开:
krdc
连接地址填写:
rdp://127.0.0.1:14389
不要填写:
gateway.example.net:45222
因为公网端口是 SSH 入口,不是 RDP 服务。
KRDC 实际连接的是 Linux 本机:
127.0.0.1:14389
SSH 客户端会自动把这条连接送到远程 Windows。
十一、KRDC 的认证信息
假设远程 Windows 信息如下:
Windows 用户名:remoteuser
Windows 计算机名:WIN-REMOTE
KRDC 可填写:
Username: remoteuser
Domain: WIN-REMOTE
Password: Windows 账户密码
另一种写法是:
Username: WIN-REMOTE\remoteuser
Domain: 留空
Password: Windows 账户密码
这里必须使用 Windows 账户密码,而不是:
- Windows Hello PIN;
- SSH 私钥密码;
- FRP 认证密钥;
- Linux 用户密码;
- KDE Wallet 密码。
KRDC 中的密码可以交给 KDE Wallet 保存。
十二、制作便捷启动脚本
为了避免每次手动输入完整命令,可以建立一个简单脚本。
例如:
~/bin/start-windows-rdp
内容如下:
#!/usr/bin/env bash
exec ssh -N \
-L 127.0.0.1:14389:127.0.0.1:3389 \
-p 45222 \
-o ExitOnForwardFailure=yes \
-o ServerAliveInterval=60 \
-o ServerAliveCountMax=3 \
remoteuser@gateway.example.net
创建方法:
mkdir -p ~/bin
cat > ~/bin/start-windows-rdp <<'EOF'
#!/usr/bin/env bash
exec ssh -N \
-L 127.0.0.1:14389:127.0.0.1:3389 \
-p 45222 \
-o ExitOnForwardFailure=yes \
-o ServerAliveInterval=60 \
-o ServerAliveCountMax=3 \
remoteuser@gateway.example.net
EOF
chmod +x ~/bin/start-windows-rdp
以后只需要执行:
start-windows-rdp
然后在 KRDC 中打开已经保存的连接:
rdp://127.0.0.1:14389
关闭时在脚本终端按:
Ctrl+C
这只会关闭 SSH 隧道,不会影响:
- Windows 上正在运行的任务;
- Windows OpenSSH;
- FRP 客户端;
- 普通 SSH 会话;
- 其他网络连接。
十三、使用 SSH 配置别名
也可以在 Linux 的 SSH 配置中定义别名:
Host office-windows
HostName gateway.example.net
Port 45222
User remoteuser
ExitOnForwardFailure yes
ServerAliveInterval 60
ServerAliveCountMax 3
普通 SSH 可以简化为:
ssh office-windows
RDP 隧道可以简化为:
ssh -N \
-L 127.0.0.1:14389:127.0.0.1:3389 \
office-windows
需要注意,如果脚本中写了:
ssh office-windows
但 SSH 配置中没有定义这个别名,就会出现:
Could not resolve hostname office-windows:
Name or service not known
此时系统会把 office-windows 当成真实域名解析,而不是 SSH 别名。
不希望依赖 SSH 配置时,应直接在脚本中写完整主机地址和端口。
十四、让连接更加自动化
可以进一步制作一个启动脚本,先检查端口,再建立隧道。
#!/usr/bin/env bash
set -u
LOCAL_PORT=14389
REMOTE_HOST='gateway.example.net'
REMOTE_PORT=45222
REMOTE_USER='remoteuser'
if ss -lnt | grep -q "127.0.0.1:${LOCAL_PORT}"; then
echo "RDP 隧道已经存在:127.0.0.1:${LOCAL_PORT}"
exit 0
fi
exec ssh -N \
-L "127.0.0.1:${LOCAL_PORT}:127.0.0.1:3389" \
-p "${REMOTE_PORT}" \
-o ExitOnForwardFailure=yes \
-o ServerAliveInterval=60 \
-o ServerAliveCountMax=3 \
"${REMOTE_USER}@${REMOTE_HOST}"
这样可以避免重复运行后出现:
bind: Address already in use
还可以建立 KDE 应用菜单启动项,分别执行:
启动 SSH 隧道
打开 KRDC
不过不建议把隧道做成完全无人值守的永久后台服务,除非确实需要持续使用。
临时启动、用完关闭,更容易理解和控制连接状态。
十五、剪贴板与文件传输
RDP 原生支持剪贴板重定向。
常见效果包括:
Linux 复制文字 → Windows 粘贴
Windows 复制文字 → Linux 粘贴
部分客户端还可以支持:
- 图片复制;
- 文件复制粘贴;
- 本地磁盘映射;
- 音频重定向;
- 打印机重定向。
KRDC 中应检查是否启用了:
Clipboard
Clipboard redirection
对于大文件,不建议长期依赖剪贴板。
更稳定的方式包括:
SFTP
SCP
SMB
RDP 磁盘重定向
文件同步工具
十六、RDP 与 RustDesk 的画质差异
RustDesk 更接近传统远程控制软件:
捕获远程电脑当前屏幕
↓
编码为连续图像或视频流
↓
通过网络发送
↓
客户端解码并缩放
这种方式适合查看远程电脑实体屏幕,也适合作为紧急救援工具。
但在高分辨率桌面上,容易出现:
- 字体边缘模糊;
- 窗口边框不够锐利;
- 快速滚动时出现压缩痕迹;
- 网络波动时降低画质;
- 客户端窗口和远程显示器分辨率不匹配。
RDP 的工作方式不同。
RDP 更接近为远程客户端创建一套远程桌面显示环境,并针对桌面界面进行优化:
- 只传输发生变化的区域;
- 对图形内容进行缓存;
- 针对文字和窗口元素优化;
- 静止桌面时流量很低;
- 分辨率可以配合客户端窗口;
- 剪贴板、音频和磁盘属于协议功能。
对于以下工作,RDP 通常明显优于 RustDesk:
PowerShell
终端
文件管理器
文本编辑器
Excel
系统设置
任务管理器
后台任务监控
相同带宽下,RDP 通常能够提供:
更清晰的文字
更锐利的界面
更低的静态流量
更自然的窗口缩放
十七、RDP 是否一定更省带宽
对于办公桌面和文字界面,通常是。
静止桌面时,RDP 基本只需要发送少量保活和状态数据。
移动窗口、编辑文字或查看任务状态时,只需传输变化部分。
RustDesk 等工具则更依赖屏幕图像编码。即使使用高效视频编码,也通常需要在画质、帧率和带宽之间进行取舍。
但在以下场景中,RDP 的优势会缩小:
- 播放视频;
- 运行高帧率动画;
- 显示大量动态图像;
- 快速滚动图片网页;
- 3D 图形;
- 游戏。
这些内容本身接近视频流,RDP 也需要使用图形或视频编码。
十八、SSH 隧道只转发 TCP
SSH 的 -L 本地端口转发承载的是 TCP。
现代 RDP 在某些环境下也可以使用 UDP,以改善:
- 高延迟;
- 丢包;
- 音频;
- 动态画面;
- 快速交互。
通过 SSH 本地端口转发时,RDP 通常只能使用 TCP 通道。
因此这种方案特别适合:
办公桌面
文字操作
系统维护
文件管理
计算任务监控
轻度图形界面
不适合追求:
云游戏
高帧率视频
低延迟音视频制作
大型 3D 应用
十九、RDP 会话和远程电脑实体屏幕
RustDesk 通常连接的是远程电脑当前正在显示的实体桌面。
RDP 则可能建立或切换到远程会话。
连接后可能出现:
- 远程 Windows 实体屏幕锁定;
- 控制台用户被切换;
- 远程桌面和实体桌面不能同时操作同一会话。
但正常情况下,RDP 连接本身不会自动停止:
- Windows 服务;
- 后台计算任务;
- 计划任务;
- 正确独立运行的程序;
- 系统级进程。
结束使用时,建议在 KRDC 中选择:
Disconnect
断开连接
不要误选:
Sign out
注销
注销会结束 Windows 用户会话,可能同时关闭该会话中运行的应用程序。
二十、故障排查顺序
遇到 KRDC 连接失败时,建议按照从外到内的顺序排查。
1. 检查公网 SSH
ssh -p 45222 remoteuser@gateway.example.net
如果普通 SSH 无法登录,问题可能位于:
- FRPS;
- FRPC;
- 公网防火墙;
- Windows OpenSSH;
- DNS;
- 网络连接。
2. 检查 Linux 隧道
ss -lntp | grep ':14389'
如果没有输出,说明隧道没有建立。
3. 检查本地端口
nc -vz 127.0.0.1 14389
4. 检查 Windows RDP 服务
Get-Service TermService
5. 检查 RDP 开关
Get-ItemProperty `
'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' `
-Name fDenyTSConnections
6. 检查监听器
qwinsta
必须出现:
rdp-tcp 侦听
7. 检查 Windows 3389
Test-NetConnection 127.0.0.1 -Port 3389
必须出现:
TcpTestSucceeded : True
8. 检查 KRDC 地址
必须连接:
rdp://127.0.0.1:14389
不能连接公网 SSH 端口。
9. 检查认证信息
确认:
用户名正确
域名或计算机名正确
使用的是 Windows 账户密码
二十一、常见报错
Could not resolve hostname
Could not resolve hostname office-windows
原因通常是 SSH 别名没有定义,或者主机名拼写错误。
Address already in use
bind: Address already in use
本地端口已经被其他进程占用。
检查:
ss -lntp | grep ':14389'
Connection refused
如果 SSH 隧道终端出现:
channel open failed: connect failed: Connection refused
通常说明:
SSH 已经连接到 Windows
但 Windows 的 127.0.0.1:3389 没有服务监听
KRDC 认证失败
可以尝试:
Username: remoteuser
Domain: WIN-REMOTE
或:
Username: WIN-REMOTE\remoteuser
Domain: 留空
二十二、安全建议
长期使用时建议保持以下原则:
- SSH 优先使用密钥认证;
- Windows 账户不要使用弱密码;
- 公网 FRP 端口尽量限制来源地址;
- 不直接暴露 RDP 3389;
- Linux 本地端口只绑定
127.0.0.1; - 不使用
0.0.0.0:14389,除非确实需要共享; - 不使用长期无人值守的隧道,除非有明确需求;
- 修改 Windows 注册表前先备份;
- 重要任务运行期间不要随意重启 Windows;
- 保留一种独立于 SSH 和 RDP 的应急控制方式。
二十三、推荐的远程管理层次
比较合理的长期结构是:
第一层:SSH
用于命令行、任务管理、脚本和服务检查
第二层:RDP over SSH
用于图形桌面、文件管理和 Windows 应用
第三层:RustDesk
用于 SSH、FRP 或 RDP 失效时的紧急救援
这种组合兼顾了:
- 安全性;
- 画质;
- 带宽效率;
- 操作便利性;
- 故障恢复能力。
结语
FRP、SSH 和 RDP 并不是三个互相替代的工具,而是可以组成一条层次清晰的远程访问链路。
FRP 解决内网主机无法被公网直接访问的问题,SSH 提供安全的远程入口和端口转发,RDP 则提供高质量的 Windows 图形桌面体验。
整个方案的核心是:
公网只开放 SSH
RDP 不直接暴露
Linux 本地临时创建 RDP 入口
用完后关闭 SSH 隧道
对于需要长期运行计算任务、偶尔进入 Windows 图形界面检查状态的远程主机,这种方式通常比长期依赖屏幕捕获型远程控制软件更清晰、更节省带宽,也更适合作为日常主力方案。