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 VPNVPN网络配置2026/10/20

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% 丢包)

二、前置条件

  1. 已按 B1 篇完成 nebula/nebula-cert 安装与 systemd 托管;
  2. 两节点均已持有同一 CA 签发的证书(CA 与节点证书可用 nebula-cert ca/sign 现签,命令与回显见 D1 篇);
  3. 熟悉 YAML 语法(nebula 的配置是严格 YAML,缩进错误会在 -test 阶段暴露);
  4. 修改配置前建议留一份备份: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_mapoverlay IP → underlay 地址的静态映射支持
static_mapstatic_host_map 的 DNS 解析行为支持
lighthouse信标开关、上报间隔、地址过滤支持
listenUDP 监听地址/端口/缓冲区端口本身需重启
routines收发包线程对数(Linux)否
punchyNAT 打洞与回连支持
cipher加密算法选择支持
preferred_ranges就近路径提示支持
relay中继角色与使用支持
tunTUN 网卡参数与 unsafe_routes支持
logging日志级别与格式支持
statsgraphite/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)。

七、常见问题

  1. 改了配置不生效? 先确认是否有对应热加载(见四、总览表),支持 HUP 的用 kill -HUP $(systemctl show -p MainPID --value nebula);listen.batch、routines、stats.message_metrics 等需重启。
  2. 握手发得出去但一直 Handshake timed out? 按 5.5 节核对两侧 cipher 是否钉死为不同值;再查 UDP 4242 放行与 static_host_map 地址正确性。
  3. 两节点都是同一台机器能测吗? 能,但要把两个实例放隔离环境或错开 TUN 名与端口(实测环境即双实例组网:lighthouse UDP 4242、client UDP 4243、TUN 名 nebula0/nebula1),否则同机路由会让回包绕过隧道造成「假通」。
  4. ICMP 规则带 port 报 WARN? 正常现象(见 5.9 实测三),ICMP 无端口概念,删掉 port 字段即可。
  5. unsafe_routes 流量被防火墙丢了? unsafe_routes 场景下 inbound 规则要显式写 local_cidr(默认 local 范围只含证书 networks),参考 5.9 示例第 3 条规则。

八、参考链接