Nebula Overlay Network Installation
Nebula is a scalable overlay networking tool that creates secure mesh VPN connections between nodes using certificates and a lighthouse-based discovery system. Developed by Slack, Nebula uses its own lightweight tunneling protocol with built-in firewall rules, making it ideal for connecting VPS instances, bare-metal servers, and cloud resources across multiple data centers with group-based access control.
Prerequisites
- Ubuntu 20.04+, Debian 11+, CentOS 8+, or Rocky Linux 8+
- At least one node with a public IP address (lighthouse)
- Root or sudo access on all nodes
- UDP port 4242 open on the lighthouse node
Downloading Nebula
# Download the latest release (check https://github.com/slackhq/nebula/releases)
NEBULA_VERSION="v1.9.0"
curl -LO "https://github.com/slackhq/nebula/releases/download/${NEBULA_VERSION}/nebula-linux-amd64.tar.gz"
# Extract binaries
tar -xzf nebula-linux-amd64.tar.gz
# Install system-wide
sudo mv nebula nebula-cert /usr/local/bin/
sudo chmod +x /usr/local/bin/nebula /usr/local/bin/nebula-cert
# Verify installation
nebula --version
nebula-cert --version
Certificate Authority Setup
The CA is used to sign all node certificates. Keep the CA key secure — it should not be on any network node.
# Create a directory for CA files (do this on a secure admin machine)
mkdir -p ~/nebula-ca && cd ~/nebula-ca
# Generate the CA certificate and key
nebula-cert ca \
--name "MyOrg Nebula CA" \
--duration 8760h # 1 year validity
# This creates:
# - ca.crt (distribute to all nodes)
# - ca.key (keep secret, never distribute)
ls -la
# ca.crt ca.key
Generating Node Certificates
Generate a certificate for each node using the CA. Assign each node a unique IP within the Nebula subnet (e.g., 10.10.0.0/16).
# Generate certificate for the lighthouse node
nebula-cert sign \
--name "lighthouse1" \
--ip "10.10.0.1/16" \
--ca-crt ca.crt \
--ca-key ca.key
# Generate certificate for an application server
nebula-cert sign \
--name "app-server1" \
--ip "10.10.0.10/16" \
--groups "servers,app" \
--ca-crt ca.crt \
--ca-key ca.key
# Generate certificate for a developer workstation
nebula-cert sign \
--name "dev-laptop" \
--ip "10.10.0.100/16" \
--groups "developers" \
--ca-crt ca.crt \
--ca-key ca.key
# View certificate details
nebula-cert print --path app-server1.crt
Copy certificates to each node:
# Copy files to lighthouse node
scp ca.crt lighthouse1.crt lighthouse1.key user@lighthouse-public-ip:/etc/nebula/
# Copy files to app server
scp ca.crt app-server1.crt app-server1.key user@app-server:/etc/nebula/
Lighthouse Configuration
The lighthouse is a publicly reachable node that helps peers find each other. Create /etc/nebula/config.yml on the lighthouse:
sudo mkdir -p /etc/nebula
sudo tee /etc/nebula/config.yml <<'EOF'
pki:
ca: /etc/nebula/ca.crt
cert: /etc/nebula/lighthouse1.crt
key: /etc/nebula/lighthouse1.key
static_host_map: {} # Lighthouse has no upstream lighthouses
lighthouse:
am_lighthouse: true
interval: 60
listen:
host: 0.0.0.0
port: 4242
punchy:
punch: true
respond: true
tun:
disabled: false
dev: nebula1
drop_local_broadcast: false
drop_multicast: false
logging:
level: info
format: text
firewall:
outbound:
- port: any
proto: any
host: any
inbound:
- port: any
proto: icmp
host: any
EOF
Node Configuration
Create /etc/nebula/config.yml on all non-lighthouse nodes:
sudo mkdir -p /etc/nebula
sudo tee /etc/nebula/config.yml <<'EOF'
pki:
ca: /etc/nebula/ca.crt
cert: /etc/nebula/app-server1.crt
key: /etc/nebula/app-server1.key
# Point to the lighthouse's public IP and Nebula port
static_host_map:
"10.10.0.1": ["203.0.113.10:4242"]
lighthouse:
am_lighthouse: false
interval: 60
hosts:
- "10.10.0.1"
listen:
host: 0.0.0.0
port: 4242
punchy:
punch: true
respond: true
tun:
disabled: false
dev: nebula1
logging:
level: info
format: text
firewall:
outbound:
- port: any
proto: any
host: any
inbound:
- port: any
proto: icmp
host: any
- port: 22
proto: tcp
groups:
- developers
- servers
- port: 443
proto: tcp
groups:
- servers
EOF
Firewall Rules and Group Access Control
Nebula's firewall uses group membership from certificates to control access. Groups are embedded in the certificate at signing time.
# Example: Allow only "developers" group to reach SSH on "servers" group
firewall:
inbound:
- port: 22
proto: tcp
groups:
- developers
# Allow servers to communicate with each other on any port
- port: any
proto: any
groups:
- servers
# Allow monitoring tools to reach all nodes
- port: 9100
proto: tcp
groups:
- monitoring
# Allow ICMP from anywhere in the overlay
- port: any
proto: icmp
host: any
# Validate your config file before deploying
nebula --config /etc/nebula/config.yml --test
Running Nebula as a Service
# Create a systemd service unit
sudo tee /etc/systemd/system/nebula.service <<'EOF'
[Unit]
Description=Nebula Overlay Network
Wants=basic.target network-online.target
After=basic.target network.target network-online.target
Before=sshd.service
[Service]
SyslogIdentifier=nebula
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/usr/local/bin/nebula --config /etc/nebula/config.yml
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Enable and start the service
sudo systemctl daemon-reload
sudo systemctl enable --now nebula
# Check status
sudo systemctl status nebula
sudo journalctl -u nebula -f
Open the required firewall port:
# Ubuntu/Debian (UFW)
sudo ufw allow 4242/udp
# CentOS/Rocky (firewalld)
sudo firewall-cmd --add-port=4242/udp --permanent
sudo firewall-cmd --reload
Troubleshooting
Nodes cannot connect to lighthouse:
# Verify UDP 4242 is open on the lighthouse
sudo ss -ulnp | grep 4242
# Test UDP reachability from a node
nc -zu lighthouse-public-ip 4242
# Check Nebula logs for handshake errors
sudo journalctl -u nebula -n 50
Certificate validation errors:
# Verify certificate details
nebula-cert print --path /etc/nebula/app-server1.crt
# Check CA matches across nodes
nebula-cert verify --ca /etc/nebula/ca.crt --crt /etc/nebula/app-server1.crt
# Confirm system time is synchronized (certificates are time-sensitive)
timedatectl status
Nodes appear in lighthouse but cannot ping each other:
# Check firewall rules allow ICMP
# In config.yml, ensure this inbound rule exists:
# - port: any
# proto: icmp
# host: any
# Ping across the overlay network
ping 10.10.0.10
# Show current Nebula interface
ip addr show nebula1
ip route show dev nebula1
Conclusion
Nebula provides a highly scalable overlay network with a strong security model based on certificate authorities and group-based firewall policies, making it well-suited for multi-site infrastructure where fine-grained access control is required. By embedding group membership directly in certificates and enforcing rules at the kernel level, Nebula eliminates the need for separate firewall infrastructure while enabling zero-trust networking across cloud providers and bare-metal servers.


