Bubu Blog: ~/article $ ls
[个人网络] 基础网络

异地组网

构建之初是希望我的网络在使用上能够像一个局域网一样,其实就是 VPN。

按节点之间的通信来分,VPN 可以分为传统的 C/S 架构以及最近流行的 P2P 架构。

C/S 架构需要一个中心服务器来传输流量,代表软件如 OpenVPN。由于所有服务器都需要经过中心服务器,中心服务器自然成为了网络的瓶颈之一。如果是有大带宽的需求,在中国目前商宽价格贵的离谱的,C/S 架构的 VPN 并不是一个好的选择(有公网 IP 的家宽也可以考虑)。

P2P 架构的 VPN 也成为 Mesh VPN,网络内节点之前连接是直连的,而不用通过某个特定的服务器。这类产品一般会有一个协调服务器记录一下各个节点的信息,当 A 节点想要连接 B 节点的时候,只需要从协调服务器获取对方的 IP 和端口,再发起连接即可。传输过程不需要任何中心服务器的参与,是点对点传输的。

然而实际的网络环境会复杂的很多,稍微加个防火墙规则就可以阻断这种 IP + 端口的传输。所以很多 Mesh VPN 的产品会有一个 Relay 的设计,通过网上一个公开的节点中转数据,以此绕过防火墙规则。

下面我就一些正在使用的产品进行介绍。

Tailscale

Tailscale 是基于 Wireguard 的 P2P VPN,即传输层用的是 Wireguard。考虑到网络环境的复杂性(例如 ISP 会禁用 Wireguard 或者封锁 UDP,全锥形 NAT 等),Tailscale 还设计了 Derp,这样数据包在 HTTPS 的基础上进行中转。

中国移动畅连

中国移动畅连是中国移动推出的异地组网软件。从抓包的数据来看,也是基于 UDP 通信的。

优点:

缺点:

目前发现有一个产品上的漏洞,免费版本的用户在界面上使用远程/RDP/SMB 都会提示免费版不可用,但直接用组网的 IP 是可以访问的,所以可以通过 RDP 或者 NoMachine/Moonlight 等直接通过 IP 访问。

题外话

构建 VPN 是为了节点之间能够互相访问,大部分情况下,意为着你信任这些节点。

当你连接一个不受信任的节点,大部分情况下,用户需求是:

  1. 我可以访问这个节点的所有资源
  2. 这个节点不能访问我的网络

这时候使用 VPN,那就有些不够安全了,当然可以通过配置 ACL 来限制节点之间的访问或者使用防火墙,但属实有些麻烦。

比较好的办法是使用 HTTP/Socks 代理,如果网络环境不好,可以套上一层加密/混淆,比如 SS、SSR、V2ray 等。

Hostname、域名以及 DNS

当网络节点数量增多,IP 数量也随之增加,这时候记 IP 是不可能记了,需要换成 Hostname 或域名等有语义化的方式,这也是 DNS 诞生的背景。

使用搜索域减少输入

而相比域名,我更喜欢使用 Hostname 来访问,需要输入的字符更少,至少不用把手移过去输入 .

然而对每台机器设置 Hostname 比较麻烦,而且 Tailscale 默认只认 Tailnet 上的 Hostname,子网段的机器是不认的。

我用了 DNS 服务器 + DNS 搜索域来解决上述问题。DNS 服务器我用的是 Technitium DNS,运行在国内的 VPS 上。

DNS 服务器维护一个 Zone,以 bb 后缀为例,比如 abc.bb 指向 127.0.0.1

然后在 Tailscale 管理界面上设置 DNS 服务器以及对客户端下发搜索域(Search Domains)。

Hostname 命名规则

遵循一个命名规则,可以快速记住 Hostname,或者在回想 Hostname 的时候作为线索。

规则根据自己的需求、偏好来指定就好,比如我的朋友是根据设备型号来作 Hostname。

这里分享一下我的命名规则:

对于位置、网络接入固定的机器,其 Hostname 组成是 {类型}-{位置代码}{序号}

对于不固定的机器,如手机、笔记本电脑等,其 Hostname 就是一个设备型号或其他助记符

根据以上规则,举几个例子:

关于给 Hostname 取名字,IETF 还出了一个 RFC 作为建议:https://datatracker.ietf.org/doc/html/rfc1178

代理/隧道/端口转发

Mihomo(Clash Meta)

Clash 的分支版本。亮点是内置了订阅处理、支持更全面的协议(如 hysteria 系列、Wireguard)。

目前使用场景:

  1. 优化国内外节点通信:一台上海电信的节点和香港 VPS 建立通信,由于 VPS 线路比较差,直连会绕地球半圈。用 Clash Meta 接入一些机场的节点作为中转可以很好改善这类情况。由于确定了线路,只需要在 proxy-providers 中添加订阅地址,再使用 filter 字段筛选出香港的节点。
  2. 在客户端上分流:内网上有两个教育网的节点,在线情况不稳定,偶尔用于通过教育网出口去查询一些资料。在节点开启 Socks5 代理监听后,再添加到 Clash 的配置中,并设置负载均衡的策略。

Gost

Gost 一般用来快速搭建端口转发,当然作为隧道、代理也是可以的。Gost 的优点就是简单,无需配置文件,直接命令行启动,非常适合快速或临时操作。在 Linux 上希望作为后台运行,也只需要编写一个 type=simple 的 Systemd Service 即可。

内网穿透:Cloudflare Tunnel + 前置代理

由于我海外的 VPS 中,配置/线路至少烂一个。所以我的服务一般不会部署在海外的 VPS 上。国内 VPS 在配置会好一些,但带宽太小,更主要是域名需要备案,比较麻烦。所以选择走“内网穿透”这条线路。

内网穿透比较热门的是 Frp,但前面也说了线路垃圾或者带宽以及备案的原因,使用 Frp 这类走公网服务器中转的线路是不太好使的。国内的商业产品(如花生壳)性价比不高。

相比之下,Cloudflare Tunnel 不仅免费,而且体验也是比较好的,说说其优点:

当然缺点也是有的:

如果需要暴露到公网的服务都是 HTTP,选择 Cloudflare Tunnel 还是很不错的。

前置代理呢?如果直接把部署在国内的服务通过 Cloudflare Tunnel 暴露出去,一到网络高峰时间段,国内节点到 Cloudflare 节点的线路会爆炸,表现为几乎不可用。前置代理就是用来改善两者之间的线路。

但 Cloudflare Tunnel 并不支持直接设置代理,官方也说明了不会支持,软件也不会认如 HTTP_PROXY 等环境变量。

所以需要在本地部署一个代理,然后让 Cloudflare Tunnel 通过这个代理访问。这个代理可以是 Gost,也可以是 Clash Meta。我这里选择 Clash Meta,启动 TPROXY,通过 iptables 来实现代理。

具体看 @Xiaomage 发表的文章:https://blog.xmgspace.me/archives/cloudflare-tunnel-via-proxy.html

目前我的姿势:

  1. 确定连接 Cloudflared 的香港节点
  2. 把机场的订阅放到 Clash Meta,筛选出香港节点,并设置规则组为 url-test,自动选择延时最低的节点,注意服务器节点不要开启流量探测。
  3. 开启 TPROXY,然后设置 IPTABLES 规则