Skip to content

ZeroTier — mihomo ​

mihomo 可以作为用户态节点加入 ZeroTier 虚拟网络,并在代理配置中把流量路由进去。该节点完全在用户态运行——不需要系统 ZeroTier 服务或内核 TUN 设备——并通过所指定的 ip-stack 承载 TCP/UDP。它支持私有 planet、moon(orbit)以及 ZeroTier 的 TCP 中继回退。

出站 ​

位于 proxies: 下、type: zerotier 的条目。内嵌 BasicOption(通用出站字段,如 dialer-proxy、interface-name、routing-mark 与 ip-version)。

字段类型默认值允许值描述
namestring(required)<string>唯一的代理名称。同时参与生成默认 state-dir,因此在未设置 state-dir 时,重命名代理会让节点获得新的身份。
networkstring(required)<16-hex-digit network ID>要加入的 ZeroTier 网络,填写 16 位十六进制网络 ID。
state-dirstringzerotier/<network>-<hash of name><directory path>保存节点持久状态及其默认身份的目录。相对于 mihomo 工作目录解析,且必须位于安全路径范围内。
identity-secretstring(from state-dir)<identity.secret contents>完整的 identity.secret 内容(address:0:public-key:private-key),必须包含私钥。会覆盖 state-dir 中保存的身份,且不会写入该目录。
planetstring(built-in Earth planet)<planet file path>私有 planet 文件路径,用于替换内置的根服务器(自建根节点)。启动时读取并校验。
mtuint(controller MTU)1280-10000虚拟网络的本地 MTU 覆盖值。它只能调低控制器分配的 MTU(控制器未下发时为 2800)。
ip-stackIPStackOption(auto)IPStackOption承载该网络 TCP/UDP 流量的用户态 IP 栈。与 WireGuard 页面上的同名块相同(mode、congestion-controller)。
physical-mtuint1432510-10324ZeroTier 在物理网络上发送的最大 UDP 载荷。
udpboolfalsetrue | false允许 UDP 流量经过该出站。
remote-dns-resolveboolfalsetrue | false在 ZeroTier 网络内解析目标主机名,使用控制器下发的 DNS 服务器(设置了 dns 时使用 dns)。关闭时主机名由 mihomo 常规解析器解析。
dns[]string(controller-provided)<nameserver> | …覆盖控制器下发的 DNS 服务器。仅在 remote-dns-resolve 为 true 时使用;查询经由该出站发送。
low-bandwidthboolfalsetrue | false减少后台流量,并降低网络配置的刷新频率。
encrypted-helloboolfalsetrue | false发送的 HELLO 数据包使用 ZeroTier 的扩展(协议 13)加密。
primary-portint00-65535主本地 UDP 端口。0 表示选取任意可用端口。
secondary-portint0-1 | 0-65535第二个本地 UDP 端口。0 表示选取可用端口(离线约两分钟后重新选取);-1 表示禁用。必须与 primary-port 不同。
tcp-fallback-modestringautoauto | force | disableTCP 中继回退。auto 保留 UDP,仅在直连 UDP 失败后改用中继;force 全部经由中继发送;disable 从不使用中继。
tcp-fallback-relaystring204.80.128.1:443<host:port>TCP 回退中继地址。默认值为 ZeroTier 的公共中继。
orbit[]ZeroTierOrbitOption[][ZeroTierOrbitOption]除 planet 之外要加入的联邦根世界(moon)。每个 world ID 只能出现一次。
remote-trace-targetstring(unset)<10-hex-digit node ID>接收本节点诊断追踪信息的节点 ID。
remote-trace-leveluint6400 | 10 | 15 | 20 | 30发送给 remote-trace-target 的追踪详细程度:0 normal、10 verbose、15 rules、20 debug、30 insane。大于 30 的值会被拒绝。

源码: adapter/outbound/zerotier.go:108-130 · 锚定版本 v1.19.31 (ab405ba)

orbit[] ​

字段类型默认值允许值描述
worldstring(required)<16-hex-digit world ID>moon 的 world ID。
seedstring(required)<10-hex-digit node ID>该 moon 中某个根服务器的节点 ID,用于获取 world 定义。

源码: adapter/outbound/zerotier.go:132-135 · 锚定版本 v1.19.31 (ab405ba)

ip-stack 块(mode、congestion-controller)的说明见 WireGuard 页面。

示例 ​

加入一个网络的最简出站(首次启动后,在控制器中授权该节点):

yaml
proxies:
  - name: zt
    type: zerotier
    network: "0123456789abcdef"
    udp: true

固定身份、使用控制器 DNS 解析主机名,并让底层流量经由另一个代理发送:

yaml
proxies:
  - name: zt-home
    type: zerotier
    network: "0123456789abcdef"
    identity-secret: "0123456789:0:<public-key>:<private-key>"
    remote-dns-resolve: true
    udp: true
    dialer-proxy: ss1

自建根节点、加入一个 moon,并强制使用 TCP 中继:

yaml
proxies:
  - name: zt-private
    type: zerotier
    network: "0123456789abcdef"
    planet: ./zerotier/planet
    orbit:
      - world: "0123456789abcdef"
        seed: "0123456789"
    tcp-fallback-mode: force

说明 ​

  • 只有位于网络控制器所分配路由内的目标可达;其他目标会以 "outside ZeroTier managed routes" 失败。若要让一般流量经由该网络发送,控制器必须通过某个充当网关的成员下发相应路由。
  • state-dir 默认为 mihomo 工作目录下的 zerotier/<network>-<SHA-256(name) 的前 12 位十六进制>,因此每个出站都有独立的身份。保留该目录(或设置 identity-secret)即可在重启后保持相同的节点 ID;在私有网络中,新的 ID 需要重新授权。
  • 配置了 identity-secret 时,若与其他节点发生地址冲突,无法通过轮换身份解决;mihomo 最多每 30 秒重试一次,直到另一个节点离开。
  • mtu 只会调低 MTU:生效值取控制器 MTU(限制在 1280–10000,未下发时为 2800)与 mtu 中较小者。
  • 除非 remote-dns-resolve: true,否则 dns 会被忽略。启用后,该出站的主机名解析会经由 ZeroTier 网络本身发往控制器的 DNS 服务器(或 dns)。
  • 设置 dialer-proxy 后,ZeroTier 的底层流量会经由另一个出站发送;此时它会为每个对端使用独立的 UDP 套接字,而非共享套接字。
  • ZeroTier 支持默认编译在内。使用 no_zerotier 构建标签的版本仍接受该配置结构,但会在启动时以 "ZeroTier support is disabled" 失败。

跨内核说明 ​

源码: adapter/outbound/zerotier.go:108-130 · v1.19.31 (ab405ba)

由 Argsment 出品的 Core Tutorial