Nebula es una red overlay de malla creada por Slack: cada nodo tiene un certificado firmado por tu propia autoridad de certificación (CA), que fija su IP en la red y los grupos a los que pertenece, y los nodos se conectan directamente entre sí. Un nodo con IP pública, el lighthouse, solo ayuda a que los demás se descubran. En este tutorial crearás una red Nebula entre tres servidores Ubuntu 24.04 (un lighthouse, un servidor web y un servidor de base de datos) y limitarás el tráfico entre ellos con el firewall de Nebula.

Requisitos previos

Para seguir esta guía necesitas:

  • Tres servidores con Ubuntu 24.04 LTS, por ejemplo VPS de CubePath, cada uno con un usuario no root con privilegios sudo. El lighthouse necesita una IP pública fija; en esta guía es your_lighthouse_ip.
  • El puerto UDP 4242 permitido en el firewall de los tres servidores.
  • Un equipo seguro donde guardar la clave de la CA. Puede ser tu portátil o uno de los servidores, pero la clave nunca debe estar en los nodos que no la necesitan.

El plan de direcciones de la red overlay es este:

NodoIP en NebulaGrupos
lighthouse192.168.100.1/24lighthouse
web01192.168.100.2/24web, admin
db01192.168.100.3/24db

Elige un rango que no se use en ninguna de las redes a las que están conectados tus servidores.

Paso 1: Instalar los binarios de Nebula

Nebula se distribuye como dos binarios estáticos: nebula (el servicio) y nebula-cert (la herramienta de certificados). Ejecuta estos comandos en los tres servidores y en el equipo de la CA. Esta guía usa la versión 1.9.5; consulta la página de versiones por si hay una más reciente:

NEBULA_VERSION="v1.9.5"
curl -fsSLO "https://github.com/slackhq/nebula/releases/download/${NEBULA_VERSION}/nebula-linux-amd64.tar.gz"
tar xzf nebula-linux-amd64.tar.gz
sudo install -m 0755 nebula nebula-cert /usr/local/bin/

En servidores ARM usa el archivo nebula-linux-arm64.tar.gz. Comprueba la instalación:

nebula -version
Version: 1.9.5

Crea el directorio de configuración en los tres servidores:

sudo mkdir -p /etc/nebula

Paso 2: Crear la autoridad de certificación

La CA firma los certificados de todos los nodos. Un nodo solo acepta conexiones de otros cuyo certificado esté firmado por la misma CA. En el equipo de la CA, crea un directorio de trabajo y genera la CA con una validez de 10 años (por defecto es de 1 año):

mkdir -p ~/nebula-ca && cd ~/nebula-ca
nebula-cert ca -name "Mi empresa Nebula CA" -duration 87600h

Se generan dos archivos:

  • ca.crt: el certificado público, que se copia a todos los nodos.
  • ca.key: la clave privada. Guárdala a salvo y haz una copia de seguridad cifrada. Quien la tenga puede añadir nodos a tu red.

Revisa el certificado:

nebula-cert print -path ca.crt

Paso 3: Firmar los certificados de los nodos

Cada nodo necesita su propio certificado, que incluye su nombre, su IP en Nebula y sus grupos. Genera los tres desde el directorio de la CA:

nebula-cert sign -name "lighthouse" -ip "192.168.100.1/24" -groups "lighthouse"
nebula-cert sign -name "web01" -ip "192.168.100.2/24" -groups "web,admin"
nebula-cert sign -name "db01" -ip "192.168.100.3/24" -groups "db"

nebula-cert sign usa ca.crt y ca.key del directorio actual y crea un par .crt y .key por nodo. Los certificados de nodo caducan un segundo antes que la CA, salvo que indiques otra duración con -duration. Verifica uno:

nebula-cert verify -ca ca.crt -crt web01.crt && echo "certificado válido"
certificado válido

Copia a cada servidor su certificado, su clave y el certificado de la CA. Sustituye your_user y las IP por las tuyas:

scp ca.crt lighthouse.crt lighthouse.key your_user@your_lighthouse_ip:/tmp/
scp ca.crt web01.crt web01.key your_user@your_web01_ip:/tmp/
scp ca.crt db01.crt db01.key your_user@your_db01_ip:/tmp/

En cada servidor, mueve los archivos a /etc/nebula y protege la clave. Por ejemplo, en web01:

sudo mv /tmp/ca.crt /tmp/web01.crt /tmp/web01.key /etc/nebula/
sudo chown root:root /etc/nebula/*
sudo chmod 600 /etc/nebula/web01.key

Paso 4: Configurar el lighthouse

En el servidor lighthouse, crea el archivo de configuración:

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

static_host_map: {}

lighthouse:
  am_lighthouse: true
  interval: 60

listen:
  host: "[::]"
  port: 4242

punchy:
  punch: true

tun:
  dev: nebula1
  mtu: 1300

logging:
  level: info
  format: text

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

El lighthouse solo acepta ICMP desde la red overlay: su trabajo es informar a los nodos de dónde está cada uno, no ofrecer servicios. host: "[::]" escucha en IPv4 e IPv6. Comprueba que la configuración es válida antes de arrancar:

sudo nebula -test -config /etc/nebula/config.yml && echo "configuración correcta"

Paso 5: Configurar los nodos

En web01 y db01, la configuración indica cuál es el lighthouse y en qué IP pública está. static_host_map asocia la IP de Nebula del lighthouse con su dirección real, y lighthouse.hosts le dice al nodo que lo use para descubrir a los demás. Crea el archivo en web01:

sudo nano /etc/nebula/config.yml
pki:
  ca: /etc/nebula/ca.crt
  cert: /etc/nebula/web01.crt
  key: /etc/nebula/web01.key

static_host_map:
  "192.168.100.1": ["your_lighthouse_ip:4242"]

lighthouse:
  am_lighthouse: false
  interval: 60
  hosts:
    - "192.168.100.1"

listen:
  host: "[::]"
  port: 4242

punchy:
  punch: true

tun:
  dev: nebula1
  mtu: 1300

logging:
  level: info
  format: text

firewall:
  outbound:
    - port: any
      proto: any
      host: any
  inbound:
    - port: any
      proto: icmp
      host: any
    - port: 22
      proto: tcp
      group: admin
    - port: 443
      proto: tcp
      host: any

En db01, usa el mismo archivo cambiando las rutas de pki a db01.crt y db01.key, y sustituye la sección inbound por esta, que solo permite PostgreSQL desde los nodos del grupo web y SSH desde el grupo admin:

  inbound:
    - port: any
      proto: icmp
      host: any
    - port: 5432
      proto: tcp
      group: web
    - port: 22
      proto: tcp
      group: admin

El firewall de Nebula se aplica según los grupos del certificado del nodo remoto, no según su IP. Como los grupos están firmados por la CA, un nodo no puede atribuirse un grupo que no tiene. Todo lo que no coincide con una regla inbound se descarta. Valida la configuración en ambos nodos:

sudo nebula -test -config /etc/nebula/config.yml && echo "configuración correcta"

Paso 6: Abrir el puerto en el firewall

Nebula usa UDP 4242 para el tráfico cifrado entre nodos. Permítelo en los tres servidores:

sudo ufw allow 4242/udp
sudo ufw status
To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
4242/udp                   ALLOW       Anywhere

Paso 7: Ejecutar Nebula como servicio de systemd

Crea la unidad de systemd en los tres servidores:

sudo nano /etc/systemd/system/nebula.service
[Unit]
Description=Nebula overlay network
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/local/bin/nebula -config /etc/nebula/config.yml
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

ExecReload envía SIGHUP, que hace que Nebula recargue la configuración (por ejemplo, reglas de firewall nuevas) sin cortar los túneles. Arranca primero el lighthouse y después los nodos:

sudo systemctl daemon-reload
sudo systemctl enable --now nebula
sudo systemctl status nebula
● nebula.service - Nebula overlay network
     Loaded: loaded (/etc/systemd/system/nebula.service; enabled; preset: enabled)
     Active: active (running) since ...

Comprueba que existe la interfaz nebula1 con la IP del certificado:

ip -br addr show nebula1
nebula1          UNKNOWN        192.168.100.2/24

Paso 8: Verificar la conectividad y el firewall

Desde web01, haz ping al lighthouse y a db01. El primer paquete puede tardar mientras se establece el túnel:

ping -c 3 192.168.100.1
ping -c 3 192.168.100.3
64 bytes from 192.168.100.3: icmp_seq=1 ttl=64 time=3.41 ms

Para comprobar el firewall, intenta conectar por SSH a web01 desde db01. Como db01 no pertenece al grupo admin, Nebula descarta la conexión y el comando acaba en tiempo de espera:

nc -zv -w 5 192.168.100.2 22
nc: connect to 192.168.100.2 port 22 (tcp) timed out: Operation now in progress

En cambio, el mismo comando desde web01 hacia db01 funciona, porque web01 sí está en el grupo admin.

Solución de problemas

Los nodos no conectan con el lighthouse. Revisa los logs del servicio y comprueba que el puerto UDP 4242 está permitido en el lighthouse y en cualquier firewall externo:

sudo journalctl -u nebula -n 50

Un mensaje repetido de Handshake message sent sin respuesta indica que los paquetes UDP no llegan.

Error de certificado al arrancar. Comprueba que el certificado del nodo está firmado por la CA copiada al nodo y que no ha caducado:

sudo nebula-cert verify -ca /etc/nebula/ca.crt -crt /etc/nebula/web01.crt
sudo nebula-cert print -path /etc/nebula/web01.crt

Los ping funcionan pero las transferencias grandes se cortan. Suele ser un problema de MTU en la ruta entre servidores. Baja tun.mtu a 1200 en todos los nodos y reinicia el servicio con sudo systemctl restart nebula.

Conclusión

Tienes una red overlay Nebula entre tres servidores Ubuntu 24.04, con una CA propia, un lighthouse para el descubrimiento y un firewall que filtra por grupos firmados en los certificados. Como siguientes pasos, puedes añadir un segundo lighthouse en otra ubicación para tener redundancia, planificar la renovación de los certificados antes de que caduque la CA, o configurar los servicios internos (PostgreSQL, SSH) para que escuchen solo en la IP de Nebula.