Nebula

出自 ArchWiki

Nebula 是一个用户空间网状虚拟专用网络 (VPN) 守护进程,它使用隧道和加密技术在参与主机之间创建安全的私有网状网络。

安装

安装 nebula 软件包。

基本概念和术语

Nebula 是一种网状 VPN 技术,灵感来源于 tinc。在网状 VPN 中,各个节点之间形成直接隧道。这允许节点之间进行高速直接通信,而无需通过中心节点。节点使用由证书颁发机构签名的证书进行身份验证。

这与 WireGuard 形成对比,WireGuard 是一种点对点 VPN 技术(尽管存在 WireGuard 的网状网络管理器,例如 innernetwesherAUR)。

这也不同于 OpenVPN,后者使用星型拓扑(也称为中心辐射型)。

证书颁发机构
证书颁发机构通过签名创建主机证书。
灯塔
在 Nebula 网络中,通常至少有一个灯塔节点,作为其他节点的信息中心。灯塔节点帮助其他节点互相发现并形成网络网状结构。
节点
Nebula 网络中的一个节点。
Nebula IP
Nebula 网络中节点的 IP 地址。也称为 VPN IP。
可路由 IP
节点的“正常”或“原生” IP 地址。这可以是公有 IP 地址或私有 IP 地址,具体取决于节点的位置及其网络的配置方式。一个节点可以有多个可路由 IP 地址。

示例:简单的网状 VPN

网络设置

在本示例中,我们有 3 个节点

  • lighthouse
    • Nebula IP: 192.168.100.1
    • 可路由 IP: 12.34.56.78
  • hostA
    • Nebula IP: 192.168.100.101
    • 可路由 IP: 10.0.0.22
  • hostB
    • Nebula IP: 192.168.100.102
    • 可路由 IP: 23.45.67.89

灯塔具有公共静态 IP 地址,并且 hostA 和 hostB 可以访问它。hostA 位于 NAT 之后。hostB 具有公共 IP 地址。

在我们的例子中,我们将为 VPN 网络使用 /24 子网。我们将此网络称为 “My Nebula Network”。

证书和密钥生成

首先,使用 nebula-cert ca -name "My Nebula Network" 生成 CA 证书和私钥。这将创建两个文件

  • ca.crt:CA 证书文件
  • ca.key:CA 私钥

随后,为网络中的节点生成证书和私钥文件

$ nebula-cert sign -name lighthouse -ip 192.168.100.1/24
$ nebula-cert sign -name hostA -ip 192.168.100.101/24
$ nebula-cert sign -name hostB -ip 192.168.100.102/24

请注意,我们没有指定 ca.crtca.key。默认情况下,nebula-cert 会在当前目录中查找这些文件。

完成此步骤后,我们将拥有以下文件

  • lighthouse.crt, lighthouse.key
  • hostA.crt, hostA.key
  • hostB.crt, hostB.key

配置

在灯塔节点上创建此配置文件

/etc/nebula/config.yml
pki:
  ca: /etc/nebula/ca.crt
  cert: /etc/nebula/lighthouse.crt
  key: /etc/nebula/lighthouse.key

lighthouse:
  am_lighthouse: true
  
listen:
  port: 4242

firewall:
  outbound:
    - port: any
      proto: any
      host: any
  inbound:
    - port: any
      proto: any
      host: any

在 hostA 上创建此配置文件

/etc/nebula/config.yml
pki:
  ca: /etc/nebula/ca.crt
  cert: /etc/nebula/hostA.crt
  key: /etc/nebula/hostA.key

static_host_map:
  "192.168.100.1": ["12.34.56.78:4242"]

lighthouse:
  hosts:
    - "192.168.100.1"

punchy:
  punch: true

firewall:
  outbound:
    - port: any
      proto: any
      host: any
  inbound:
    - port: any
      proto: any
      host: any

最后,对 hostB 使用此配置文件

/etc/nebula/config.yml
pki:
  ca: /etc/nebula/ca.crt
  cert: /etc/nebula/hostB.crt
  key: /etc/nebula/hostB.key

static_host_map:
  "192.168.100.1": ["12.34.56.78:4242"]

lighthouse:
  hosts:
    - "192.168.100.1"

firewall:
  outbound:
    - port: any
      proto: any
      host: any
  inbound:
    - port: any
      proto: any
      host: any

分发证书和私钥

由于证书和私钥是由证书颁发机构生成的,因此需要将它们分发到每个节点。SCP 和 SFTP 适用于此目的。

具体来说

  • ca.crt 应复制到所有 3 个节点:lighthouse、hostA 和 hostB
  • lighthouse.crtlighthouse.key 应复制到 lighthouse 节点
  • hostA.crthostA.key 应复制到 hostA
  • hostB.crthostB.key 应复制到 hostB
注意: ca.key 文件不必复制到任何节点。请妥善保管它(不要丢失)并确保安全(不要泄露)。

启动 nebula 守护进程

在每个节点上,启动 nebula.service。可选地,启用 它,以便在启动时启动。

请注意,哪个节点启动 nebula 守护进程并不重要。灯塔节点甚至可以最后启动。每个单独的节点始终尝试连接到已知灯塔节点的列表,因此任何网络中断都可以快速纠正。

测试网状功能

在网状网络中,每个节点都直接连接到其他每个节点。因此,即使灯塔与 hostA 和 hostB 之间的连接速度很慢,只要这两个节点之间有直接链接,hostA 和 hostB 之间的流量也可能很快。

这可以通过在 hostA 上进行简单的 ping 测试来演示

$ ping -c 5 12.34.56.78
PING 12.34.56.78 (12.34.56.78) 56(84) bytes of data.
64 bytes from 12.34.56.78: icmp_seq=1 ttl=56 time=457 ms
64 bytes from 12.34.56.78: icmp_seq=2 ttl=56 time=480 ms
64 bytes from 12.34.56.78: icmp_seq=3 ttl=56 time=262 ms
64 bytes from 12.34.56.78: icmp_seq=4 ttl=56 time=199 ms
64 bytes from 12.34.56.78: icmp_seq=5 ttl=56 time=344 ms

--- 12.34.56.78 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4004ms
rtt min/avg/max/mdev = 199.141/348.555/480.349/108.654 ms
$ ping -c 5 192.168.100.1
PING 192.168.100.1 (192.168.100.1) 56(84) bytes of data.
64 bytes from 192.168.100.1: icmp_seq=1 ttl=64 time=218 ms
64 bytes from 192.168.100.1: icmp_seq=2 ttl=64 time=241 ms
64 bytes from 192.168.100.1: icmp_seq=3 ttl=64 time=264 ms
64 bytes from 192.168.100.1: icmp_seq=4 ttl=64 time=288 ms
64 bytes from 192.168.100.1: icmp_seq=5 ttl=64 time=163 ms

--- 192.168.100.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4004ms
rtt min/avg/max/mdev = 162.776/234.874/288.073/42.902 ms
$ ping -c 5 192.168.100.102
PING 192.168.100.102 (192.168.100.102) 56(84) bytes of data.
64 bytes from 192.168.100.102: icmp_seq=1 ttl=64 time=106 ms
64 bytes from 192.168.100.102: icmp_seq=2 ttl=64 time=2.14 ms
64 bytes from 192.168.100.102: icmp_seq=3 ttl=64 time=4.53 ms
64 bytes from 192.168.100.102: icmp_seq=4 ttl=64 time=4.29 ms
64 bytes from 192.168.100.102: icmp_seq=5 ttl=64 time=5.39 ms

--- 192.168.100.102 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 2.136/24.535/106.344/40.918 ms

请注意,hostA 和灯塔之间的连接速度很慢,但 hostA 和 hostB 之间的连接速度非常快。另请注意,hostA 和 hostB 之间的第一个数据包会稍微延迟,但随后的数据包几乎不花费任何时间。

配置选项

listen.port
这是 nebula 守护进程的监听端口,默认情况下为 4242。在灯塔节点或具有静态 IP 地址的节点上,将其设置为任何其他数字,以便个性化您的设置并减少在该端口上发生意外服务发现和 DDoS 攻击的机会。然后更新 static_host_map 以反映更改。
在具有动态 IP 地址的节点上,建议将其设置为 0,这样 nebula 守护进程将使用随机端口进行通信。
logging.level
默认情况下,nebula 守护进程记录 INFO 级别的消息。因此,会打印握手信息,这可能会生成大量日志消息。将其设置为 warning 以减少记录的消息量。
relay
如果一个节点无法从另一个节点直接访问,则可以使用此选项。中继节点帮助转发此类节点之间的通信。
firewall
此选项可用于仅允许特定流量进出节点。

故障排除

我的灯塔节点握手时间过长

如果您的灯塔节点需要很长时间才能握手,并且在握手完成时一次打印多条握手消息,则可能它不支持 recvmmsg()。为了解决这个问题,请添加此配置选项

/etc/nebula/config.yml
listen:
  batch: 1

如果您的 Linux 内核版本过旧(<2.6.34),则通常会发生此问题。正确的解决方案是升级内核。

参见