转发 Windows 远程桌面连接的几种方案



购买了一台美国西海岸的 Windows VPS, 使用远程桌面连接它时非常卡顿,先试试通过一台优质线路的 Linux VPS 转发到这台 Windows VPS 的远程桌面连接,看看能不能改善由于网络问题引起的远程桌面连接卡顿。

使用场景

有三台设备:

  • 设备 A, Windows, 就是日常用的电脑
  • 设备 B, Linux, 有公网 IP
  • 设备 C, Windows, 允许远程桌面连接,采用方案一时无需公网 IP, 其它方案需要公网 IP

A 通过远程桌面连接 C 时网络不稳定,需要通过 B 进行中转。

阅读本文时假定你具有基本的 Windows 和 Linux 使用经验。

方案一:使用 frp

frp 是一个快速的反向代理 (fast reverse proxy). 它支持 TCP 和 UDP, 以及 HTTP 和 HTTPS 协议。

frp 包含 frps 和 frpc 两个可执行文件 (在 Windows 系统中是 frps.exe 和 frpc.exe), 以及对应的配置文件,使用的时候,不要搞混淆了。

下面将在设备 B 上运行 frps, 在设备 C 上运行 frpc.

为了便于理解,这里不会使用服务端,被控端,远控端等术语,也无需知道内网穿透等概念。你只需要记得,设备 A 使用远程桌面通过设备 B 登录设备 C.

1 在设备 B 上运行 frps

首先使用以下命令在设备 B (Linux) 上下载并解压 frp, 并进入解压后的目录:

1
2
3
wget  https://github.com/fatedier/frp/releases/download/v0.49.0/frp_0.49.0_linux_amd64.tar.gz
tar -xf frp_0.49.0_linux_amd64.tar.gz
cd frp_0.49.0_linux_amd64

然后将 frps.ini 文件的内容修改成下面这样:

1
2
3
[common]
bind_port = 7000
token = 6984387498563980

bind_port 是 frps 监听端口,用于接收 frpc 的连接。
token 是鉴权使用的 token 值,相当于密码,可以自己写一个,后面会用到。

然后使用以下命令运行 frps:

1
nohup ./frps -c frps.ini > frps.log 2> frps.log &

上面的命令表示在后台运行 frps, 并且在关闭终端后仍然运行。实际运行的命令是 ./frps -c frps.ini.

设备 A 将通过此设备的 3389 端口连接设备 C. 如果此设备开启了防火墙的话,请在防火墙中放行 3389 和 7000 端口。

2 在设备 C 上运行 frpc

首先使用以下命令在设备 C (Windows) 上下载并解压 frp, 并进入解压后的目录:

1
2
3
curl -sSOL https://github.com/fatedier/frp/releases/download/v0.49.0/frp_0.49.0_windows_amd64.zip
tar -xf frp_0.49.0_windows_amd64.zip
cd frp_0.49.0_windows_amd64

注:从 Windows 10 build 17063 开始,tarcurl 两个命令在 Windows 中可用,详见 Tar and Curl Come to Windows. 如果你的系统中没有这个两个命令,你可以手动下载并解压 frp.

然后将 frpc.ini 文件的内容修改成下面这样:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[common]
server_addr = b.b.b.b
server_port = 7000
token = 6984387498563980

[rdp]
type = tcp
local_ip = 127.0.0.1
local_port = 3389
remote_port = 3389

请将 b.b.b.b 换成设备 B 的实际 IP.
token 是鉴权使用的 token 值,设备 C 和设备 B 使用一样的 token 就行。
3389 是远程桌面连接将会用到的端口。

然后使用以下命令运行 frpc.exe:

3 在设备 A 上使用远程桌面连接设备 C

在设备 A 上打开远程桌面连接,在计算机 (computer) 中填写设备 B 的 IP (因为要通过设备 B 中转). 然后输入设备 C 的用户名和密码就可以了。

方案二:使用 Xshell

Xshell 是一个强大的 SSH 客户端,家庭和学校用户可以免费使用 Xshell, 请从 这里 下载它。

1 设备 A 使用 Xshell 登录设备 B

首先在设备 A 上下载并安装 Xsehll.

然后打开 Xshell, 在其中新建一个会话,主机填写设备 B 的 IP.

然后在用户身份验证中填写设备 B 的用户名和密码。

配置好了之后使用 Xshell 通过 SSH 登录设备 B.

2 Xshell 设置 SSH 隧道

打开上面的 Xshell 会话属性,在 “SSH > 隧道” 中点击添加按钮。

在转移规则中,侦听端口填写一个本地未被占用的端口,如 33899. 目标主机填写设备 C 的 IP, 目标端口填写 3389.

添加完成之后会出现在之前的窗口中。

然后关闭前面的 SSH 连接 (如果后面出现问题,这里可以先关闭 Xshell, 再重新打开 Xsell), 再重新打开这个配置 SSH 隧道后的 SSH 连接。

3 在设备 A 上使用远程桌面连接设备 C

在设备 A 上打开远程桌面连接,在计算机 (computer) 中填写127.0.0.1:33899. 然后输入设备 C 的用户名和密码就可以了。

方案三:使用 ssh

ssh 自身就支持流量转发,这也是上面方案二的原理。

最新的 Windows 10 和 Windows 11 包含一个内置的 SSH 服务端和客户端。我们可以使用它中转远程桌面连接。

下面的操作是和上面的方案二对应的,而且它完全通过命令行进行,更加简单。

首先在设备 A 上运行以下命令打开一个到设备 B 的 SSH 连接,并且通过 -L 33899:c.c.c.c:3389 选项指定流量转发规则。

1
ssh -L 33899:c.c.c.c:3389 [email protected]

请将 c.c.c.c 换成设备 C 的实际 IP.
请将 b.b.b.b 换成设备 B 的实际 IP.
33899 是 ssh 流量转发监听的本地端口。
3389 是远程桌面连接将会用到的端口。

然后在设备 A 上打开远程桌面连接,在计算机 (computer) 中填写127.0.0.1:33899. 然后输入设备 C 的用户名和密码就可以了。

需要注意的是,服务器上的 SSHD 的默认配置不会限制 TCP 转发,如果它被限制了,请看这里 SSH 端口转发.

方案四:使用 Nginx

1 在设备 B 上开启 Nginx 转发

Nginx 的 stream 模块可以用于转发 tcp 和 udp 流量,我们可以使用它转发远程桌面连接。

这个模块默认没有启用,需要自行安装并启用。

Nginx 的安装与配置就不介绍了,这不是本文重点。下面将直入正题。

Nginx 的配置文件 nginx.conf 内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
user www-data;
worker_processes auto;
pid /run/nginx.pid;

include modules-enabled/*.conf;

events {
    worker_connections 1024;
}

stream {
    server {
        listen 3389;
        proxy_pass c.c.c.c:3389;
    }

    # 如果需要启用 udp 的话
    server {
        listen 3389 udp;
        proxy_pass c.c.c.c:3389;
    }
}

请将 c.c.c.c 换成设备 C 的实际 IP.

然后重启 Nginx.

设备 A 将通过此设备的 3389 端口连接设备 C. 如果此设备开启了防火墙的话,请在防火墙中放行 3389 端口。

2 在设备 A 上使用远程桌面连接设备 C

在设备 A 上打开远程桌面连接,在计算机 (computer) 中填写设备 B 的 IP (因为要通过设备 B 中转). 然后输入设备 C 的用户名和密码就可以了。

方案五:使用 firewalld

firewalld 提供一个动态管理的防火墙。它功能强大并且易于使用,可以使用它的端口转发功能转发远程桌面连接。

firewalld 的安装与配置就不介绍了,这不是本文重点。下面将直入正题。

1 在设备 B 上开启 firewalld 端口转发

首先,在设备 B (Linux) 上开启 firewalld 端口转发。依次执行以下命令。

a: 开启防火墙伪装, 开启后才能转发端口

1
firewall-cmd --add-masquerade

b: 添加端口转发规则

1
firewall-cmd --add-forward-port=port=3389:proto=tcp:toport=3389:toaddr=c.c.c.c

请将 c.c.c.c 换成设备 C 的实际 IP.

c. 让以上设置永久生效

1
firewall-cmd --runtime-to-permanent

如果要移除端口转发规则,使用以下命令:

1
2
3
firewall-cmd --remove-forward-port=port=3389:proto=tcp:toport=3389:toaddr=c.c.c.c
firewall-cmd --remove-masquerade
firewall-cmd --runtime-to-permanent

2 在设备 A 上使用远程桌面连接设备 C

在设备 A 上打开远程桌面连接,在计算机 (computer) 中填写设备 B 的 IP (因为要通过设备 B 中转). 然后输入设备 C 的用户名和密码就可以了。

总结

本文一共介绍了五种转发远程桌面连接的方案。总结如下:

方案 配置设备 A 配置设备 B 配置设备 C 设备 C 公网 IP 特点
不需要 需要 需要 不需要 连接稳定
需要 不需要 不需要 需要 无需命令行操作
需要 不需要 不需要 需要 完全命令行操作
不需要 需要 不需要 需要 具有更多控制选项
不需要 需要 不需要 需要 Linux 系统自带

简单来讲,如果设备 C 没有公网 IP, 那么显然方案一是最优的,而且它连接稳定。

如果需要对更精细地控制转发功能,那么应该使用方案四,毕竟 Nginx 的反向代理功能非常强大。

其他方案可以根据自己的需要使用。