Nebula
Nebula 是一个用户空间网状虚拟专用网络 (VPN) 守护进程,它使用隧道和加密技术在参与主机之间创建安全的私有网状网络。
安装
基本概念和术语
Nebula 是一种网状 VPN 技术,灵感来源于 tinc。在网状 VPN 中,各个节点之间形成直接隧道。这允许节点之间进行高速直接通信,而无需通过中心节点。节点使用由证书颁发机构签名的证书进行身份验证。
这与 WireGuard 形成对比,WireGuard 是一种点对点 VPN 技术(尽管存在 WireGuard 的网状网络管理器,例如 innernet 和 wesherAUR)。
这也不同于 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.crt
和 ca.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 和 hostBlighthouse.crt
和lighthouse.key
应复制到 lighthouse 节点hostA.crt
和hostA.key
应复制到 hostAhostB.crt
和hostB.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),则通常会发生此问题。正确的解决方案是升级内核。