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/tcp443/tcp3478/udp
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
建议分别生成:
authSecretencryptionKey
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=none。4
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 说明
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
登录后台后:
SettingsAuthentication- 打开
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. 组网建议
推荐分组
adminsserversmobilestoragelab
推荐策略
- 默认拒绝
- 按组开放
- 管理员只给必要权限
- 移动端只访问少量服务
lab与生产隔离
12. 关键注意事项
- 不要把
3478/udp交给 Nginx - Nginx 必须支持 HTTP/2
- gRPC 路径必须单独代理
- 本地账号 + MFA 足够起步
- 微软认证器可用,但它是 TOTP,不是专门的 Microsoft SSO
- iOS 找不到不影响服务端部署
13. 最终版一句话
这套方案的核心是:
Debian 云服务器上的 NetBird combined server + 现有 Nginx 外部反代 + 本地用户密码 + Microsoft Authenticator TOTP MFA + 3478/UDP 直通
参考链接:
- https://docs.netbird.io/selfhosted/identity-providers/local
- https://docs.netbird.io/selfhosted/identity-providers/enable-local-mfa
- https://docs.netbird.io/selfhosted/selfhosted-quickstart
- https://docs.netbird.io/selfhosted/external-reverse-proxy
- https://docs.netbird.io/selfhosted/maintenance/configuration-files
- https://docs.netbird.io/get-started/install
- https://docs.netbird.io/about-netbird/ports-and-firewalls
Footnotes
-
NetBird Docs — External Reverse Proxy Setup for Self-Hosted NetBird ↩ ↩2 ↩3
-
NetBird Docs — Ports & Firewalls ↩ ↩2
-
NetBird Docs — Self-Hosting Quickstart Guide (5 min) ↩ ↩2
-
NetBird Docs — Self-Hosted Deployment Configuration Files Reference ↩
-
NetBird Docs — Local User Management ↩
-
NetBird Docs — Enable MFA for local users ↩
-
NetBird Docs — Install NetBird ↩