NetBird 自托管私有组网方案

admin
2
2026-07-26

NetBird 自托管私有组网方案

1. 拓扑

域名规划

  • netbird.example.com:NetBird 管理与登录入口
  • *.netbird.example.com:可选,后续扩展用

访问方式

  • 浏览器访问 https://netbird.example.com
  • 客户端连接到同一个域名
  • 认证走本地账号
  • MFA 走 Microsoft Authenticator 的 TOTP 码

2. 前置条件

服务器

  • Debian 12
  • 已安装 Docker / Docker Compose
  • 已有 Nginx
  • 已有 TLS 证书或可签发证书

端口

对公网开放:

  • 80/tcp
  • 443/tcp
  • 3478/udp

其中 3478/udp 是 STUN,必须直通。12


3. 目录建议

/opt/netbird/
├── docker-compose.yml
├── config.yaml
├── dashboard.env
└── data/

4. docker-compose.yml 示例

说明:这是按官方 combined 架构整理的示例。
如果你用 getting-started.sh 生成了基础文件,可以只替换域名和端口映射,不必完全手工重写。31

services:
  dashboard:
    image: netbirdio/dashboard:latest
    container_name: netbird-dashboard
    restart: unless-stopped
    env_file:
      - ./dashboard.env
    ports:
      - "127.0.0.1:8080:80"
    networks:
      - netbird

  netbird-server:
    image: netbirdio/netbird-server:latest
    container_name: netbird-server
    restart: unless-stopped
    volumes:
      - ./config.yaml:/etc/netbird/config.yaml:ro
      - netbird_data:/var/lib/netbird
    ports:
      - "127.0.0.1:8081:80"
      - "3478:3478/udp"
    networks:
      - netbird

networks:
  netbird:
    driver: bridge

volumes:
  netbird_data:

5. config.yaml 示例

这个配置走的是:

  • 本地用户
  • 密码登录
  • 本地 MFA/TOTP
  • 初始管理员自动创建
  • 单机 combined server
  • 外部反代域名为 https://netbird.example.com
server:
  listenAddress: ":80"
  exposedAddress: "https://netbird.example.com"
  stunPorts:
    - 3478
  metricsPort: 9090
  healthcheckAddress: ":9000"
  logLevel: "info"
  logFile: "console"
  authSecret: "REPLACE_WITH_RANDOM_BASE64_32_BYTES"
  dataDir: "/var/lib/netbird"

  auth:
    issuer: "https://netbird.example.com/oauth2"
    localAuthDisabled: false
    signKeyRefreshEnabled: true
    dashboardRedirectURIs:
      - "https://netbird.example.com/nb-auth"
      - "https://netbird.example.com/nb-silent-auth"
    cliRedirectURIs:
      - "http://localhost:53000/"
    grantTypes:
      - authorization_code
      - refresh_token
      - device_code
    owner:
      email: "admin@example.com"
      password: "ChangeMe-Please123!"
    mfaSessionMaxLifetime: "24h"
    mfaSessionIdleTimeout: "1h"

  store:
    engine: "sqlite"
    encryptionKey: "REPLACE_WITH_RANDOM_BASE64_32_BYTES"

  activityStore:
    engine: "sqlite"

  authStore:
    engine: "sqlite3"

生成密钥

openssl rand -base64 32

建议分别生成:

  • authSecret
  • encryptionKey

6. dashboard.env 示例

LETSENCRYPT_DOMAIN=none
NETBIRD_MGMT_API_ENDPOINT=https://netbird.example.com
NETBIRD_MGMT_GRPC_API_ENDPOINT=https://netbird.example.com
AUTH_AUDIENCE=netbird-dashboard
AUTH_CLIENT_ID=netbird-dashboard

说明:使用外部 Nginx 时,LETSENCRYPT_DOMAIN=none4


7. Nginx 新增部分

只贴新增部分,不重复你现有配置。
下面这段放进你现有 http {} 里的合适位置。
如果你还没有 map,先加 map,再加 server 块。

7.1 http {} 里新增 map

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

7.2 新增 server 块

server {
    listen 443 ssl http2;
    server_name netbird.example.com;

    access_log  /usr/local/nginx/logs/nginx.netbird.log;
    error_log   /usr/local/nginx/logs/error.netbird.log;

    ssl_certificate     /etc/nginx/ssl/example.com.pem;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;

    location ^~ /signalexchange.SignalExchange/ {
        grpc_pass grpc://127.0.0.1:8081;
        grpc_set_header Host $host;
        grpc_set_header X-Real-IP $remote_addr;
        grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        grpc_set_header X-Forwarded-Proto https;
        grpc_read_timeout 3600s;
        grpc_send_timeout 3600s;
    }

    location ^~ /management.ManagementService/ {
        grpc_pass grpc://127.0.0.1:8081;
        grpc_set_header Host $host;
        grpc_set_header X-Real-IP $remote_addr;
        grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        grpc_set_header X-Forwarded-Proto https;
        grpc_read_timeout 3600s;
        grpc_send_timeout 3600s;
    }

    location ^~ /management.ProxyService/ {
        grpc_pass grpc://127.0.0.1:8081;
        grpc_set_header Host $host;
        grpc_set_header X-Real-IP $remote_addr;
        grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        grpc_set_header X-Forwarded-Proto https;
        grpc_read_timeout 3600s;
        grpc_send_timeout 3600s;
    }

    location ^~ /ws-proxy/ {
        proxy_pass http://127.0.0.1:8081;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }

    location ^~ /relay {
        proxy_pass http://127.0.0.1:8081;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }

    location ^~ /api/ {
        proxy_pass http://127.0.0.1:8081;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }

    location ^~ /oauth2/ {
        proxy_pass http://127.0.0.1:8081;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }
}

server {
    listen 80;
    server_name netbird.example.com;
    return 301 https://$host$request_uri;
}

7.3 说明

  • 80/443 只给 Nginx
  • 8080 只给 dashboard
  • 8081 只给 netbird-server
  • 3478/udp 直接对外开放,不走 Nginx12

8. 部署步骤

8.1 启动

cd /opt/netbird
docker compose up -d

8.2 检查容器

docker compose ps
docker compose logs -f netbird-server
docker compose logs -f dashboard

8.3 检查 OIDC

curl -k https://netbird.example.com/oauth2/.well-known/openid-configuration

8.4 首次初始化

浏览器访问:

https://netbird.example.com

第一次会进入 /setup,创建初始管理员:

  • Email:admin@example.com
  • Password:ChangeMe-Please123!
  • Name:Example Admin

官方说明,新部署首次运行时没有用户,需要先完成这一步。3


9. 开启本地 MFA

登录后台后:

  • Settings
  • Authentication
  • 打开 Local MFA

然后用 Microsoft Authenticator 扫码绑定。
官方文档说明本地用户 MFA 是基于 TOTP,任何兼容 TOTP 的认证器都能用。56


10. 客户端接入方法

Windows

  • 安装 NetBird 客户端
  • 连接 netbird.example.com
  • 用本地账号登录
  • 绑定 MFA

Android / 小米手机 / 小米平板

  • 安装 Android 客户端
  • 同上

iOS / 苹果手机

  • 官方安装页仍保留 iOS 入口。7
  • 如果你的 App Store 暂时搜不到,先把服务端部署完成,再回头核对商店地区、搜索词和账号区域

Linux / Debian / Kali

  • 安装 Linux 客户端
  • 推荐用 setup key 做批量注册
  • 服务器类设备建议用服务方式常驻

NAS

  • 如果 QNAP 能跑容器,就优先容器化
  • 不行就用旁路 Linux 节点做 NAS 入口

11. 组网建议

推荐分组

  • admins
  • servers
  • mobile
  • storage
  • lab

推荐策略

  • 默认拒绝
  • 按组开放
  • 管理员只给必要权限
  • 移动端只访问少量服务
  • lab 与生产隔离

12. 关键注意事项

  1. 不要把 3478/udp 交给 Nginx
  2. Nginx 必须支持 HTTP/2
  3. gRPC 路径必须单独代理
  4. 本地账号 + MFA 足够起步
  5. 微软认证器可用,但它是 TOTP,不是专门的 Microsoft SSO
  6. iOS 找不到不影响服务端部署

13. 最终版一句话

这套方案的核心是:

Debian 云服务器上的 NetBird combined server + 现有 Nginx 外部反代 + 本地用户密码 + Microsoft Authenticator TOTP MFA + 3478/UDP 直通


参考链接:

Footnotes

  1. NetBird Docs — External Reverse Proxy Setup for Self-Hosted NetBird 2 3

  2. NetBird Docs — Ports & Firewalls 2

  3. NetBird Docs — Self-Hosting Quickstart Guide (5 min) 2

  4. NetBird Docs — Self-Hosted Deployment Configuration Files Reference

  5. NetBird Docs — Local User Management

  6. NetBird Docs — Enable MFA for local users

  7. NetBird Docs — Install NetBird

动物装饰