2026年7月22日 1 分钟阅读

小团队临时连机想要统一 IP 网段?用 TunD 自建一张受限的虚拟 IPv4 LAN

tinyash 0 条评论
复古纸张插画中的网线、空白怀表与网络设备静物

远程协作里有一类需求很具体:几台电脑不在同一物理局域网,却要像接到同一交换机一样,用固定的私有地址直接互通。它可能是一次联机测试、一次临时演示,或者一个只信任少数参与者的内部实验。此时,人们常常先想到通用 VPN;但如果你的目标只是让一组机器拥有一张小而明确的 IPv4 虚拟网,TunD 提供了另一种更窄的选择。

TunD 是一个自托管的虚拟局域网工具。它在每台参与机器上创建三层 TUN 接口,把 IP 包经由 UDP 汇聚到一台 Hub,再分发给其他客户端。项目核心以 C11 编写,Linux、macOS 使用系统网络接口,Windows 使用 Wintun;v2.1 发布包提供了 Windows、macOS 与 Linux 的 GUI 或 CLI 资产。它不是通用 VPN 的替代品,而是为小型、可信组的“直接 IP”场景准备的专用通道。

先判断:它解决的是哪一个网络问题?

TunD 的网络结构很直白:一台机器运行 Hub,其他机器以客户端接入。Hub 使用 10.9.0.1,客户端从 10.9.0.210.9.0.254 自动顺序分配,整个虚拟网固定为 10.9.0.0/24。每个端点的 TUN MTU 设为 1400,用来给 UDP 封装留出空间并降低常规分片的概率。

Client A (10.9.0.2) ── UDP ──┐
                              ├── TunD Hub (10.9.0.1)
Client B (10.9.0.3) ── UDP ──┘

这意味着它特别适合“双方都能明确输入对方虚拟 IP”的软件或测试环境。Hub 只要可被其他成员访问;若跨互联网部署,就要让入口 UDP 端口可达。默认端口是 9909,因此服务器防火墙至少要为可信来源放通该 UDP 端口。

但不要把“虚拟 LAN”误读为“完整二层网络”。TunD 不传输 Ethernet 帧,不支持 IPv6,也不承诺任意组播发现协议可用。某些局域网游戏或工具依赖二层广播、组播发现时,自动发现可能失败;更稳妥的做法是改用手动输入 10.9.0.x 地址。若本地网络或另一条 VPN 已经使用 10.9.0.0/24,则应先处理路由冲突,而不是强行启动。

最小可复现流程:一台 Hub,两个客户端

先从 Releases 页面取得对应平台的 CLI;Linux 的独立二进制名为 tund-cli-linux-x86_64,下文把它简写为 ./tund-cli。Hub 与所有客户端必须共享同一把长随机密钥。不要把密钥直接塞进命令行:那会出现在 shell 历史和进程列表中。

在 Hub 上生成密钥并启动服务:

openssl rand -base64 24 > tund.key
chmod 600 tund.key
sudo ./tund-cli server --key-file tund.key

在客户端加入。--key-stdin 会从标准输入读取或提示输入密钥,避免在参数中暴露它:

sudo ./tund-cli client -s 203.0.113.10 -n "dev-laptop" --key-stdin

这里的 203.0.113.10 只是文档保留的示例地址,必须换成实际 Hub 的可达 IP 或主机名。客户端需要 -s/--server;可用 -p/--port 覆盖默认 UDP 9909,用 -n/--name 设定显示名称。Linux 需要创建 TUN 设备的权限,Windows 则应从管理员终端运行 CLI,并保留发布包附带的 wintun.dll

接入后,先用虚拟地址检查路径。例如 Hub 与某个客户端间可测试:

ping 10.9.0.1

若系统防火墙禁用了 ICMP,不应立刻断定隧道失败。可以在 Hub 上监听一个 TCP 端口,再从客户端连接:

nc -l 10.9.0.1 7777

nc 10.9.0.1 7777

这一步把“UDP 隧道已接通”和“ICMP 恰好被本机策略阻止”区分开,也更接近应用真正需要的连通性。

加密不等于对 Hub 保密:最重要的边界

TunD 的文档没有回避它的信任模型。每个 UDP 数据报使用共享密钥做认证加密,项目技术文档说明采用 Monocypher 的 XChaCha20-Poly1305 AEAD;报文有序号和每端点的小型滑动窗口,用于丢弃重放的序号。没有密钥的节点不应能注册为 Peer 或向虚拟网注入流量。

不过,这只是端点到 Hub 之间的传输保护。Hub 为了路由数据包,必须解密数据,因此它并不是“Hub 也看不到内容”的端到端设计。项目的安全策略明确建议只在可信 Hub 与可信参与者之间使用,不要把它当作通用隐私 VPN,更不要把它当作生产级 VPN 的替代方案。

这个限制反而可以成为部署清单的一部分:

  1. Hub 由谁控制、谁能读到其日志与磁盘?
  2. 共享密钥是否通过受保护渠道分发,并在活动结束后轮换?
  3. UDP 9909 是否只对必要来源开放?
  4. 该业务是否真的容许 Hub 参与信任边界?

只要其中任何一项回答是否定的,就应回到 WireGuard、Tailscale、ZeroTier 或符合组织要求的生产 VPN 方案,而不是试图用 TunD 补齐它并未承诺的能力。

接入失败时,按路径而不是按直觉排查

临时网络最常见的误判,是把所有问题都归因于“UDP 被墙了”。更节省时间的排查顺序是先确认 Hub 进程是否真的已绑定预期端口,再确认云安全组与主机防火墙是否允许 UDP 9909,最后才检查客户端的地址、密钥和本地路由。客户端启动时需要能解析并抵达 Hub;若 Hub 位于家庭网络,还要确认路由器的端口转发目标没有随着 DHCP 变化。

连接已建立但业务仍不可用时,先看业务是否把服务绑定在正确接口。只监听 127.0.0.1 的服务不会因为 TunD 存在就自动对 10.9.0.x 开放;需要按照该服务自身的安全模型,明确监听虚拟接口或合适的全部接口,同时用本机防火墙限制来源。反过来,也不要为了省事而把测试服务暴露到公网。隧道解决的是参与者之间的三层可达性,不替应用做访问控制。

还应把 MTU 当作一个可观察的边界,而不是一个神秘参数。TunD 将 TUN MTU 固定为 1400,是为了容纳 UDP 封装。若某类应用对大包、路径 MTU 或分片非常敏感,先在小范围内做真实传输测试,再决定是否纳入活动;不要仅凭小 ping 包成功就推断所有流量模式都可靠。项目给出的固定地址和固定 MTU 有利于复现问题:记录客户端名称、虚拟地址、Hub 日志时间与复现步骤,下一次排查就不必从猜网络开始。

从“能跑”走向“可维护”的两件事

第一,先验证构建而非只验证连接。源码仓库在 Linux/macOS 上可用 make 构建,make verify 会执行格式检查、lint、单元测试、UDP 集成检查、错误密钥拒绝检查、sanitizer、原生构建以及 Windows 交叉构建。对于准备自行编译或二次集成的团队,这比一次 ping 成功更有价值。若只使用官方 Release,也应固定记录下载的版本、目标平台和校验结果,并避免把不同版本的 Hub 与客户端混在同一场活动中;协议兼容性问题往往比网络错误更难从现场症状辨认。

第二,把密钥、地址和端口视为一次活动的配置,而非聊天记录里长期复用的常量。将 Hub 地址、端口、参与者清单和开始/结束时间放进受限的运行说明;结束时撤销端口转发、删除临时密钥,并确认没有留下自动启动的服务。这样即使下一次仍选用 TunD,也能以新的信任边界重新开始,而不是继承一张没人说得清谁还持有密钥的旧网络。

第三,在参加者增加之前做一次容量和故障演练。让一台客户端主动断开,再重新接入,确认地址分配和应用重连是否符合预期;同时观察 Hub 端的资源与日志。TunD 的定位是小型可信组,越早把它限制在这个范围,越不会在参与者、流量或合规要求变化后,误把实验工具承担成基础设施。

第四,把应用层的最低验证写成可执行清单。对需要直接连接的游戏、调试服务或演示程序,记录由哪台客户端发起、目标使用哪个 10.9.0.x 地址、成功时应看到什么输出。网络工具只保证路径存在,最终是否能完成协作仍由应用协议、监听地址、身份验证和防火墙策略共同决定。

TunD 最适合的是明确知道自己只需要什么的人:一台可信 Hub、少量可信机器、一个可验证的 IPv4 私网,以及一次有结束时间的协作。它不试图覆盖所有 VPN 场景,恰好也让部署者更容易看清何时应该停止使用它。

相关链接

发表评论

你的邮箱地址不会被公开,带 * 的为必填项。