Nebula
Updated: April 6, 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
- iPhone App
- 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
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 as network with name of megaport
nebula-cert ca -name "megaport" -duration 87600h
# This creates:
# - ca.crt (public certificate)
# - ca.key (private key - keep this secure!)
# Check CA information (expiration, network, subnets etc)
nebula-cert print -path ca.crt
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.
iPhone Nebula App
The Nebula app will provide a device.pub that is shared.
Place that device.pub on the machine where you can sign and send back a cert pair. (Single File)
nebula-cert sign -in-pub device.pub -name "phoneName" -ip "10.99.0.152/16" -groups "admin" ca.crt ca.key
The app will need the signed cert and ca.crt.
The process is started where you will want to import your config.yml
With these 3 things your phone should be able to connect to the Nebula Mesh.
For phones, because they travel, set listen port to 0.0.0.0:0
This sets the port to search dynamically back to the network which can help with port conflicts.
Lighthouse Setup
A lighthouse helps hosts discover each other. You typically need at least one lighthouse in your network.
Generate Lighthouse Certificate
Set a name, nebula ip address and group
The cert will have expiration of CA that signed as well as network (megaport)
# Generates (sign) certificate for a host machine. key and cert will bear hostname
nebula-cert sign -name "hostname" -ip "10.99.0.42/24" -groups "admin,server" 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