# zerotier-one-dual-instance **Repository Path**: hyonex/zerotier-one-dual-instance ## Basic Information - **Project Name**: zerotier-one-dual-instance - **Description**: ZeroTier One 双实例共存版 - 一台机器同时跑公网+私网两个 ZeroTier 实例 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-09 - **Last Updated**: 2026-08-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ZeroTier One 双实例共存版(Dual Instance Patch) 让一台机器同时运行**两个 ZeroTier One 实例**(如:官方公网 cmnet + 自建私有 secondnetwork),两个虚拟网络互不干扰、同时在线。 > 基于 [zerotier/ZeroTierOne](https://github.com/zerotier/ZeroTierOne) 1.16.2 (master) 修改 > 修改人:小龙虾 🦞 (hyonex) · 2026-08-08 --- ## 为什么要改?(背景) ### 问题现象 在一台 Mac 上同时跑两个 `zerotier-one` 实例(如 `9993` 端口连公网、`9994` 端口连私网)时: - **后启动的实例会把先启动实例的虚拟网卡(feth)全部删掉** - 导致先启动的实例**断网**(SSH 走 ZeroTier 的话直接失联) ### 根因(源码级分析) `osdep/MacEthernetTap.cpp` 中,**每个 zerotier-one 进程第一次创建 tap 时**会执行: ```cpp // Destroy all feth devices on first tap start in case ZeroTier did not exit cleanly last time. if (! globalTapInitialized) { globalTapInitialized = true; // 遍历删除所有 feth0 ~ feth9999 设备! } ``` - **设计意图**:ZeroTier 崩溃/断电后 feth 虚拟网卡可能残留,下次启动时主动清理,防止残留干扰(单实例思维下的防御逻辑)。 - **副作用**:多实例场景下,每个进程都有自己独立的 `globalTapInitialized` 标志。**第二个实例启动时会把第一个实例已建好的 feth 设备全部 destroy** → 第一个实例的虚拟网卡消失 → 断网。 ### 为什么 Catalina (1.12.2) 能共存而 Sequoia (1.16.2) 不行? - 1.12.2 的 `MacEthernetTap.cpp` **没有**这段"全局删除 feth"逻辑 - 1.16.2 **新增**了这段清理逻辑 → 双实例冲突 --- ## 怎么改的?(Patch 内容) 只改 1 个文件,删掉"启动时全局删除 feth"逻辑: ```diff - // Destroy all feth devices on first tap start in case ZeroTier did not exit cleanly last time. - // We leave interfaces less than feth100 alone in case something else is messing with feth devices. + // [PATCHED] Disable global feth cleanup to allow multi-instance (dual ZeroTier). if (! globalTapInitialized) { globalTapInitialized = true; - struct ifaddrs* ifa = ... // 删除整个清理块 - ... } ``` 保留 `globalTapInitialized = true;` 标志(避免影响其他逻辑),仅移除"扫描并删除 feth 设备"的行为。 **Patch 文件**:`patches/mac-ethernet-tap-dual-instance.patch` **附带修改**(构建时需要,与双实例无关): - `make-mac.mk`:去掉 `-DZT_SSO_SUPPORTED` 和 rustybits 依赖(跳过 Rust 编译,SSO/zeroidc 功能不需要时可用纯 C++ 快速构建)→ `patches/make-mac-nosso.patch` --- ## 怎么用?(双网配置) ### 前提 - 两个网络的 **planet 不同**(公网用官方 planet,私网用自建 planet) - 两个实例用 **不同端口**(默认 9993,第二个用 9994) - 每个实例有**独立的配置目录**(identity / networks.d / planet) ### 目录结构 ``` /Library/Application Support/ZeroTier/One/ ├── zerotier-one # 主实例二进制(9993,公网) ├── MacEthernetTapAgent # tap agent ├── planet # 公网 planet ├── identity.secret # 主实例身份 ├── networks.d/ │ └── b15644912e7404b2.conf # 公网网络配置 ├── launch.sh # 双实例启动脚本 └── prv/ # 私有实例配置目录(9994,私网) ├── zerotier-one.pid ├── identity.secret # 私有实例身份(可与主实例相同或不同) ├── planet # 私有 planet(自建) ├── networks.d/ │ └── d3a04e0bd837a46e.conf # 私网网络配置 └── MacEthernetTapAgent # tap agent(同一份定制版) ``` ### launch.sh(双实例启动脚本) ```bash #!/bin/bash export PATH="/Library/Application Support/ZeroTier/One:/bin:/usr/bin:/sbin:/usr/sbin" /usr/bin/killall MacEthernetTapAgent >>/dev/null 2>&1 exec zerotier-one & # 主实例 9993(公网) cd /Library/Application\ Support/ZeroTier/One/prv exec zerotier-one -p9994 /Library/Application\ Support/ZeroTier/One/prv & # 私实例 9994(私网) sleep 2 pids=$(ps -e | grep 'zerotier-one' | awk '{print $1}') for pid in $pids; do wait $pid done ``` ### 验证双网 ```bash # 主实例(公网) zerotier-cli info zerotier-cli listnetworks # 应显示 cmnet,IP 如 192.168.196.103/24 # 私实例(私网,端口 9994,目录 prv) zerotier-cli -p9994 -D/Library/Application\ Support/ZeroTier/One/prv info zerotier-cli -p9994 -D/Library/Application\ Support/ZeroTier/One/prv listnetworks # 应显示 secondnetwork,IP 如 192.168.31.103/24 # 连通性 ping 192.168.196.x # 公网对端 ping 192.168.31.x # 私网对端 ``` > 注意:macOS 上 `feth` 设备名 = `feth<编号>`(编号 = 100 + nwid 哈希 % 4900), > 两个实例网络不同 → 设备号不同 → feth 名不同 → 不冲突。 --- ## 三平台编译 ### macOS(Intel / Apple Silicon) ```bash # 需要 Xcode Command Line Tools cd source make -j8 # 产物:zerotier-one, zerotier-cli, zerotier-idtool, MacEthernetTapAgent ``` ### Linux ```bash cd source make -j8 # 产物:zerotier-one, zerotier-cli, zerotier-idtool ``` ### Windows(官方方式:Visual Studio) > ⚠️ ZeroTier 官方 Windows 只支持 **Visual Studio**(MinGW 交叉编译有 std::mutex/平台宏兼容问题,不推荐) ```powershell # 用 Visual Studio 2022 打开源码中的官方解决方案 # 源码目录: source/windows/ZeroTierOne.sln # 选择 Release x64 配置 → 生成 # 产物: windows/x64/Release/ZeroTierOne.exe ``` > 详细脚本见 `scripts/` 目录。 --- ## Release 二进制 见 `release/` 目录: - `zerotier-one-darwin-universal` — macOS 通用版 (x86_64 + arm64) - `zerotier-one-linux-x86_64` — Linux x86_64 - `zerotier-one-win-x86_64.exe` — Windows x86_64 --- ## 许可 - ZeroTier One 本体:**BSL 1.1**(Business Source License) - 本修改:基于上游源码的衍生修改,遵循上游许可 - 源码修改仅移除一段防御性清理逻辑,不影响网络协议/加密/安全特性