概述 链接到标题
用 NetBird 自建控制平面,替换现有的 WireGuard VPN 手动组网。控制平面部署在云服务器上,所有节点通过 P2P WireGuard 隧道互联。
步骤 链接到标题
1. Traefik v2 → v3 升级 链接到标题
现有 Traefik 版本是 v2.10.7,先升级到 v3.7.5 为后续路由做准备。
兼容性分析:
- 文件配置文件(File provider)的 YAML 语法完全兼容,无需改动
--serversTransport.insecureSkipVerifyCLI 参数名不变ipwhitelist中间件重命名为ipAllowList,在 v3 中需要手动迁移- 升级时需要加
--core.defaultrulesyntax=v2保持路由语法兼容,确认稳定后移除
升级步骤:只需改 Docker Compose 的 image tag,重启即可。
2. NetBird 控制平面部署 链接到标题
控制平面用 Docker Compose 部署,使用 NetBird v0.65+ 的合并容器架构,不再需要分开的 management/signal/relay/coturn 四个容器。
架构:
netbirdio/netbird-server— 合并容器,包含 management + signal + relay + STUNnetbirdio/dashboard— Web 管理界面- SQLite 存储(无需 PostgreSQL)
Traefik 路由:
nb.example.com→ dashboard(Web UI)api.nb.example.com→ combined server(gRPC + REST API + WebSocket)
3. 内网 DNS 服务器 链接到标题
在办公室的节点上用 Docker 部署 dnsmasq 2.93,提供 *.lan 域名解析。
选型:dnsmasq 仍然是最轻量的内网 DNS 方案。2026年5月 dnsmasq 被通报了 6 个 CVE(CVE-2026-2291 等),修复版本 2.93,务必使用最新版。
镜像:使用 dockurr/dnsmasq(GitHub 开源,500K+ pulls),支持 arm64。由于 Docker Hub 被墙,通过 DaoCloud 镜像拉取。
4. NetBird Agent 安装 链接到标题
两个节点安装 agent:
- 云服务器(控制平面所在节点)— 也需要装 agent,控制平面和 agent 是两回事,可以共存
- 办公室节点(同时跑 dnsmasq)
踩坑记录 链接到标题
Signal 连接不上 链接到标题
现象:agent 的 Management 显示 Connected,但 Signal 始终 Disconnected。日志报错 missing port in address。
原因:NetBird 合并容器的 exposedAddress 配置中必须包含端口号。例如 https://api.example.com:443,否则客户端解析 Signal URI 时获取不到端口,gRPC 拨号失败。
解决:在 config.yaml 的 server.exposedAddress 中显式加上 :443。
DNS 端口冲突 链接到标题
现象:dnsmasq 无法启动,报错 Address in use。ss 发现 NetBird agent 内部 DNS 代理占用了 53 端口。
原因:NetBird agent 收到 Nameserver Group 配置后,会在本地启动 DNS 代理监听 53 端口。与已有 dnsmasq 冲突。
解决:在 DNS 服务器所在的节点上禁用 NetBird 的 DNS 代理:
{"disable_dns": true}
写入 /etc/netbird/config.json 后重启 agent。
FQDN 解析失败 链接到标题
现象:短名 server-a 能解析,但 server-a.lan(FQDN)返回 NXDOMAIN。
原因:dnsmasq 的 expand-hosts 只对 /etc/hosts 中的短名生效,自动添加 domain 后缀。但通过 NetBird Nameserver Group 发来的查询已经是 FQDN 格式(server-a.lan),expand-hosts 不会再次匹配。
解决:使用 dnsmasq 的 address=/ 指令显式声明 FQDN 映射:
address=/server-a.lan/10.0.0.50
address=/server-b.lan/10.0.0.51
而非依赖 /etc/hosts + expand-hosts。
STUN 端口未开放 链接到标题
现象:两个 agent 注册后无法建立 P2P 连接,Nameserver 显示 required key not available。
原因:STUN UDP 3478 端口未在云服务器安全组中开放,NAT 穿透失败。
解决:在安全组中添加 UDP 3478 入站规则。
最终拓扑 链接到标题
云服务器 (控制平面 + agent)
├── Traefik v3 (nb.example.com / api.nb.example.com)
├── NetBird combined server (Docker)
└── NetBird agent (WireGuard peer)
│ P2P 隧道
办公室节点 (agent + dnsmasq)
├── NetBird agent
└── dnsmasq 2.93 (Docker, host network)
│
└── 解析 *.lan 域名
所有节点 → Nameserver Group → 办公室节点:53 → 解析 *.lan
总结 链接到标题
NetBird 的自建方案已经成熟,合并容器架构让部署简化很多。关键点是配置文件中的细节(端口号、DNS 代理冲突、FQDN 格式),踩过一遍就清楚了。