如何在 VPS 上自行托管 NetBird VPN 服务器
在一台 VPS 上部署 NetBird 网状 VPN,涵盖 DNS、TLS、固定版本 quickstart 脚本和无人值守对等节点的 setup key,并对比 Headscale。
自行托管 NetBird VPN 服务器的作用
自行托管 NetBird VPN 服务器后,控制平面会运行在您拥有的 VPS 上。控制平面保存对等节点列表,决定哪些机器可以访问哪些机器,并帮助位于 NAT(网络地址转换)之后的两个对等节点互相发现。隧道本身仍使用 WireGuard,直接在您的机器之间加密传输。变化在于,您的设备清单和登录流程不再由外部公司托管。需要明确这一方案的实际收益:托管式控制平面同样不会持有用于加密流量的密钥,而且在阅读 协调服务器遭入侵后实际能做什么 之前,大多数人通常会高估它的能力范围。
NetBird 位于您可能已经了解的两类方案之间。它是一个网状覆盖网络,因此对等节点会彼此连接,而不是将所有流量都发送到同一个网关。它还支持端到端自行托管,因此可与 自行托管的 Tailscale 控制服务器 Headscale 对比。如果您过去只运行过单网关隧道,请先阅读 普通 WireGuard 与网状覆盖网络的区别。只有理解这种网络模型,才能更好地使用本页后续内容。
如果您的实际需求是让所有流量都从一台服务器出口,使用网状网络就超出了需求范围。在单个 VPS 上运行普通 WireGuard VPN 或 使用 Tailscale 出口节点 即可实现这一点,同时需要运行的组件少得多。如果您的目标是访问一个私有网络,而不是让多台机器彼此互联,在 VPS 上运行 Tailscale 子网路由器 可以将该网段发布到您已有的 tailnet,无需部署下面介绍的整套组件。
实际运行的组件
近期调整了架构,大多数旧文档描述的都是旧架构。截至 August 2026,版本为 v0.76.2 时,quickstart 脚本默认会写入一个包含 3 个服务的 Compose 文件。
netbird-server提供管理 API、信号服务、内置 STUN 监听器的中继服务,以及内置身份提供商。在旧版本中,这些组件分别运行在不同容器中,身份提供商则是单独安装的 Zitadel,必须先自行构建。dashboard是管理 Web 控制台。traefik负责终止 TLS(传输层安全),并在首次启动时向 Let's Encrypt 申请证书。
另外还有 2 个服务。除非在提示中确认启用,否则它们不会启动。NetBird Proxy 服务会通过公共主机名发布内部服务。CrowdSec 会过滤滥用流量。构建可用的 mesh 不需要这两个服务,而且在小型服务器上运行它们都会占用内存。
如果您之前使用的是 单个 Docker 容器中的 wg-easy,那么这里的组件数量会明显增加。换来的好处是可以使用访问策略和按用户划分的账户,并且各个 peer 可以彼此直接连接,而不必通过一个网关。
开始前的准备工作
公网域名不是可选项。仪表板、API 和中继服务都通过 443 端口使用 HTTPS,Traefik 通过 HTTP challenge 从 Let's Encrypt 获取证书。此流程要求域名从公网解析到这台 VPS。直接使用 IP 地址无法完成此流程。
创建一条 A 记录,将 netbird.example.com 指向 VPS 的公网 IPv4 地址。等待 DNS 生效后再执行任何操作。
dig +short netbird.example.com该命令必须输出服务器的地址。在 DNS 传播完成前运行安装程序,会导致首次启动时证书请求失败。反复验证失败还会触发 Let's Encrypt 的速率限制,因此之后需要等待一小时才能再次尝试。
必须允许互联网访问 3 个端口:TCP 80 用于证书 challenge 和重定向到 HTTPS;TCP 443 用于仪表板、API、信令和中继流量;UDP 3478 用于 STUN。
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3478/udp
sudo ufw reload
sudo ufw status还要在服务商的网络防火墙中开放这些端口。大多数 VPS 控制面板将其作为独立的控制项。这也是服务器自身的 ufw status 配置看似正确,但仍拒绝连接的原因。
STUN(用于 NAT 的会话穿越工具)用于让对等端获知其自身 NAT 分配的公网地址和端口,从而使两个对等端能够尝试建立直接隧道。阻止 UDP 3478 后,对等端仍会通过 TCP 443 上的中继建立连接,因此表面上看不到明显故障。但每个对等端都会显示 Connection type: Relayed,并且所有流量都会经过 VPS,而不是在对等端之间直接传输。
软件方面需要安装带有 Compose v2 插件的 Docker,以及 jq 和 curl。脚本会检查所有这些组件,缺少任何一项都会停止运行。如果这台服务器刚安装 Docker,请先完成在 VPS 上运行 Docker Compose。
跳过捆绑反向代理时的端口
不使用 Traefik 时,各项服务会直接暴露,因此需要开放的端口更多:
- TCP 80,HTTP 重定向
- TCP 443,HTTPS
- TCP 33073,管理 gRPC
- TCP 10000,信令 gRPC
- TCP 33080,通过 WebSocket 或 QUIC 传输中继流量
- UDP 3478,STUN
仅当服务器已经为其他服务终止 TLS 时,才选择此方式。否则,使用捆绑的 Traefik 所需规则更少,也更不容易出错。
使用快速启动脚本安装 NetBird 服务器
文档中的单行命令会直接将最新版本发布内容通过管道传入 shell:
curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh | bash请固定版本。latest 会变化,因此相隔两周执行同一条命令可能得到两个不同的安装结果,而且磁盘上不会记录哪个版本写入了配置。请下载带标签的版本,先阅读脚本,再执行它。
mkdir -p ~/netbird
cd ~/netbird
curl -fsSL -o getting-started.sh \
https://github.com/netbirdio/netbird/releases/download/v0.76.2/getting-started.sh
less getting-started.sh
bash getting-started.sh脚本首先询问域名:
Enter the domain you want to use for NetBird (e.g. netbird.my-domain.com):然后询问如何处理 TLS:
Which reverse proxy will you use?
[0] Traefik (recommended - automatic TLS, included in Docker Compose)
[1] Existing Traefik (labels for external Traefik instance)
[2] Nginx (generates config template)
[3] Nginx Proxy Manager (generates config + instructions)
[4] External Caddy (generates Caddyfile snippet)
[5] Other/Manual (displays setup documentation)
Enter choice [0-5] (default: 0):选择 [0]。选项 2 到 5 会写入配置片段,并将后续配置交给您处理。在已经运行代理的服务器上,这样做是正确的;但在全新服务器上则不合适。选项 0 随后会询问 Let's Encrypt 电子邮件地址,用于接收证书过期通知。
首次安装时,请拒绝 NetBird Proxy 服务。它需要另外添加两个 DNS 记录:proxy.netbird.example.com 和通配符记录 *.proxy.netbird.example.com;而普通网状网络并不需要它。CrowdSec 也请拒绝。两者都可以稍后添加。
脚本会将文件写入当前目录:docker-compose.yml、权限为 600 的 config.yaml、dashboard.env,以及在选择捆绑的 Traefik 时生成的 traefik-dynamic.yaml。请将该目录视为需要保留的状态目录,因为 config.yaml 中保存着用于加密存储数据的密钥。丢失该目录无法通过重新安装修复。
docker compose ps
docker compose logs -f netbird-server每个服务都应读取 running,服务器日志也应停止循环重启。请单独监控证书:
docker compose logs traefik | grep -i acmeACME(自动证书管理环境)是 Traefik 用于获取证书的协议。这里出现错误时,原因几乎总是 DNS 配置错误或 80 端口未开放。
创建第一个管理员帐户
打开 https://netbird.example.com。在全新安装中,这里显示的是设置页面,而不是登录表单。输入电子邮件地址、姓名和密码,然后单击 Create Account。该帐户会成为第一个管理员,页面随后重定向到登录表单。
该帐户存储在 NetBird 自带的用户存储中,由嵌入 netbird-server 容器的身份提供商提供支持。整个过程不涉及外部服务。这是它与一年前的自托管 NetBird 之间最大的变化。当时,要让安装正常运行,必须先部署 Zitadel 或 Keycloak,再将 4 个 OIDC(OpenID Connect)值复制到 setup.env 中,否则服务根本无法启动。
如果浏览器显示证书警告,而不是设置页面,说明证书未签发。请先修复此问题再继续,因为控制面板会通过同一主机名与 API 通信;证书错误会导致通信失败,而且故障表现通常不直观。
加入第一个对等节点
在任意 Linux 机器上安装客户端。如果希望将 VPS 加入网状网络,也可以直接在 VPS 上安装:
curl -fsSL https://pkgs.netbird.io/install.sh | sh在 Debian 和 Ubuntu 上,该脚本会配置 NetBird 软件包仓库,然后通过 apt 安装客户端,因此最终都由软件包管理器负责管理。如果不希望将脚本通过管道传给 shell,请先使用 curl -fsSL -o install.sh https://pkgs.netbird.io/install.sh 保存脚本,阅读后再运行 sh install.sh。无论采用哪种方式,都应确认实际安装的内容:
apt-cache policy netbirdnetbird 是命令行客户端和守护进程。netbird-ui 是桌面托盘应用,无头服务器不需要它。
现在让客户端连接到您的服务器:
sudo netbird up --management-url https://netbird.example.com省略 --management-url 时,客户端会向 NetBird 托管服务注册,因为这是编译时的默认设置。命令仍会成功执行,机器仍会获得地址,但自托管控制面板仍为空。这是最常见的错误之一。
命令会输出一个 URL。请在浏览器中打开该 URL 以完成登录。完成后:
netbird status
ip addr show wt0从 netbird status 中读取4行:Management: Connected、Signal: Connected、报告所有可用中继的 Relays: 行,以及 overlay 地址范围内的 NetBird IP:。wt0 是 NetBird 创建的 WireGuard 接口,并且应使用同一个地址。
使用设置密钥以无人值守方式加入第二台计算机
对于没有浏览器且无人操作的计算机,浏览器登录无法使用。设置密钥是一种预认证令牌,可在不执行交互式步骤的情况下注册计算机。在控制面板的 Setup Keys 下创建设置密钥。
设置密钥有两种类型。一次性密钥只能认证一台计算机,使用后即失效。可复用密钥可注册多台计算机,也可以设置数量上限。两种密钥都需要设置过期时间,并且都可以在新对等端加入时自动将其分配到某个组,因此该组的访问规则会立即生效。
sudo netbird up --setup-key <SETUP-KEY> \
--management-url https://netbird.example.com \
--hostname build-runner-01--hostname设置控制面板中显示的名称。如果不设置该项,对等端会使用计算机自身报告的名称;如果整个计算机集群中的条目都显示为 ubuntu,则无法有效区分它们。
对于容器和生命周期较短的构建代理,创建密钥时将其标记为临时密钥。使用临时密钥注册的对等端离线超过 10 分钟后会自动删除,从而避免对等端列表中残留已失效的条目。
在规划使用设置密钥之前,需要了解一个限制:密钥过期或删除后,只会阻止新的注册,不会断开已经使用该密钥注册的计算机。要移除某台计算机的访问权限,必须移除该对等端。
是否仍需要单独的身份提供商?
对于小型部署,不需要。内置用户存储可以管理从控制面板创建的账户,少量用户使用它就足够了。
如果您已经有外部身份提供商,并且不想维护第二套用户列表,则应使用外部身份提供商。NetBird 接受支持 OIDC 的任何提供商。在您的提供商中注册一个机密 OIDC 客户端,然后在 NetBird 控制面板中填写4项信息:名称、客户端 ID、客户端密钥和 issuer。NetBird 会提供一个重定向 URL,您需要将其粘贴回提供商中。NetBird 为 Google、Microsoft Entra ID、Okta、Zitadel、Keycloak、Authentik 和 Pocket ID 提供预配置集成,其他提供商则使用通用 OIDC 配置。如果您已经运行 Authentik 作为自托管单点登录服务,使用此方式即可保留一套账户列表,而不是两套。
添加提供商后,本地登录仍然可用,所有已配置的提供商都会显示在登录页面上。保留一个使用强密码的本地 admin 账户。这样,即使 OIDC 配置损坏,您仍然可以登录。
NetBird 还是 Headscale:应运行哪个控制平面?
两者都移除了同一个依赖项,即客户端原本需要回连的托管控制服务器。但它们的项目形态不同。
Headscale 重新实现了 Tailscale 控制服务器,因此您仍使用官方 Tailscale 客户端。它没有官方 Web 控制台。您通过 `headscale` 命令操作配置文件,以管理用户和预认证密钥。社区提供了一些 Web 界面,但这些界面不属于该项目。如果您希望将状态保存在文件中,并通过版本控制管理变更,Headscale 更适合您。
NetBird 提供完整产品:自有客户端、自有控制面板、内置身份提供商,以及可在浏览器中编辑的访问策略。这会在您的 VPS 上引入更多组件,但如果需要交给不会打开终端的同事管理,所需工作会少得多。
如果您已经在使用 Tailscale 客户端,或希望控制平面尽可能精简,请运行 Headscale。如果需要由多人管理对等节点,并且希望直接获得控制台和 SSO,而不自行组装,请运行 NetBird。在决定使用哪一个之前,请先了解 Tailscale 免费套餐实际包含哪些内容,因为如果团队不超过 six 个用户且设备数量不限,托管控制平面无需付费,您可能根本没有必要自行运行控制平面。超过这一上限后,费用会随人数而不是机器数量增长,因此请先计算 Tailscale 会向您的团队收取多少费用,再将其与 VPS 成本及维护这套技术栈所需的时间进行比较。
这套服务最低需要多小的 VPS?
文档规定的最低配置是 1 个 CPU 和 2 GB 内存。NetBird 的说明指出,用户管理改为本地处理后,目前最低内存需求约为 1 GB;旧版架构包含完整的 Zitadel 部署,当时需要 2 GB 到 4 GB。建议购买 2 GB 配置。额外的内存余量可以让升级过程在旧镜像仍保留在磁盘上时拉取新镜像。
在配置较小的服务器上,可以安全地省略以下 3 项。不要启用 NetBird Proxy 服务。该服务用于通过公网主机名发布内部服务,与节点之间建立连接无关。不要启用 CrowdSec。对于已暴露到公网的服务器,可以稍后再添加,不必在初始部署时启用。保留 netbird_data 卷中的默认 SQLite 存储。只有在将部署拆分到多台机器,或遇到实际并发需求时,才迁移到 PostgreSQL;文档说明这项迁移可以稍后进行。
中继是不能省略的组件。如果 NAT 为每个目标分配不同端口,两个节点就永远无法建立直接隧道。此时只有中继可以让它们建立连接。禁用中继只能节省很少的内存,却会导致连接失败,而且故障原因很难追踪。
当一台服务器无法满足需求时,应首先将中继迁移出去。独立中继使用 NB_LISTEN_ADDRESS、NB_EXPOSED_ADDRESS、NB_AUTH_SECRET 和 NB_ENABLE_STUN 运行。中继和主服务器上的共享密钥必须完全一致,否则客户端无法通过身份验证连接到中继。
故障现象及排查方法
控制面板显示证书警告。 Traefik 未获取证书。运行 docker compose logs traefik | grep -i acme。通常有两个原因:dig +short netbird.example.com 尚未解析到此 VPS,或 Let's Encrypt 与容器之间的某处关闭了 TCP 80,通常是服务商的网络防火墙,而不是 ufw。重试前先修复原因,不要循环重试,因为验证失败受速率限制,您可能会在 1 小时内无法再次尝试。
客户端提示已连接,但控制面板为空。 由于缺少 --management-url,客户端注册到了 NetBird 托管服务。运行 netbird status --detail 并读取 Management: 行,该行会显示客户端实际连接的服务器。若看到 Management: Connected to https://api.netbird.io:443,说明客户端连接到了云端。运行 sudo netbird down,然后再次运行 sudo netbird up --management-url https://netbird.example.com。
所有对等节点都显示 Connection type: Relayed。 未建立直接隧道,因此所有流量都会经过您的 VPS,并增加一跳延迟。检查 VPS 防火墙和服务商防火墙上的 UDP 3478,因为 STUN 用于帮助对等节点获知自身的公网地址和端口。netbird status --detail 还会输出 Direct: false 以及每个对等节点的 ICE(交互式连接建立)候选类型,从而显示连接尝试进行到了哪一步。在某些网络中,中继是唯一可用的结果,这不表示存在问题。
对等节点加入后无法访问任何资源。 加入网状网络不代表两个对等节点可以互相通信。访问策略决定通信权限,而未关联任何策略的组无法访问任何资源。在排查路由和防火墙前,先检查控制面板中的策略。
netbird status 报告守护进程问题。 服务未运行。使用 sudo netbird service status 和 sudo netbird service start。客户端日志位于 /var/log/netbird/client.log。对于无法定位的问题,netbird debug bundle --anonymize --system-info 会将日志、状态、路由、DNS 设置和防火墙状态收集到一个归档文件中。
备份和升级
整个安装依赖两项内容:保存 docker-compose.yml 和 config.yaml 的目录,以及保存数据库和加密密钥的 Docker 卷。请将它们一起备份。config.yaml 保存用于加密存储数据的密钥,因此没有它,单独恢复数据库副本后无法读取任何数据。
docker volume ls
docker compose down
sudo tar czf netbird-config.tgz -C ~ netbird
docker run --rm -v netbird_netbird_data:/data -v "$PWD":/backup \
alpine tar czf /backup/netbird-data.tgz -C /data .
docker compose up -dCompose 会使用项目目录作为卷名称前缀,因此文档中写作 netbird_data 的卷通常会显示为 netbird_netbird_data。请先运行 docker volume ls,并使用它输出的名称;否则,上面的 docker run 会静默创建一个空卷,并且不会归档任何内容。请将归档文件存放在 VPS 之外。如果已有备份工具,可以使用 restic 或 BorgBackup 完成异地备份。
升级服务器包括拉取镜像并重新创建容器:
docker compose pull
docker compose up -d
docker compose ps在依赖此流程前,请运行 docker compose config | grep image:。任何值为 latest 的标签都应固定为具体版本,原因与固定安装脚本版本相同:您需要确认当前运行的内容,并在升级出现问题时能够回退到某个版本。客户端通过安装它们时使用的软件包管理器进行升级。
FAQ
我需要自行部署身份提供商才能自托管 NetBird 吗?
不需要。当前版本包含内置用户存储,您可以在浏览器中通过 https://netbird.example.com 创建第一个管理员账户,之后再从控制面板添加用户。外部 OIDC 提供商是可选项,之后可以使用 4 个值添加:名称、客户端 ID、客户端密钥和签发者。要求您先于 NetBird 部署 Zitadel 或 Keycloak 的指南,描述的是现在已不再需要的配置。照此操作会额外增加一个需要运行的服务。
为什么我的所有对等节点都显示 Connection type: Relayed?
直连未建立,因此流量会经过 VPS 上的中继。通常原因是 UDP 3478 被阻止。对等节点使用该 STUN 端口发现自身的公网地址和端口。请在 VPS 防火墙以及云服务商单独提供的网络防火墙中放行该端口,然后再次运行 netbird status --detail 并读取 Direct: 行。如果网络中的 NAT 会为每个目标分配不同端口,那么只能使用中继,这不表示配置有误。
我的客户端已连接,但控制面板中没有显示对等节点。发生了什么?
客户端注册到了 NetBird 的托管服务,而不是您的服务器。这通常是因为未设置 --management-url。netbird status --detail 会在 Management: 行输出其连接的服务器,因此其中显示类似 https://api.netbird.io:443 的值即可确认这一点。运行 sudo netbird down,然后运行 sudo netbird up --management-url https://netbird.example.com,对等节点就会出现在控制面板中。
自托管 NetBird 与 Headscale 有什么区别?
两者都会用您自行运行的控制服务器替代托管控制服务器。Headscale 只有控制平面:您通过 headscale 命令和配置文件管理它,没有官方 Web 控制台,并且由它驱动官方 Tailscale 客户端。NetBird 在同一套组件中提供自有客户端、管理员控制面板和身份提供商集成。Headscale 运行规模更小,并将状态保存在文件中。对于不使用终端的用户,NetBird 更容易交付使用。
自托管 NetBird 服务器需要多大规格的 VPS?
文档规定的最低配置是 1 个 CPU 和 2 GB 内存,建议购买 2 GB 内存的实例。由于身份提供商现在已内置,不再需要单独部署,近期版本的实际最低内存需求已降至约 1 GB。安装时停用可选的代理和 CrowdSec 服务。除非确实需要 PostgreSQL,否则继续使用默认的 SQLite 存储。