本文记录:在受限出口网(出站强过滤、对称 NAT)里,不用第三方远控公有云,而是用自己的云主机把本机 Linux 当前桌面透出去的完整方案。
目标链路(端口与域名请按自己的环境替换):
1 | 外网 VNC 客户端 |
1. 环境与约束
| 项 | 典型情况 |
|---|---|
| 被控端 | Linux 图形会话已登录(如 lightdm + Xorg :0) |
| 中转节点 | 自有云主机,已有 nginx 与 HTTPS |
| 受限出口网出站 | HTTP/HTTPS 正常;普通 SSH 端口常超时 |
| DPI | 非 HTTP/TLS 载荷(SSH 横幅、普通二进制)即使改端口也会被 RST |
| NAT | 对称型(Symmetric),打洞不可靠,必须中继 |
| 本机常见现状 | 可能已有 xrdp(新会话,不是当前屏幕);Docker 可用 |
结论:必须让“控制通道”长得像 HTTPS,桌面内容再通过隧道转发。直接把 VNC 暴露到公网、或走明文中继端口,在受限出口网里都不稳。
2. 走过的弯路(RustDesk)
曾在云主机上部署 RustDesk Server OSS(hbbs / hbbr),两端能配对,但受限出口网连明文中继时:
- HTTP 探测可保持连接
- SSH / 二进制握手约几十毫秒后被 RST
- 客户端常见报错:
Failed to receive public key/Connection reset by peer
尝试过 nginx 把 WebSocket 路径反代到 RustDesk 的 WS 端口。社区版桌面端注册 WebSocket 会收到 NOT_SUPPORT,需要 RustDesk Server Pro 才完整支持。因此放弃 RustDesk,改用 frp over WSS + x11vnc。
xrdp 适合“另开一套桌面”;若要看到本机当前屏幕,用 x11vnc。
3. 最终架构
1 | ┌──────────────┐ TCP <对外端口> ┌─────────────────────────────┐ |
要点:
- frpc → frps 走
protocol = wss、server_port = 443,伪装成 WebSocket over TLS,过受限出口网 DPI。 - x11vnc 只绑 localhost,公网只看到云主机上的对外映射端口。
- nginx:普通访问仍是站点;带
Upgrade: websocket的请求转到 frps。
下文用占位符:
<你的域名>:云主机域名<token>:frp 鉴权令牌<本地VNC端口>:如常用的本机 VNC 端口<对外映射端口>:frpremote_port,需安全组放行
4. 云主机配置
(若受限出口网 SSH 不通,可用云厂商的网页/Workbench 类通道执行。)
4.1 安装并启动 frps
GitHub Release 在受限出口网/部分云主机上可能下不动,可改用 Docker 镜像(版本与客户端一致即可):
1 | mkdir -p /opt/frp |
bind_addr = 127.0.0.1:控制口只本机可连,由 nginx 反代。proxy_bind_addr = 0.0.0.0:让对外映射端口听在公网网卡上(另需安全组放行)。
4.2 nginx:443 上把 WebSocket 转给 frps
保留站点原有路径;对根路径按 Upgrade 分流(示意):
1 | location @frps_ws { |
1 | nginx -t && systemctl reload nginx |
4.3 安全组
入方向增加:
- 协议:TCP
- 端口:
<对外映射端口> - 源:尽量写外网客户端公网 IP,不要长期
0.0.0.0/0
443 / 80 给站点与证书续期用。
5. 被控端(受限出口网内)配置
5.1 安装 x11vnc
若镜像源出现 Hash 校验和不符,换官方/高校源下载对应 deb,校验 SHA256 后再 dpkg -i,并 apt-get install -f。
设 VNC 密码(仅本机 x11vnc 用):
1 | mkdir -p ~/.vnc ~/frp |
5.2 常驻 x11vnc(systemd –user)
1 | # ~/.config/systemd/user/x11vnc.service |
1 | systemctl --user daemon-reload |
5.3 frpc 配置与启动
1 | # ~/frp/frpc.ini |
受限出口网直连 Docker Hub 可能被 RST,可用国内镜像加速拉取同版本 frpc:
1 | docker pull <镜像加速前缀>/snowdreamtech/frpc:<版本> |
6. 外网怎么连
- 安全组已放行你的公网 IP → TCP
<对外映射端口> - 安装任意 VNC 客户端,例如 TigerVNC / RealVNC / Remmina,或 macOS 自带
vnc:// - 连接:
<你的域名>:<对外映射端口> - 密码:本机
x11vnc -storepasswd设置的密码
看到的是被控机当前 :0 桌面。
7. 自检清单
| 步骤 | 期望 |
|---|---|
| 本机 VNC | 仅 127.0.0.1:<本地VNC端口> 在听 |
| frpc | 日志含 login to server success |
| 云主机映射 | frps 在听 <对外映射端口> |
| 隧道握手 | 在云主机对本机映射端口读到 RFB 003.008 |
| nginx | nginx -t 通过;站点首页仍可打开 |
| 外网不通 | 先查安全组,再查 frpc 是否掉线 |
8. 安全建议
- 不要把 frp
token、VNC 密码、真实域名/IP/端口写进公开博客或 git。 - 安全组对外映射端口尽量锁源 IP。
- x11vnc 保持
-localhost,不要直接对公网监听。 - 不用时停掉
frpc或关掉安全组对应端口。
9. 小结
受限出口网的核心限制往往不是“没有公网 IP”,而是 DPI 只放行像 HTTPS 的流量,加上对称 NAT。
在自有云主机上用 nginx(443) + frp WSS + 本机 x11vnc,可以把当前桌面稳定透到外网,且不依赖第三方远控厂商的中继云。
若以后要网页里看桌面,可在云主机再加 noVNC/websockify 指到对外映射端口(同样建议鉴权与 IP 限制);当前方案以外网原生 VNC 客户端为主,链路最短。