SSH|SSH 内网穿透实现远程桌面
两个局域网的主机要进行远程桌面,必须进行内网穿透。frp 是一个不错的选项。但其实不依赖外部的工具,仅仅利用系统的 SSH 也能实现,而且在安全性上可能会更好。
最终架构
参与该网络的各个机器、端口、执行的命令及其顺序如下图所示:
文章图片
实现步骤
假设我们现在在办公室有一台 MacOS 主机 C,要连接家里的 MacOS 主机 A。
- 购买一台公网服务器 B,且具有公网 IP。带宽可能要的比较大,见下文的说明。假设公网 IP 为 123.1.2.3,其 SSHD 端口为 22。
- 在主机 A 上,开启 VNC 服务:前往 System Preferences->Share,勾选 Screen Share。它会监听本机的 5900 端口。
- 在主机 A 上,开启 SSHD 服务:前往 System Preferences->Share,勾选 Remote Login。它会监听本机的 22 端口。
- 在主机 A 上,开启 SSH 反向隧道:
ssh -gNTR 127.0.0.1:7000:127.0.0.1:22 root@123.1.2.3
。这里相当于在公网服务器 B 上开了一个新的 SSHD 服务代理,其端口是 7000(这里是示例端口,可以自己修改,下同)。 - 在公网服务器 B 上,通过 7000 端口代理的 SSHD 服务,建立一个到主机 A 的 VNC 服务的反向代理:
ssh -p 7000 -N -L 127.0.0.1:5900:127.0.0.1:5900 admin@127.0.0.1
(admin 表示主机 A 的登录用户名,请改成自己使用的)。这里就相当于公网服务器 B 提供了一个 VNC 服务,其端口为 5900。 - 在主机 C 上,建立一个到公网服务器 B 的 VNC 服务的反向代理:
ssh -N -L 127.0.0.1:5900:127.0.0.1:5900 root@123.1.2.3
。这里就相当于主机 C 提供了一个 VNC 服务,其端口为 5900。 - 在主机 C 上,打开 Finder->Go->Connect to Server,填写
vnc://127.0.0.1
,然后在弹出的用户密码框中输入远程主机的登录用户名(如示例的 admin)及其密码,就可以访问咯。或者用命令行打开:open vnc://127.0.0.1:5900
效果 以上所有的端口都是本地 127.0.0.1 的,除了公网服务器 B 需要对外暴露 SSHD 端口(22),无需再暴露任何其他主机、其他端口,而且使用 OpenSSH 加密通信数据,相对来说比较安全。当然上面用了公网服务器的 root 用户,你也可以新建一个低权限用户来做这个,进一步提升安全性。
但是也存在一些需要关注的问题、优化的地方。最大的一个问题就是卡顿。在 1Mbit/s(其实只有 100KB)的公网带宽服务器上,效果一般。打字什么的没什么问题。要是传送文件,挤占带宽后会导致屏幕完全没法操作。浏览网页比较卡顿,可以看到明显的延迟(尤其是滚动页面时)。这一点相比 TeamViewer 免费版来说都差很多。很大的原因可能还是 VNC 的协议不如 TeamViewer,OpenSSL 的加密也比较重。公网带宽提升到 10Mbit/s 可能会比较流畅,当然还要确保家里的电脑的上传带宽也足够(>=10Mbit/s),可以用 http://www.speedtest.cn/ 测试下网速。
其他的一些问题:
- SSH 有时候不太稳定,容易断掉。可以考虑使用 autossh 之类。
- 输入文字时会有一个大的光标,可能是协议实现的问题。
- 使用 MacOS 自带的 VNC 客户端,复制文件只能通过拖拽方式,无法直接 CMD+C、CMD+V。但复制文字可以用快捷键。
- 如果远程主机配置了屏保,有时候取消屏保特别慢。这个时候可以先断开连接,重新连。可能还是带宽不足的并发症。
推荐阅读
- SSH|SSH 免密
- ssh生成公钥秘钥
- 为Google|为Google Cloud配置深度学习环境(CUDA、cuDNN、Tensorflow2、VScode远程ssh等)
- 运维|如何限制IP 通过 SSH连接服务器
- 运维|Linux 禁止用户或 IP通过 SSH 登录
- 后台|NATAPP内网穿透通过nginx实现一个端口访问多个不同端口服务
- 服务器|用旧手机搭建服务器并实现内网穿透不需要root(本人亲测很多次最简单的一个)
- [内附完整源码和文档]|[内附完整源码和文档] 基于JSP SSH框架的客车网上售票系统的设计与实现
- NATAPP免费实现内网穿透
- Mac生成ssh|Mac生成ssh key,通过ssh-keygen命令