Nebula
Updated: February 8, 2026
Nebula is a scalable overlay networking tool with a focus on performance, simplicity, and security. It allows you to connect devices across different networks into a single secure mesh network, similar to Tailscale but self-hosted and completely under your control. Nebula uses certificate authority-based authentication and encrypted tunnels to create a private network that can traverse NAT and firewalls.
Table of Contents
- Installation
- NixOS Configuration
- Certificate Authority Setup
- Lighthouse Setup
- Client Configuration
- Relay Setup
- Firewall Configuration
- Commands
- Troubleshooting
Installation
Manual Install
Nebula can be installed on various platforms:
# Linux
wget https://github.com/slackhq/nebula/releases/download/v1.7.2/nebula-linux-amd64.tar.gz
tar -xzf nebula-linux-amd64.tar.gz
sudo cp nebula /usr/local/bin/
# macOS
brew install nebula
# Or download binary
curl -OL https://github.com/slackhq/nebula/releases/download/v1.7.2/nebula-darwin-amd64.tar.gz
tar -xzf nebula-darwin-amd64.tar.gz
sudo cp nebula /usr/local/bin/
Nix Install
nix-env -iA nixpkgs.nebula
NixOS Configuration
Enable Nebula as a system service in your NixOS configuration:
{ config, pkgs, ... }:
{
environment.systemPackages = with pkgs; [
nebula
];
# Enable Nebula service for a specific network (e.g., "mynet")
services.nebula.networks.mynet = {
enable = true;
isLighthouse = false;
isRelay = false;
ca = ./ca.crt;
cert = ./host.crt;
key = ./host.key;
# Static host map for initial connection
staticHostMap = {
"10.100.0.1" = [ "lighthouse.example.com:4242" ];
};
# Lighthouse addresses
lighthouse = [ "10.100.0.1" ];
listen = {
host = "0.0.0.0";
port = 4242;
};
tun = {
disabled = false;
device = "nebula1";
};
firewall = {
outbound = [
{ port = "any"; proto = "any"; host = "any"; }
];
inbound = [
{ port = "any"; proto = "any"; host = "any"; }
];
};
};
# Optional: Enable IP forwarding for routing
boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
}
Rebuild and switch:
sudo nixos-rebuild switch
Certificate Authority Setup
First, create a Certificate Authority (CA) for your Nebula network:
# Generate CA certificate and key valid 10 years
nebula-cert ca -name "MyNebulaCA" -duration 87600h
# This creates:
# - ca.crt (public certificate)
# - ca.key (private key - keep this secure!)
The ca.crt will be distributed to all hosts in the network. The ca.key should only exist on the machine where you sign certificates.
Lighthouse Setup
A lighthouse helps hosts discover each other. You typically need at least one lighthouse in your network.
Generate Lighthouse Certificate
# Generate certificate for lighthouse
nebula-cert sign -name "lighthouse1" -ip "192.100.100.1/24" -groups "desktop,lighthouse" ca.crt ca.key
This creates lighthouse1.crt and lighthouse1.key.
Lighthouse NixOS Configuration
services.nebula.networks.mynet = {
enable = true;
isLighthouse = true;
ca = ./ca.crt;
cert = ./lighthouse1.crt;
key = ./lighthouse1.key;
listen = {
host = "0.0.0.0";
port = 4242;
};
# Lighthouses don't need staticHostMap to other lighthouses
staticHostMap = {};
tun = {
disabled = false;
device = "nebula1";
};
firewall = {
outbound = [
{ port = "any"; proto = "any"; host = "any"; }
];
inbound = [
{ port = "any"; proto = "any"; host = "any"; }
];
};
};
Client Configuration
Generate Client Certificate
# Generate certificate for a host named "server1" with IP 10.100.0.2
nebula-cert sign -name "server1" -ip "192.100.100.2/24" -groups "server" ca.crt ca.key
# For a client/laptop with a group
nebula-cert sign -name "laptop1" -ip "10.100.0.10/24" -groups "admin,dev" ca.crt ca.key
Client NixOS Configuration
services.nebula.networks.mynet = {
enable = true;
isLighthouse = false;
ca = ./ca.crt;
cert = ./server1.crt;
key = ./server1.key;
# Point to lighthouse for discovery
staticHostMap = {
"10.100.0.1" = [ "lighthouse.example.com:4242" ];
};
lighthouse = [ "10.100.0.1" ];
listen = {
host = "0.0.0.0";
port = 4242;
};
tun = {
disabled = false;
device = "nebula1";
};
firewall = {
outbound = [
{ port = "any"; proto = "any"; host = "any"; }
];
inbound = [
{ port = "any"; proto = "any"; host = "any"; }
];
};
};
Relay Setup
Relays are useful for devices behind symmetric NAT that cannot make direct connections.
Generate Relay Certificate
nebula-cert sign -name "relay1" -ip "10.100.0.100/24" ca.crt ca.key
Relay NixOS Configuration
services.nebula.networks.mynet = {
enable = true;
isLighthouse = false;
isRelay = true;
ca = ./ca.crt;
cert = ./relay1.crt;
key = ./relay1.key;
staticHostMap = {
"10.100.0.1" = [ "lighthouse.example.com:4242" ];
};
lighthouse = [ "10.100.0.1" ];
listen = {
host = "0.0.0.0";
port = 4242;
};
tun = {
disabled = false;
device = "nebula1";
};
};
Client Using Relay
services.nebula.networks.mynet = {
enable = true;
ca = ./ca.crt;
cert = ./client.crt;
key = ./client.key;
staticHostMap = {
"10.100.0.1" = [ "lighthouse.example.com:4242" ];
};
lighthouse = [ "10.100.0.1" ];
relays = [ "10.100.0.100" ];
# Force relay usage if needed
useRelay = true;
};
Firewall Configuration
System Firewall
Ensure Nebula’s UDP port is open:
networking.firewall.allowedUDPPorts = [ 4242 ];
Or for specific interface:
networking.firewall.extraCommands = ''
iptables -A INPUT -i eth0 -p udp --dport 4242 -j ACCEPT
'';
Nebula Internal Firewall
Control traffic between hosts:
services.nebula.networks.mynet = {
# ... other config ...
firewall = {
outbound = [
# Allow all outbound traffic
{ port = "any"; proto = "any"; host = "any"; }
];
inbound = [
# Allow only specific ports
{ port = "22"; proto = "tcp"; host = "any"; }
{ port = "80"; proto = "tcp"; host = "10.100.0.2"; }
{ port = "443"; proto = "tcp"; host = "10.100.0.2"; }
# Allow ICMP (ping)
{ port = "any"; proto = "icmp"; host = "any"; }
];
};
};
Commands
Certificate Management
# Create CA
nebula-cert ca -name "MyNetwork"
# Sign host certificate
nebula-cert sign -name "hostname" -ip "10.100.0.X/24" ca.crt ca.key
# Sign with groups
nebula-cert sign -name "hostname" -ip "10.100.0.X/24" -groups "admin,dev" ca.crt ca.key
# Sign with additional IPs
nebula-cert sign -name "hostname" -ip "10.100.0.10/24" -subnets "192.168.1.0/24" ca.crt ca.key
# Verify certificate
nebula-cert verify ca.crt host.crt
# Show certificate info
nebula-cert print host.crt
# Revoke certificate (create new CA with CRL)
nebula-cert sign -name "hostname" -ip "10.100.0.X/24" ca.crt ca.key -revoke
Service Management
# NixOS service
systemctl status nebula@mynet
systemctl restart nebula@mynet
systemctl stop nebula@mynet
journalctl -u nebula@mynet -f
Network Diagnostics
# Check nebula interface
ip addr show nebula1
# Check routes
ip route show
# Ping another host in mesh
ping 10.100.0.2
# Check nebula status
nebula-test status
# Check connection to lighthouse
nebula-test ping lighthouse-ip
Troubleshooting
Common Issues
Hosts can’t connect:
# Check if nebula service is running
systemctl status nebula@mynet
# Check firewall rules
iptables -L -n -v
# Verify certificate is valid
nebula-cert verify ca.crt host.crt
# Check lighthouse is accessible
ping lighthouse.example.com
telnet lighthouse.example.com 4242
NAT traversal issues:
- Enable relays for problematic hosts
- Check UDP port forwarding on routers
- Verify lighthouse is accessible from outside
Performance issues:
# Check nebula connections
ip link show nebula1
# Monitor nebula traffic
tcpdump -i nebula1
# Check system load
htop
Certificate expiration:
# Check certificate expiration
nebula-cert print host.crt | grep -i not
# Renew certificates before expiration
nebula-cert sign -name "hostname" -ip "10.100.0.X/24" ca.crt ca.key
Debug Mode
Enable debug logging:
services.nebula.networks.mynet = {
# ... other config ...
# Add to config.yml for debug
settings = {
logging = {
level = "debug";
format = "text";
};
};
};
Or temporarily run nebula manually:
sudo nebula -config /var/lib/nebula/mynet/config.yml