Nebula VPN 1.11.2 配置参数详解
Nebula VPN 1.11.2 config.yaml 全参数详解:pki、static_host_map、lighthouse、listen、cipher、punchy、relay、tun/unsafe_routes、firewall、logging、stats、handshakes 逐项说明,含热加载、防火墙 drop/reject、cipher 协商实测回显。
Nebula VPN 1.11.2 配置参数详解
目标:逐项讲清 Nebula VPN 1.11.2 的 config.yaml 配置体系——每个段落管什么、改了什么会生效、哪些能热加载,并以两节点组网(lighthouse 10.99.0.1 + client 10.99.0.2)完成防火墙、热加载、加密算法协商的真实实测。安装与服务托管见《Ubuntu 22.04 安装 Nebula VPN 指南》(https://www.quzuo.net/document/q9aNBLxK6Apa),证书签发命令见《Nebula VPN 1.11.2 常用 CLI 命令详解》。参数语义同时对照官方示例配置 v1.11.2(examples/config.yml)核校,全部实测于 2026-10-20。
一、环境信息
- 操作系统:Ubuntu 22.04.4 LTS(x86_64)
- 软件版本:Nebula VPN 1.11.2(官方二进制,systemd 托管 lighthouse + 第二节点 client)
- 实测拓扑:lighthouse 节点(overlay 10.99.0.1/24,underlay 地址 10.200.0.1,UDP 4242);client 节点(overlay 10.99.0.2/24,underlay 地址 10.200.0.2,UDP 4243),两节点经直连链路互通,client 通过
static_host_map指向 lighthouse - 配置基线:官方示例配置 https://github.com/slackhq/nebula/blob/v1.11.2/examples/config.yml(465 行)
- 实测连通基线:client → lighthouse overlay ping 全通(
rtt min/avg/max = 0.242/0.254/0.266 ms量级,0% 丢包)
二、前置条件
- 已按 B1 篇完成 nebula/nebula-cert 安装与 systemd 托管;
- 两节点均已持有同一 CA 签发的证书(CA 与节点证书可用
nebula-cert ca/sign现签,命令与回显见 D1 篇); - 熟悉 YAML 语法(nebula 的配置是严格 YAML,缩进错误会在
-test阶段暴露); - 修改配置前建议留一份备份:
cp config.yaml config.yaml.bak。
三、参数查看与修改方式
3.1 nebula -test:查看合并后的生效配置
nebula -test -config <文件> 会加载配置、展开默认值,并以单行形式回显整份生效配置后退出(不启动服务)。实测(lighthouse 配置,回显为实测单行节选):
time=2026-10-20T18:21:10.771+08:00 level=INFO msg="firewall:\n conntrack:\n default_timeout: 10m\n tcp_timeout: 12m\n udp_timeout: 3m\n ... lighthouse:\n am_lighthouse: true\n interval: 60\nlisten:\n host: 0.0.0.0\n port: 4242\nlogging:\n format: text\n level: info\npki:\n ca: /etc/nebula/ca.crt\n ... tun:\n dev: nebula0\n disabled: false\n drop_local_broadcast: false\n drop_multicast: false\n mtu: 1300\n tx_queue: 500\n"
这条回显是「参数总览」的最佳来源:没写的参数会显示实际默认值(如 logging.level 未写时回显 info)。配置不可用时以 ERROR 行说明原因并以 exit 1 退出(实测:证书路径写错时回显 level=ERROR msg="Could not load client cert" error="unable to read pki.cert file /etc/nebula/missing.crt: open /etc/nebula/missing.crt: no such file or directory")。
3.2 kill -HUP:热加载
Nebula 支持向主进程发送 SIGHUP 重新加载配置文件,日志会明确记录(实测 journalctl -u nebula):
time=2026-10-20T18:34:40.717+08:00 level=INFO msg="Caught HUP, reloading config"
time=2026-10-20T18:34:40.718+08:00 level=INFO msg="Starting prometheus stats listener" addr=127.0.0.1:9801
防火墙修改热加载后立即生效(实测):
time=2026-10-20T18:30:20.371+08:00 level=INFO msg="New firewall has been installed" firewallHashes=SHA:807243764ac783d089ea5ae93e0ed7fc0a1da4756ca7cb7ae553e128a2b3eb65,FNV:789024431 oldFirewallHashes=SHA:498215dec4e5687a2353f51c10838c113bd1af35ef72b8e8c9f536986ada5417,FNV:2782948616 rulesVersion=1
systemd 托管下热加载命令(实测取 MainPID 再发信号):
kill -HUP $(systemctl show -p MainPID --value nebula)
💡 哪些段落支持 HUP?官方示例配置在注释中逐项标注 "This setting is reloadable"。本文四、参数总览表汇总了各段的实测/官方标注情况。注意:
listen.batch、stats.message_metrics、stats.lighthouse_metrics等少数参数标注不支持热加载,改它们要systemctl restart nebula。
四、参数总览
config.yaml 的顶层段与作用一览(依据官方示例 v1.11.2 排序):
| 顶层段 | 作用 | 是否热加载 |
|---|---|---|
| pki | 证书/私钥路径、吊销列表、失效连接处理 | 证书切换支持 |
| static_host_map | overlay IP → underlay 地址的静态映射 | 支持 |
| static_map | static_host_map 的 DNS 解析行为 | 支持 |
| lighthouse | 信标开关、上报间隔、地址过滤 | 支持 |
| listen | UDP 监听地址/端口/缓冲区 | 端口本身需重启 |
| routines | 收发包线程对数(Linux) | 否 |
| punchy | NAT 打洞与回连 | 支持 |
| cipher | 加密算法选择 | 支持 |
| preferred_ranges | 就近路径提示 | 支持 |
| relay | 中继角色与使用 | 支持 |
| tun | TUN 网卡参数与 unsafe_routes | 支持 |
| logging | 日志级别与格式 | 支持 |
| stats | graphite/prometheus 指标 | 监听可热起;开关类指标不支持 |
| handshakes | 握手重试节奏 | 支持 |
| tunnels | 不活跃隧道清理 | 支持 |
| firewall | 双端过滤规则(default deny) | 支持 |
五、核心参数分类详解
5.1 pki:证书与吊销
pki:
ca: /etc/nebula/ca.crt
cert: /etc/nebula/host.crt
key: /etc/nebula/host.key
# blocklist: # 吊销的证书 SHA 列表(v2 证书为证书指纹)
# - "b5d3cbcff9..."
# disconnect_invalid: true
ca/cert/key支持文件路径,也支持直接内嵌 PEM 文本(key亦可传-----BEGIN NEBULA ED25519 PRIVATE KEY-----形式)。- 实测要点:三个路径任何一个不可读,
nebula -test直接失败(见 3.1 节 ERROR 回显);私钥文件实测权限为 0600(-rw------- 1 root root 127 ... host.key),变更属主/权限到 nebula 运行账户不可读时启动即报错。 blocklist按证书指纹吊销节点;disconnect_invalid让已被吊销/过期证书的隧道即时断开(生产建议开启,默认 true)。
5.2 static_host_map 与 static_map:对端地址直达表
static_host_map:
"10.99.0.1": ["10.200.0.1:4242"]
- 键是对方的 overlay IP,值列表是对方可达的 underlay 地址。写明后无需等 lighthouse 查询即可直接发起握手——实测 client 就是用这条映射在毫秒级完成 stage 1 握手(
Handshake message sent ... udpAddrs=[10.200.0.1:4242])。 - 值里允许写 DNS 名(适合动态公网地址的 lighthouse),配合
static_map控制解析行为:
static_map:
cadence: 30s # DNS 重查间隔
network: ip4 # ip4/ip6/ip
#nameserver: 127.0.0.53:53
- lighthouse 自己的配置不需要 static_host_map(它是被查的一方);多 lighthouse 场景下它们互相也要写对方的映射。
5.3 lighthouse:信标节点参数
lighthouse:
am_lighthouse: true # 只有 lighthouse 节点为 true
interval: 60 # 向 lighthouse 上报地址的周期(秒)
#hosts: # 普通 client 必填:lighthouse 的 overlay IP 列表
# - "10.99.0.1"
#serve_dns: false # 在 overlay 内提供 DNS 解析
#remote_allow_list: # 握手时允许的对端 underlay 网段
# "0.0.0.0/0": true
#local_allow_list: # 本机愿意上报的地址过滤(可按网卡名正则)
# interfaces:
# tun0: false
#advertise_addrs: # 额外上报的可达地址(NAT 端口映射场景)
# - "1.2.3.4:0" # 端口写 0 表示自动使用真实监听端口
实测要点(三条红线都在官方注释里):
am_lighthouse: true时 hosts 必须为空(信标不依赖其他信标);- client 的
hosts写的是 lighthouse 的 overlay IP(证书里的 IP),不是公网地址——公网地址写在 static_host_map 里,二者职责不同; - 实测 lighthouse 配置(
am_lighthouse: true, interval: 60)与 client 配置(hosts: ["10.99.0.1"])均通过nebula -test校验并成功握手。
5.4 listen:UDP 监听
listen:
host: 0.0.0.0 # 只听 IPv4 用 0.0.0.0;默认 "::" 双栈
port: 4242 # 0 表示随机端口(漫游节点推荐)
#batch: 64 # 单次 syscall 最大收包数,不支持热加载
#read_buffer: 10485760 # UDP 读缓冲(内核会翻倍)
#write_buffer: 10485760
#send_recv_error: always # always/never/private
#accept_recv_error: always
- 默认 UDP 4242;实测
ss -lunp | grep 4242回显UNCONN ... 0.0.0.0:4242 ... users:(("nebula",pid=...,fd=...))(注意是 UNCONN 的 UDP 监听)。 - 端口被占时的真实报错与排查:
level=ERROR msg="Failed to open udp listener" queue=0 error="unable to bind to socket: address already in use"(先ss -lunp查占用)。 - 漫游节点(笔记本/办公网)推荐
port: 0随机端口,减少被扫描面;lighthouse 固定 4242 并在防火墙/安全组放行。
5.5 cipher:加密算法与协商
cipher: aes # 可选 chachapoly(默认)或 aes
官方注释写明「该值必须在所有节点一致」,但 v1.11 实测行为更细致,本文在两节点上做了三组实测:
| 组合 | 实测结果 |
|---|---|
| 双方均不配置(默认) | 正常握手,ping 0% 丢包 |
lighthouse 不配置,client 配 cipher: aes | 协商成功:stage 2 完成耗时 754958 纳秒(durationNs=754958),ping 0% 丢包 |
lighthouse 显式 cipher: chachapoly,client cipher: aes | 握手失败:client 反复 Handshake message sent(stage 1)后 Handshake timed out,6.8 秒超时(durationNs=6800172370),ping 100% 丢包 |
失败时 client 侧实测日志:
time=2026-10-20T18:32:53.408+08:00 level=INFO msg="Handshake message sent" vpnAddrs=[10.99.0.1] localIndex=1460673972 remoteIndex=0 udpAddrs=[10.200.0.1:4242] initiatorIndex=1460673972 handshake="map[stage:1 style:ix_psk0]"
time=2026-10-20T18:33:00.208+08:00 level=INFO msg="Handshake timed out" vpnAddrs=[10.99.0.1] localIndex=1460673972 remoteIndex=0 udpAddrs=[10.200.0.1:4242] initiatorIndex=1460673972 durationNs=6800172370 handshake="map[stage:1 style:ix_psk0]"
结论:未显式配置的节点可与任何算法协商;双侧显式钉死不同算法才会互拒。排障时若看到「stage 1 发得出去、stage 2 永远等不到」,先核对两侧 cipher。要切换全网算法:先滚动去掉所有显式 cipher(回默认协商),再统一写入新值。
5.6 punchy:NAT 打洞
punchy:
punch: true # 周期向对端发包维持 NAT 映射(实测默认已启用,-test 回显 "punchy enabled")
respond: true # 对端打洞失败时主动回连(对称 NAT 兜底)
#delay: 1s # 回包延迟,规避乱序 NAT
#respond_delay: 5s # 触发回连前的等待
实测两个节点的配置都写了 punch: true, respond: true,启动日志即出现 punchy enabled;内网直连场景下打洞包不影响 RTT(实测 0.25ms 量级)。
5.7 relay:中继
relay:
am_relay: true # 本机愿意当中继(默认 false)
use_relays: true # 本机允许经中继建立连接
#relays: # 本机可用的中继节点 overlay IP 列表
# - 10.99.0.1
- 中继节点自身无需知道谁会用它:只把
am_relay: true打开,client 在自己的relay.relays里填它的 overlay IP 即可。实测 lighthouse 配置即写了am_relay: true(nebula -test回显relay:\n am_relay: true\n use_relays: true)。 - 中继只在直连打不通时启用,连通后仍会尝试升级为直连;中继节点能看到的只是加密后的转发流量。
5.8 tun 与 unsafe_routes:虚拟网卡与路由扩展
tun:
disabled: false
dev: nebula0 # 网卡名,多实例同机时务必错开
mtu: 1300 # 官方默认值即 1300(互联网链路的安全值)
drop_local_broadcast: false
drop_multicast: false
tx_queue: 500
#routes: # 证书 networks 之外的额外路由
#unsafe_routes: # 把 overlay 流量路由到节点身后的普通网段
# - route: 192.168.87.0/24
# via: 192.168.100.99 # 亦可写成 via 列表做多网关等价均衡
# mtu: 1300
# metric: 100
# install: true # 是否自动安装该路由到系统路由表
实测证据:
- 网卡与地址(client 侧
ip -4 addr show nebula1实测inet 10.99.0.2/24 brd 10.99.0.255 scope global nebula1); - MTU 落到路由(lighthouse 侧
ip route实测10.99.0.0/24 dev nebula0 proto kernel scope link src 10.99.0.1 mtu 1300); - 服务停止后 TUN 网卡随进程消失(实测
systemctl stop后ip link show nebula0回显Device "nebula0" does not exist.)。 unsafe_routes是站点扩展的关键:边缘节点把它身后的普通网段(如 192.168.87.0/24)宣告进 overlay,其他节点访问该网段即会经它转发;防火墙侧要用local_cidr配合放行(见 5.9)。
5.9 firewall:双端过滤规则(default deny)
Nebula 防火墙是纯白名单——官方注释原文 "The firewall is default deny. There is no way to write a deny rule."。规则由协议、端口与多维身份条件构成,逻辑为 port AND proto AND (ca_sha OR ca_name) AND (host OR group OR groups OR cidr) AND (local cidr):
firewall:
outbound_action: drop # 不匹配出站规则时:drop(静默丢)
inbound_action: reject # 或 reject(TCP 回 RST,其他协议回 ICMP 管理性不可达)
conntrack:
tcp_timeout: 12m
udp_timeout: 3m
default_timeout: 10m
outbound:
- port: any
proto: any
host: any
inbound:
- port: 22
proto: tcp
group: ops # 只有 ops 组成员能 SSH
- port: 443
proto: tcp
groups: # groups 列表为 AND 关系(需同时具备)
- laptop
- home
- port: 8080
proto: tcp
group: remote_client
local_cidr: 192.168.100.1/24 # 配合 unsafe_routes 限定目标网段
实测一:规则收窄立即生效(drop)。 把 lighthouse 的 inbound 改为仅 icmp 并 HUP,client 的 TCP 立即被静默丢弃(实测 curl 4 秒超时,exit=28),同时 ICMP 不受影响;HUP 日志出现 New firewall has been installed ... rulesVersion=1。
实测二:reject 与 drop 的体感差异。 inbound_action: reject + 仅放行 icmp 时,同样的 curl 立刻失败且报连接拒绝(实测 * connect to 10.99.0.1 port 9800 failed: Connection refused、after 0 ms、exit=7),而 drop 场景要等满 4 秒超时。reject 的拒绝包会穿过隧道送回发起方,适合内网排障时快速区分「被防火墙拒」与「服务没起」;对外节点用 drop 更收敛。
实测三:ICMP 规则不写端口。 inbound 规则里 proto: icmp 时 port 会被忽略并打 WARN(实测):
time=2026-10-20T18:30:20.371+08:00 level=WARN msg="ignoring port specification for ICMP firewall rule" port=any
5.10 logging:日志
logging:
level: info # panic/error/warning/info/debug/trace
format: text # 或 json
- 生产建议
info;排障时临时调debug(HUP 即生效)后务必改回,debug 会输出逐包信息。 - 接入日志平台用
format: json(systemd/journald 场景 text 足够)。
5.11 stats:可观测性
stats:
type: prometheus
listen: 127.0.0.1:9801
path: /metrics
interval: 10s
#namespace: prometheusns
#subsystem: nebula
#message_metrics: false # 握手等元包计数,不支持热加载
#lighthouse_metrics: false # lighthouse 包计数,不支持热加载
实测全流程:在 lighthouse 配置追加上述段落 → kill -HUP → 日志出现 Starting prometheus stats listener addr=127.0.0.1:9801(见 3.2 节回显)→ ss -ltnp 可见 127.0.0.1:9801 监听 → curl -s http://127.0.0.1:9801/metrics 返回 286 行指标。指标为「裸名 + 点分」风格(未设 namespace/subsystem 时无前缀),代表样例:
certificate_ttl_seconds 3.15359117e+08
firewall_conntrack_count 0
hostmap_main_hosts 1
certificate_ttl_seconds ≈ 3.15e8 秒即 10 年,与实测 CA 签发的 -duration 87600h 完全吻合,可直接用于证书到期告警;hostmap_main_hosts 反映当前 hostmap 规模。graphite 后端则把同名指标按 prefix 推送到 host:port。
5.12 handshakes 与 tunnels:握手节奏与隧道回收
handshakes:
try_interval: 100ms # 首次重试间隔,线性退避
retries: 20 # 默认 20 次退避 ≈ 5.5 秒内放弃(官方注释)
tunnels:
drop_inactive: false # 开启后不活跃隧道到期即回收
inactivity_timeout: 10m # 不活跃判定阈值
实测佐证:5.5 节 cipher 钉死不匹配时,client 在约 6.8 秒后打出 Handshake timed out(durationNs=6800172370),与默认握手窗口(5.5~10 秒量级)一致。大网建议开启 drop_inactive 控制内存(官方注释说明未来将默认开启)。
5.13 routines 与 preferred_ranges
routines: 4 # 收发包线程对数,Linux 专属;>1 启用 TUN 多队列与 SO_REUSEPORT
preferred_ranges: ["10.200.0.0/24"] # 本机所在 underlay 网段提示,加速就近直连
多核高吞吐节点可调大 routines(TUN 与 UDP 各自多队列);preferred_ranges 写本节点所处的内网网段,两节点同内网时能更快选中内网路径(实测环境 underlay 即 10.200.0.0/24 直连)。
5.14 sshd:已标记废弃
官方示例中 sshd 段(SSH 远程调试通道)已标注 THIS FLAG IS DEPRECATED AND WILL BE REMOVED IN A FUTURE RELEASE。新配置不要启用,历史配置建议显式删除;需要调试信息时用日志级别与 prometheus 指标替代。
六、生产配置模板
以下两份模板与本文实测配置同构,可直接改造使用(占位值均为本文实测值,替换证书路径与地址即可)。
lighthouse 节点(/etc/nebula/config.yaml):
pki:
ca: /etc/nebula/ca.crt
cert: /etc/nebula/host.crt
key: /etc/nebula/host.key
lighthouse:
am_lighthouse: true
interval: 60
listen:
host: 0.0.0.0
port: 4242
punchy:
punch: true
respond: true
relay:
am_relay: true
use_relays: true
tun:
dev: nebula0
mtu: 1300
logging:
level: info
format: text
stats:
type: prometheus
listen: 127.0.0.1:9801
path: /metrics
interval: 10s
firewall:
outbound_action: drop
inbound_action: drop
conntrack:
tcp_timeout: 12m
udp_timeout: 3m
default_timeout: 10m
outbound:
- port: any
proto: any
host: any
inbound:
- port: any
proto: any
host: any
普通 client 节点(/etc/nebula/config.yaml):
pki:
ca: /etc/nebula/ca.crt
cert: /etc/nebula/host.crt
key: /etc/nebula/host.key
static_host_map:
"10.99.0.1": ["<lighthouse 可达地址>:4242"]
lighthouse:
am_lighthouse: false
interval: 60
hosts:
- "10.99.0.1"
listen:
host: 0.0.0.0
port: 0
punchy:
punch: true
respond: true
relay:
am_relay: false
use_relays: true
tun:
dev: nebula0
mtu: 1300
logging:
level: info
format: text
firewall:
outbound_action: drop
inbound_action: drop
conntrack:
tcp_timeout: 12m
udp_timeout: 3m
default_timeout: 10m
outbound:
- port: any
proto: any
host: any
inbound:
- port: 22
proto: tcp
group: ops
要点:client 的 static_host_map 值填 lighthouse 的可路由地址(公网 IP 或端口映射地址),hosts 填 lighthouse 的 overlay IP;漫游 client 用 port: 0;按需把 inbound 换成精确白名单(示例给出仅 ops 组可 SSH)。
七、常见问题
- 改了配置不生效? 先确认是否有对应热加载(见四、总览表),支持 HUP 的用
kill -HUP $(systemctl show -p MainPID --value nebula);listen.batch、routines、stats.message_metrics等需重启。 - 握手发得出去但一直 Handshake timed out? 按 5.5 节核对两侧 cipher 是否钉死为不同值;再查 UDP 4242 放行与 static_host_map 地址正确性。
- 两节点都是同一台机器能测吗? 能,但要把两个实例放隔离环境或错开 TUN 名与端口(实测环境即双实例组网:lighthouse UDP 4242、client UDP 4243、TUN 名 nebula0/nebula1),否则同机路由会让回包绕过隧道造成「假通」。
- ICMP 规则带 port 报 WARN? 正常现象(见 5.9 实测三),ICMP 无端口概念,删掉 port 字段即可。
- unsafe_routes 流量被防火墙丢了? unsafe_routes 场景下 inbound 规则要显式写
local_cidr(默认 local 范围只含证书 networks),参考 5.9 示例第 3 条规则。
八、参考链接
- 官方示例配置(v1.11.2,本文参数语义来源):https://github.com/slackhq/nebula/blob/v1.11.2/examples/config.yml
- 官方配置文档索引:https://nebula.defined.net/docs/
- 站内相关:《Nebula VPN 1.11.2 介绍与选型指南》、《Ubuntu 22.04 安装 Nebula VPN 指南》、《Nebula VPN 1.11.2 常用 CLI 命令详解》(Nebula VPN 专栏)