SSD Nodes Learn 🎉 VPS $4.99/月起
指南 Matt Connor作者: Matt Connor

在VPS上自托管NetBird VPN服务器

了解NetBird v0.76.2的3服务架构,完成DNS、TLS和Let's Encrypt配置,固定quickstart脚本,并用设置密钥无人值守加入对等节点,再与Headscale比较。

自托管 NetBird VPN 服务器的作用

自托管 NetBird VPN 服务器后,控制平面会运行在您拥有的 VPS 上。控制平面保存节点列表,决定哪些机器可以访问哪些机器,并帮助位于 NAT(网络地址转换)之后的两个节点互相发现。隧道本身仍使用 WireGuard,由您的机器直接进行加密通信。变化在于,您的设备清单和登录流程不再由外部公司托管。

NetBird 结合了两种您可能已经了解的特性。它是一个网状覆盖网络,因此节点彼此连接,而不是将所有流量发送到同一个网关。它也支持端到端自托管,因此可与 自托管的 Tailscale 控制服务器 Headscale 对比。如果您以前只运行过单网关隧道,请先阅读 普通 WireGuard 与网状覆盖网络的区别,因为这个模型有助于理解本页后续内容。

如果您的实际需求是让所有流量都从同一台服务器出口,使用网状网络就超出了需求。在单个 VPS 上运行普通 WireGuard VPN使用 Tailscale 出口节点 即可实现这一点,而且需要运行的组件少得多。

实际运行的组件

该架构最近发生了变化,许多旧文档介绍的仍是旧架构。截至 August 2026,版本 v0.76.2 的 quickstart 脚本默认会写入包含 3 个服务的 Compose 文件。

  • netbird-server 提供管理 API、信令服务、内置 STUN 监听器的中继服务,以及内置身份提供商。在较早版本中,这些组件分别运行在不同容器中,身份提供商还是一个独立的 Zitadel 安装,必须先自行构建。
  • dashboard 是管理 Web 控制台。
  • traefik 负责终止 TLS(传输层安全),并在首次启动时向 Let's Encrypt 申请证书。

此外还有 2 个服务。除非在提示中确认启用,否则它们不会启动。NetBird Proxy 服务会通过公网主机名发布内部服务。CrowdSec 会过滤滥用流量。构建可用的网状网络不需要这两个服务,而且在小型主机上运行它们会占用内存。

如果您之前使用的是 单个 Docker 容器中的 wg-easy,那么这里的组件数量会明显增加。换来的是访问策略和按用户管理的账户,以及可以彼此直接连接、无需经过单个网关的对等节点。

开始前的准备工作

公网域名不是可选项。仪表板、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 用于证书验证和重定向到 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,以及 jqcurl。脚本会检查所有这些依赖项,缺少任意一项都会停止运行。如果此服务器刚安装 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.yamldashboard.env,以及选择内置 Traefik 时生成的 traefik-dynamic.yaml。请将此目录视为需要保留的状态目录,因为 config.yaml 保存了用于加密存储区数据的密钥。丢失该目录无法通过重新安装修复。

docker compose ps
docker compose logs -f netbird-server

每个服务都应读取 running,并且服务器日志应趋于稳定,而不是反复重启。请单独监控证书:

docker compose logs traefik | grep -i acme

ACME(自动证书管理环境)是 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 netbird

netbird 是命令行客户端和守护进程。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: ConnectedSignal: 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,则没有任何帮助。

对于容器和短生命周期的构建代理,请在创建密钥时将其标记为 ephemeral。使用 ephemeral 密钥注册的对等节点离线超过 10 minutes 后会自动删除,从而避免无效条目留在对等节点列表中。

在规划使用设置密钥的方案前,还需要了解一个限制:密钥过期或被删除后,只会阻止新的注册,不会断开已经使用该密钥注册的计算机。要撤销某台计算机的访问权限,必须删除对应的对等节点。

是否仍然需要单独的身份提供商?

对于小型部署,不需要。内置用户存储可以管理从控制面板创建的帐户,几个人使用时已经足够。

如果您已经有外部身份提供商,并且不想维护第二份用户列表,则应使用外部身份提供商。NetBird 支持所有使用 OIDC 的提供商。在您的提供商中注册一个机密 OIDC 客户端,然后在 NetBird 控制面板中使用以下4个值添加它:名称、客户端 ID、客户端密钥和 issuer。NetBird 会提供一个重定向 URL,您需要将其粘贴回提供商中。NetBird 为 Google、Microsoft Entra ID、Okta、Zitadel、Keycloak、Authentik 和 Pocket ID 提供了专用集成,其他提供商则使用通用 OIDC 配置。如果您已经运行 Authentik 作为自托管的单点登录服务,使用此方式即可保留一份帐户列表,而不是两份。

添加提供商后,本地登录仍然可用,所有已配置的提供商都会显示在登录页面上。请保留一个使用强密码的本地管理员帐户。这样,即使 OIDC 配置损坏,您仍然可以登录。

NetBird 还是 Headscale:应该运行哪个控制平面?

两者都移除了同一个依赖项,即客户端原本需要回连的托管控制服务器。但它们的项目形态不同。

Headscale 重新实现了 Tailscale 控制服务器,您仍使用官方 Tailscale 客户端。它没有官方 Web 控制台。您通过 headscale 命令操作配置文件,以管理用户和预认证密钥。社区提供了一些 Web 界面,但它们不属于该项目。对于希望将状态保存在文件中,并通过版本控制管理变更的用户,这种方式更合适。

NetBird 提供完整产品:自有客户端、自有控制面板、内置身份提供商,以及可在浏览器中编辑的访问策略。这会在 VPS 上增加更多组件,但如果需要交给不使用终端的同事管理,NetBird 所需的工作要少得多。

如果您已经在使用 Tailscale 客户端,或希望控制平面尽可能精简,请运行 Headscale。如果需要多人管理对等节点,并且希望直接获得控制台和 SSO,而不自行组装这些功能,请运行 NetBird。

这需要多小的 VPS?

文档规定的最低配置是 1 个 CPU 和 2 GB 内存。NetBird 的说明显示,由于用户管理现在改为本地处理,当前最低内存需求接近 1 GB;旧架构包含完整的 Zitadel 部署,需要 2 GB 到 4 GB。建议购买 2 GB。额外的内存余量可以让升级过程在旧镜像仍保留在磁盘上时拉取新镜像。

在小型服务器上,可以安全地省略以下 3 项。不要启用 NetBird Proxy 服务。该服务用于通过公网主机名发布内部服务,与对等节点建立连接无关。不要启用 CrowdSec。对于暴露在公网的服务器,可以稍后再添加,不必在初始部署时启用。保留 netbird_data 卷中的默认 SQLite 存储。只有在将部署拆分到多台机器,或遇到实际并发需求时,才迁移到 PostgreSQL;文档说明该迁移可以稍后进行。

Relay 是不能省略的组件。两个对等节点的 NAT 如果为每个目标分配不同端口,就永远无法建立直接隧道。因此,Relay 是让它们能够连接的唯一方式。禁用 Relay 节省的内存很少,却会导致连接失败,而且问题通常难以定位。

当一台服务器无法满足需求时,首先应将 Relay 迁移出去。独立运行的 Relay 使用 NB_LISTEN_ADDRESSNB_EXPOSED_ADDRESSNB_AUTH_SECRETNB_ENABLE_STUN。Relay 与主服务器上的共享密钥必须完全一致,否则客户端无法通过身份验证。

故障模式及可见现象

控制面板显示证书警告。 Traefik 未能获取证书。运行 docker compose logs traefik | grep -i acme。通常有两个原因:dig +short netbird.example.com 尚未解析到此 VPS,或者 TCP 80 在 Let's Encrypt 与容器之间的某处被阻断。阻断通常发生在服务商的网络防火墙上,而不是 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 statussudo netbird service start。客户端日志位于 /var/log/netbird/client.log。对于无法定位的问题,netbird debug bundle --anonymize --system-info 会将日志、状态、路由、DNS 设置和防火墙状态收集到一个归档文件中。

备份和升级

整个安装依赖两部分:保存 docker-compose.ymlconfig.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 -d

Compose 会在卷名称前加上项目目录,因此文档中写作 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-urlnetbird 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 存储。