一招 ZTM,轻松搞定远程访问(如 NAS SMB、OpenWrt、Windows)

184 天前
 hanfengzxh

入手极空间 Z4Pro 快两个周了,使用体验文章还得再等一等,多一些深度体验的时间。到目前来看,还是很满意的。

虽然演示里用上 NAS 来运行 Docker ,实际上即使没有 NAS 设备,只要网络中存在任何可以运行 ZTM 组件的设备,都可以实现远程访问。

背景

今天来说说极空间的远程访问功能,产品页面对远程访问的描述是:

让极空间真正成为你家庭中的网络设备控制中心:

  • 无需公网 IP 就可以便捷访问家中路由器、Docker 和智能家居
  • 不用学习网络知识也可以以轻松使用,快速添加
  • 自定义名称及颜色,方便查找与收藏,配合容器使用,扩展丰富功能

比如借助该功能可以方便地管理家中的软路由,非常适合没有公网 IP 的用户。

然后就可以点击新添加的链接,在极空间的窗口内访问 OpenWrt 的 web 后台了。

细心的你可能会注意到它只能支持 HTTP 协议(官方的功能介绍),只能通过极空间窗口访问,并且只能为管理员账号下使用该功能,灵活性大打折扣。比如远程访问家中的 Windows 设备( Windows 的远程桌面协议 RDP );或者需要 ssh 远程访问 HomeLab 虚拟机。

这些极空间的远程访问就无能为力了,这里就要用到 ZTM 了。

关于 ZTM

ZTM( Zero Trust Mesh )是一款开源的网络基础设施软件。它基于 HTTP/2 隧道构建,可以在任何类型的 IP 网络上运行,例如局域网、容器化网络和互联网等。

ZTM 可以在各种环境中使用,从连接家庭和工作场所的 2 节点个人网络,到连接全球办公室和分支机构的 10,000 节点企业网络。

ZTM 可以支持多种 CPU 架构,如 x86, ARM, MIPS, RISC-V, LoongArch 等,以及多种操作系统,如 Linux, Windows, macOS, FreeBSD, Android 。

ZTM 包含了几个核心组件:

方案

在远程访问中,我们需要在极空间中安装 ZTM Agent 。其主动与部署在公有云的 ZTM Hub 建立加密隧道,然后将家庭网络中的服务注册到 Hub 。

位于另一个网络中的电脑或者任意服务器,同样安装 ZTM Agent ,在成功与 Hub 建立隧道后,就可以发现其他 Agent 注册的服务。然后就可以通过创建端口将发现的服务映射到本地。

接下来就开始我们的演示!

演示

在演示中我们将会用台有公网 IP 的云主机,可以购买云厂商 99 元的主机,通常都有 3-4M 的带宽,用来转发 1080P 甚至低码流的 4K 也没压力。

在极空间中,我们是使用 Docker 来运行 ZTM Agent 。Agent 占用的资源非常低,我为容器分配 0.5 核的 CPU 和 128M 的内存,如果流量不大可以分配更少的资源。

1. 运行 ZTM Hub

首先 ssh 到云主机,通过 ZTM CLI 安装 ZTM CA 和 Hub 。 当前最新的 ZTM 为 0.0.3 版本,通过下面的命令安装 CLI 。

ZTM_VERSION=0.0.3

curl -sL https://github.com/flomesh-io/ztm/releases/download/v${ZTM_VERSION}/ztm-aio-v${ZTM_VERSION}-generic_linux-x86_64.tar.gz | tar -zxf -
sudo cp bin/ztm /usr/local/bin/ztm

通过命令 ztm help 可以查看 CLI 的使用方法。

通过下面的命令启动 ZTM 的 CA 服务,非常简单。

sudo ztm start ca --listen 127.0.0.1:9999

接下来是启动 Hub ,默认监听在 8888 端口,同样可以通过参数 --listen 来修改,这里我们使用默认值。

sudo ztm start hub

2. 为 Agent 颁发证书

Agent 与 Hub 建立 HTTP/2 的加密隧道,使用 mTLS 进行双向认证。使用 CA 服务为 Agent 颁发证书,格式为 ztm invite USERNAME --bootstrap HUB_PUBLIC_IP:PORT,这里我们为两个 Agent 颁发证书。将证书保存到 json 文件中并下载到本地,后面会用到。

注意:json 文件中包含了公钥和密钥,请妥善保存。如若遗失,通过 ztm evict USERNAME 吊销证书,然后颁发新的证书。

ztm invite home --bootstrap 13.229.223.113:8888 --output > home.json
ztm invite macbook --bootstrap 13.229.223.113:8888 --output > macbook.json

3. 极空间 Agent 部署

访问极空间 Docker ,在仓库中搜索并下载 addozhang/ztm 镜像。若遇到镜像下载问题,可以从 这里 下载镜像 tar 文件并上传到极空间中,然后在 本地镜像中选择从极空间导入

找到已经下载好的镜像,创建容器。

把前面颁发的证书 JSON 文件上传到极空间中,比如保存到存储的 /Docker/ZTM 目录中,然后在容器的文件夹路径中添加文件路径,装载到容器的 /tmp/ztm 中。

ZTM Agent 提供了 web 界面,为了方便使用可以将容器的 7777 端口映射到本地。

同样,为了便于容器外访问,将环境中的 LISTEN 修改为 0.0.0.0:7777,其他保持默认。

点击应用创建容器。

4. Agent 接入 Hub

Agent 启动之后,最重要的一步就是将其连接到 ZTM Hub 。这里有两种方法:命令行和 Web 界面。

方法一:使用命令行

点击容器的 SSH 按钮,在弹窗中用户输入 ztm( ZTM 的运行不需要任何特权)。

在命令行窗口中执行下面的命令,与 Hub 建立安全隧道,命令格式 ztm join MESH_NAME --as AGENT_NAME --permit JSON_FILE

ztm join my-hub --as zspace --permit /tmp/ztm/home.json

可通过命令 ztm get mesh 查看隧道状态。

注:通过 ztm left MESH_NAME 可以断开与 Hub 的连接。

方法二:使用 Web 界面

在浏览器中打开 http://<极空间 IP>:7777,如果是从外部访问可以使用极空间的远程访问功能添加新的连接:使用 http://127.0.0.1:7777 即可。

Meshes 标签页中点击 Join

填入信息,并点击保存:

保存后在 Meshes 标签页中可以看到刚添加的 Hub ,以及其状态。如果状态不是 Connected 请检查颁发的 JSON 文件的内容。

注:点击 Hub 右侧的三个点,可以修改或者断开连接。

5. 注册服务

想要从外部访问内网的服务,我们需要在内网的 Agent 上将服务注册到 Hub ,即创建两个服务。同样可以使用命令行,或者 Web 界面来操作。

方法一:使用命令行

命令格式为 ztm create service PROTOCOL/SERVICE_NAME --host SERVICE_IP --port SERVICE_PORT。这里我们准备了两个服务:OpenWrt 的 Web 后面和一台开启了远程访问的 Windows 电脑。

ztm create service tcp/openwrt-web --host 192.168.11.1 --port 80
ztm create service tcp/win-11 --host 192.168.11.184 --port 3389

使用命令 ztm get service 可以查看注册的服务。

注:通过 ztm delete service PROTOCOL/SERVICE_NAME 可以注销服务。

方法二:使用 Web 界面

Services 标签页中,点击 Create

填入服务的相关信息,然后点击 Save 保存:

使用同样的方式创建 win-11 服务:

到此,我们已经完成了家庭网络服务的注册。要想从外部网络访问家庭网的服务,我们需要在外网的设备进行类似的操作。

6. 外网 Agent 部署

首先是安装 ZTM ,可以从 这里 下载对应平台的 CLI ,在 mac 平台有支持 x86 和 M 芯片的 CLI ,win 平台上也有对应的 exe 下载。

我在外网的设备是一台 MacBook ,下载的是 arm64 的 CLI 。

curl -sL https://github.com/flomesh-io/ztm/releases/download/v0.0.3/ztm-aio-v0.0.3-macos-arm64.tar.gz | tar -zxf -
sudo cp bin/ztm /usr/local/bin/ztm

安装好 CLI 之后,执行命令启动 Agent ,会自动加入系统服务。

sudo ztm start agent

7. Agent 接入 Hub

重复同样的步骤,使用前面颁发的证书 macbook.json 与 Hub 建立隧道。可以使用命令行或者 Web 界面( http://localhost:7777 )来操作。这里使用命令行来完成,Web 界面的操作可以参考前面的操作。

ztm join my-hub --as macbook --permit macbook.json

检查隧道状态。

ztm get mesh
NAME    JOINED AS  USER     HUBS                 STATUS
my-hub  macbook    macbook  13.229.223.113:8888  Connected

8. 映射服务到本地

服务的映射也是两种方式:命令行和 Web 界面。

方法一:使用命令行

通过下面命令可以查看 Hub 上注册的服务。

ztm get service
NAME             ENDPOINTS
tcp/openwrt-web  1
tcp/win-11       1

服务的映射是通过创建一个本地端口来实现的,格式为 ztm create port LAN_IP/PROTOCOL/PORT --service PROTOCL/NAME

ztm create port 127.0.0.1/tcp/18080 --service tcp/openwrt-web
ztm create port 127.0.0.1/tcp/13389 --service tcp/win-11

检查创建的端口。

ztm get port
NAME                 ENDPOINT  SERVICE
127.0.0.1/tcp/18080  macbook   tcp/openwrt-web
127.0.0.1/tcp/13389  macbook   tcp/win-11

注:通过 ztm delete port LAN_IP/PROTOCOL/PORT 可以删除端口。

方法二:使用 Web 界面

Services 标签页中找到发现的服务,点击服务右上角的按钮。

在弹窗中输入端口的信息。

同样的方式,映射 win-11 服务到本地 13389 端口。

Local Ports 标签中可以看到创建的两个本地端口。

9. 测试

远程访问 OpenWrt

在浏览器中打开 http://localhost:18080 可以成功访问远程的 OpenWrt 。

远程访问 Windows 设备

使用 macOS 平台上的软件 Microsoft Remote Desktop 来访问远程桌面。

添加一台 PC ,地址为 127.0.0.1:13389,账号为 Windows 设备的登录账号。

登录完成后,就可以远程来操作 Windows 设备了。

2577 次点击
所在节点    NAS
36 条回复
OliverLee
184 天前
跟 Tailscale 的区别是?我在极空间部署了 Tailscale 容器,也挺方便的。
Chaiii
184 天前
@OliverLee 同,都有云主机了,直接用来搭建个 derp 节点,结合 tailsacle 使用,能直连就直连,不能直连走 derp 中转多香啊。我一般是旁路由安装 Tailscale 负责宣告路由表,这样只要其他设备都能访问得到。
hanfengzxh
184 天前
@OliverLee @Chaiii 感谢关注。与 Tailscale 方案相比,ZTM 是用户空间的 L7 ( HTTP/2 ) 解决方案,不需要操作网卡、防火墙、路由。。。不需要 root ,整个架构简单。其他的想广泛的协议支持、平台兼容性、性能,都是不输 Tailscale 。倒不是说 Tailscale 不好,二者在实现上对其他运行的环境要求不同。所在在某些受限的场景,ZTM 比 Tailscale 适应性更强。
HOMO114514
184 天前
@OliverLee 带宽受公有云是的 Hub 限制,而国内云服务带宽费是最贵的,so……这玩意儿更像是一个带路由的公网中转
Chaiii
184 天前
@hanfengzxh 不敢苟同。你想从网络协议层面对比的话,第 7 层反而是最外层的,Tailscale 的 WireGuard 协议工作在 OSI 模型的第四层,也就是传输层,它直接处理 IP 数据包,而不是 HTTP 请求。这使得 WireGuard 可以用于任何基于 IP 的通信,不仅仅是 HTTP. 我自己使用的另外一个 Zero Trust 应用是 Cloudflare Tunnel, 不但支持 HTTP2 也支持 QUIC 协议,但是局限性依旧很大,这类应用完全无法比拟虚拟局域网。我举个最简单的例子,数据库和 SSH 协议同为 L7 层应用层,这个时候试问 ZTM 是否还能有效?要知道 IP 层的通信是无状态的,所以需要额外的机制来保持和管理连接状态,这些都增加了实现的复杂性...

> 其他的广泛的协议支持、平台兼容性、性能,都是不输 Tailscale ...
> 所在在某些受限的场景,ZTM 比 Tailscale 适应性更强。

不知道从何得来的结论,请问是否严谨地做过对比测试,直接抛结论没有说服力的,也容易误导不了解情况的人。

我明白楼主自己成功地找到了一个异地组网方案并成功实施的欣喜之情,但这不意味着就能够认为自己的方案一定是最优的,任何事情都需要辩证比较才能下结论。Tailscale 的宣告路由表功能我想楼主并没有实际体会过,简单解释一下,只要你的外地设备进入 Taiscale 网络并接受了你家里的网关设备宣告的路由,从使用体验上来说,你可以完全认为你的家庭设备已经对你的外地设备可见(就好像在一个局域网内,所以叫虚拟局域网)。而且 Tailscale 完全没必要和 ZTM, FRP 一样去为应用做单独的端口映射设置。更何况现在 Tailscale 除了 CLI 管理,还提供了完全基于 Web 界面的用户管理和 access control, 从易用性来说已经是第一梯队了(注意我这里没说是绝对第一)。

像我这种懒人,一个所谓的异地组网工具,要求单独配置端口映射、没有简单可用的 UI 客户端,已经足以劝退。
Chaiii
184 天前
@chowdpa02k413 是的,所以还是建议用一些具备打洞 P2P 直连能力的工具。如果单纯是公网云,那我平时简单使用的话,直接搞个 rustdesk 远程桌面到内网机器得了...
hanfengzxh
184 天前
@Chaiii 首先,第一个点:我说是 L7 的方案,意思是 ZTM 是建立 HTTP/2 的隧道。在这个隧道上,一样可以传输 TCP/UDP 流,并不是说只能传输 HTTP 流。数据库和 SSH ,在 ZTM 上一样没有问题,基于 UDP 的视频流也是 ok 的。你提到的 Cloudflare Tunnel ,这个需要用到 Cloudflare 的中转。

适应性更强,是指我前面说的:ZTM 不需要网络、路由、防火墙的设置,不需要 root 。Tailscale 基于 wireguard ,需要修改本地网络配置和路由,wg 的 peer 需要分配 IP 地址。ZTM 的 peer ( agent )可以是无状态的。

我还是强调一点:“倒不是说 Tailscale 不好,二者在实现上对其他运行的环境要求不同。所在在某些受限的场景,ZTM 比 Tailscale 适应性更强。” 当环境受限,比如无法修改路由、防火墙,无法使用 root ,ZTM 确实适应性更强一些。像 FRP 、ZTM 这种做单独的端口映射,也会减少暴露面:只将特定的端口进行开放。

我也明白你,在看到我拿出一个你完全没有听到的方案,来对比你满意的方案会觉得有些不妥。抱歉,“Tailscale 的宣告路由表”我有用过; ZTM 也有提供 CLI 和 Web 界面,一样也有 access control 。

最后再强调一次,没有通用场景的最优解,只有特定场景的,并不是说 Tailscale 不好。
hanfengzxh
184 天前
@chowdpa02k413 带宽贵这点我非常认同,所以有提到 99 元一年的云主机,3/4 M 的固定带宽,不限流量(不是在打广告哈)。
Chaiii
184 天前
@hanfengzxh 听你这么一解释,我就理解 ZTM 优势的地方了,刚好我自己有个地方可以用到,谢谢。
hanfengzxh
184 天前
@Chaiii 不客气,多多交流哈。
xxxccc
184 天前
我司也有这样的网络基础设施,主要就是解决边缘节点之间的通信问题,我们是使用类似 ssh tunnel 的能力来实现的。
hanfengzxh
184 天前
@xxxccc 握手,异曲同工的实现啊。ZTM 我们还在端侧设备上运行,比如摄像头这种。可以看下我在另一个帖子发的 ZTM 的介绍 https://www.v2ex.com/t/1050990
Chaiii
183 天前
fishioon
183 天前
相对 tailscale 的方案,这个更像代理;还是 tailscale 完美
hanfengzxh
183 天前
@Chaiii 😄 还是手试过才知道,你这链接是故意的么
Achophiark
183 天前
这类产品已经很多,目前成熟的当属 frp 、tailscale 、zerotier 等,但 ztm 的图形界面真的是脱俗,第一眼就很赏心悦目,只是效率如何需要测试一下。
hanfengzxh
183 天前
@Achophiark 成熟的产品确实有,不过 ZTM 还一些场景上有优势的,可以看看 #3 #7 我的回复。
gray0128
181 天前
感谢分享!有个问题想问题一下,我在 unraid 中使用 docker 部署了 agent ,其他都正常,就是不能使用 ip:7777 访问服务,不知问题出在哪里?
hanfengzxh
181 天前
@gray0128 Docker 容器怎么配置的,有没有把容器端口映射出来?
gray0128
181 天前
@hanfengzxh 有映射,bridge 172.17.0.5:7777/TCP 192.168.31.254:7777 。目前注册服务,代理访问都很正常,就是不能用 web 访问。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1050886

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX