slackhq/nebula
A scalable overlay networking tool with a focus on performance, simplicity and security
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 1d ago
- ✓12 active contributors
- ✓Distributed ownership (top contributor 33% of recent commits)
Show 3 more →Show less
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/slackhq/nebula)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/slackhq/nebula on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: slackhq/nebula
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/slackhq/nebula shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 1d ago
- 12 active contributors
- Distributed ownership (top contributor 33% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live slackhq/nebula
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/slackhq/nebula.
What it runs against: a local clone of slackhq/nebula — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in slackhq/nebula | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 31 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of slackhq/nebula. If you don't
# have one yet, run these first:
#
# git clone https://github.com/slackhq/nebula.git
# cd nebula
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of slackhq/nebula and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "slackhq/nebula(\\.git)?\\b" \\
&& ok "origin remote is slackhq/nebula" \\
|| miss "origin remote is not slackhq/nebula (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "cmd/nebula/main.go" \\
&& ok "cmd/nebula/main.go" \\
|| miss "missing critical file: cmd/nebula/main.go"
test -f "control.go" \\
&& ok "control.go" \\
|| miss "missing critical file: control.go"
test -f "connection_manager.go" \\
&& ok "connection_manager.go" \\
|| miss "missing critical file: connection_manager.go"
test -f "config/config.go" \\
&& ok "config/config.go" \\
|| miss "missing critical file: config/config.go"
test -f "cert/cert.go" \\
&& ok "cert/cert.go" \\
|| miss "missing critical file: cert/cert.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 31 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~1d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/slackhq/nebula"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Nebula is a scalable peer-to-peer overlay networking tool built on the Noise Protocol Framework that lets you create encrypted virtual networks across any cloud provider, datacenter, or endpoint. It uses certificate-based authentication to assert node IP addresses and group membership, enabling provider-agnostic traffic filtering and discovery through lighthouses (bootstrap nodes) that support UDP hole punching for NAT traversal. The core appeal is a unified network abstraction that works across 10s to 10,000s of nodes without maintaining specific addressing schemes. Monolithic Go module structure: root contains core networking logic (allow_list.go, calculated_remote.go, bits.go for bitwise utilities); cert/ subpackage handles PKI and certificates (ca_pool.go, cert.go for v1); cmd/ contains CLI entry points; test files colocated (_test.go suffix). GitHub Actions workflows in .github/workflows/ drive CI/CD; smoke tests in .github/workflows/smoke/ validate end-to-end scenarios across OS variants with Vagrant.
👥Who it's for
Infrastructure engineers and DevOps teams managing distributed systems across multiple clouds/datacenters; security-conscious organizations that need encrypted peer-to-peer connectivity; platform teams building private network overlays for microservices or IoT deployments. Contributors are primarily systems programmers comfortable with low-level networking (Go, C interop via cgo) and cryptographic protocols.
🌱Maturity & risk
Production-ready and actively maintained. The codebase is substantial (1.35M LOC Go), has comprehensive CI/CD with smoke tests across Linux/FreeBSD/NetBSD/OpenBSD variants, broad platform support (Linux, Windows, macOS, iOS, Android), and is packaged in major distros (Arch, Fedora, Debian, Alpine, Homebrew). It's backed by Slack's infrastructure org and has clear security processes (SECURITY.md present, code signing in CI).
Moderate risk factors: 40+ direct dependencies (some security-critical like golang.org/x/crypto and miekg/dns); cryptographic code is complex and requires careful auditing; single primary maintainer risk typical of infrastructure projects. However, the explicit security policy, signed releases, and integration into stable distributions mitigate exposure. No obvious abandoned areas, though mobile app is in separate repo (github.com/DefinedNet/mobile_nebula).
Active areas of work
Active development focused on stability and platform support. The repo has smoke test workflows for multiple OSes, Dependabot integration for dependency updates, and recent code organization (gofmt.yml linting). Release workflow (release.yml) and code-signing action suggest active release cadence. No specific issue data visible, but Makefile and build infrastructure suggest ongoing build system refinement.
🚀Get running
Clone and build: git clone https://github.com/slackhq/nebula.git && cd nebula && make. Requires Go 1.25.0+. Run tests: go test ./.... Review Makefile for available targets (build, test, install). See cert/README.md for certificate generation, LOGGING.md for debug output configuration.
Daily commands:
Build: make. Install: make install (platform-dependent). Run nebula daemon (after cert setup): nebula -config /etc/nebula/config.yml. For development: go build -o nebula ./cmd/nebula creates binary. Smoke tests: .github/workflows/smoke/smoke.sh demonstrates end-to-end setup with Vagrant.
🗺️Map of the codebase
cmd/nebula/main.go— Entry point for the Nebula daemon; orchestrates initialization of network stack, configuration loading, and lifecycle management.control.go— Core control plane logic managing handshakes, tunnel establishment, and packet routing decisions—essential for understanding overlay network behavior.connection_manager.go— Manages peer connection lifecycle, including connection creation, state tracking, and cleanup; central to tunnel stability.config/config.go— Configuration parsing and validation; all network settings flow through here, affecting initialization and runtime behavior.cert/cert.go— Certificate handling and validation; critical for mTLS and trust chain verification in the overlay network.allow_list.go— Implements firewall-like filtering rules for inbound/outbound traffic; determines whether packets are allowed between peers.cmd/nebula-cert/main.go— CLI for certificate generation and management; required for bootstrapping secure Nebula networks.
🛠️How to make changes
Add a new firewall rule type to allow_list
- Define the new rule structure and parsing logic in allow_list.go (e.g., add a new field to the rule struct and update the rule evaluation logic in the Evaluate method). (
allow_list.go) - Extend config/config.go to accept the new rule type in the firewall configuration section and parse it from YAML. (
config/config.go) - Add comprehensive test cases in allow_list_test.go covering your new rule type with positive and negative scenarios. (
allow_list_test.go) - Update the control.go handshake or packet handling logic to invoke the allow_list evaluator with the new rule context. (
control.go)
Add a new certificate extension to cert format
- Define the new extension field in cert/cert_v2.asn1 or update cert/cert_v1.proto (depending on format), then regenerate Go bindings. (
cert/cert_v2.asn1) - Implement getter/setter methods in cert/cert_v2.go or cert/cert_v1.go to expose the new field. (
cert/cert_v2.go) - Update cmd/nebula-cert/sign.go to accept the new extension as a CLI flag and populate it during certificate signing. (
cmd/nebula-cert/sign.go) - Update cert validation logic in cert/crypto.go or control.go to enforce constraints based on the new extension. (
cert/crypto.go) - Add tests in cert/cert_v2_test.go to verify encoding, decoding, and validation of the new extension. (
cert/cert_v2_test.go)
Add a new configuration parameter for tunnel behavior
- Add the new field to the Config struct in config/config.go, provide YAML tag, and implement parsing with validation/defaults. (
config/config.go) - Reference the new config value in control.go or connection_manager.go where tunnel behavior is initialized or adjusted. (
control.go) - Add test cases in config/config_test.go to verify the new parameter is parsed correctly from YAML. (
config/config_test.go) - Update cmd/nebula/main.go logging output to report the new setting at startup for visibility. (
cmd/nebula/main.go)
Optimize peer connection establishment
- Review the handshake state machine in control.go, specifically the message handling and retransmission logic. (
control.go) - Adjust connection timing and retry logic in connection_manager.go based on network conditions or measured latency. (
connection_manager.go) - Modify calculated_remote.go address resolution caching to improve direct connectivity detection. (
calculated_remote.go) - Add metrics collection and logging throughout the handshake process to measure latency and success rates. (
control_test.go)
🔧Why these technologies
- Go 1.25.0 — Cross-platform compilation, minimal dependencies, efficient networking primitives, and strong concurrency model ideal for high-performance overlay networking.
- Noise Protocol (flynn/noise) — Modern, lightweight cryptographic framework for authenticated encryption; chosen over TLS for simplicity and performance in peer-to-peer tunnels.
- Certificate-based PKI (v1 Protobuf + v2 ASN.1) — Flexible credential model supporting group-based access control, IP binding, and flexible signing; avoids external CA dependencies.
- Lighthouse (optional centralized discovery) — Enables peer discovery and NAT traversal in dynamic networks without requiring global DHT; supports hybrid deployments.
- Prometheus metrics (prometheus/client_golang) — Standard observability framework for monitoring tunnel health, connection counts, and latency; integrates with existing infrastructure.
⚖️Trade-offs already made
-
Custom handshake protocol instead of standard VPN protocols (WireGuard, OpenVPN)
- Why: Nebula prioritizes group-based firewall rules and decentralized peer discovery; existing VPN protocols lack this natively.
- Consequence: Smaller ecosystem, custom implementation burden, but tighter security model and simpler operational requirements.
-
Certificate-based identity instead of preshared keys or username/password
- Why: Scales better in large deployments, supports fine-grained group-based policies, and enables offline verification.
- Consequence: Requires PKI bootstrapping complexity, but eliminates credential rotation overhead and supports dynamic group membership.
-
Stateful connection tracking (connection_manager.go) instead of stateless packet forwarding
- Why: Enables efficient retransmission, rate limiting, and per-peer encryption state; required for Noise protocol security guarantees.
- Consequence: Higher memory footprint at scale, but deterministic encryption key lifecycle and better DDoS resilience.
-
Lighthouse as optional—not required for small deployments
- Why: Supports mesh networks without centralized infrastructure; lighthouse is purely for discovery optimization.
- Consequence: Adds operational complexity for large networks, but enables fully decentralized topologies when needed.
-
Allow/deny rules evaluated on every packet in allow_list.go
- Why: Provides zero-trust security model with dynamic group membership; firewall rules are core to Nebula's security posture.
- Consequence: CPU overhead per packet, but justifies with strong security guarantees and auditability.
🚫Non-goals (don't propose these)
- Does not provide traditional VPN user authentication (no username/password, LDAP, or OAuth integration
🪤Traps & gotchas
Certificate generation is prerequisite: config requires valid ca.crt, host.crt, host.key (see cert/README.md for nebula-cert tool). Platform-specific network interfaces require elevated privileges (root/admin). TUN interface setup differs by OS (Linux via netlink, Windows via wintun package). Smoke tests use Vagrant and Docker — heavy dependencies for local testing. YAML config parsing is strict (typos fail silently or cause runtime errors). IPv6 has OS-specific handling (see vagrant-linux-amd64-ipv6disable test variant).
🏗️Architecture
💡Concepts to learn
- Noise Protocol Framework — Nebula's foundational cryptographic protocol providing mutual authentication and encryption; understanding its design (handshake messages, forward secrecy) is critical for debugging security issues
- UDP Hole Punching — Enables Nebula peers behind NAT/firewalls to establish direct connections; implemented in calculated_remote.go and essential for understanding lighthouse-mediated peer discovery
- Lighthouse Discovery Pattern — Nebula's answer to centralized coordination — lightweight bootstrap nodes that relay peer addresses without routing traffic; critical to grasping architecture vs. traditional VPNs
- Certificate-Based Authorization — Nebula uses certificates (not just keypairs) to bind IP addresses, hostnames, and group memberships to identities; allow_list.go and cert/ implement this; core to understanding traffic filtering
- TUN/TAP Interface — Virtual network interface abstraction allowing userspace packet capture/injection; Nebula uses platform-specific implementations (Linux netlink, Windows wintun) to create overlay network
- CIDR Notation & Bit Operations — bits.go implements IP range matching for allow list rules; understanding bitwise operations on IP addresses is necessary for modifying traffic filtering logic
- Radix Tree for Route Lookup — Nebula uses armon/go-radix for efficient IP prefix matching in calculated_remote.go; understanding tree-based route lookups is important for performance optimizations
🔗Related repos
wireguard/wireguard-go— Complementary VPN technology; Nebula's architecture borrows ideas from WireGuard but adds discovery/lighthouse abstraction for dynamic peeringtailscale/tailscale— Direct competitor offering similar peer-to-peer VPN with centralized coordination; Nebula differs by focusing on decentralized lighthouse discoveryDefinedNet/mobile_nebula— Official mobile app companion repo (iOS/Android) extending Nebula to mobile platforms with native TUN integrationfastly/boringtun— High-performance WireGuard implementation in Rust; reference for optimized TUN/UDP handling patterns Nebula could adopthashicorp/nomad— Common deployment platform for distributed systems that use Nebula for secure inter-node communication in Nomad clusters
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for allow_list.go and bits.go
These core utility files (allow_list.go, bits.go, calculated_remote.go) have corresponding test files but lack coverage for edge cases in firewall rule matching and bit manipulation operations. Given Nebula's security focus, robust testing of allow/deny list logic is critical. The existing test files are minimal and could be expanded significantly.
- [ ] Review existing allow_list_test.go, bits_test.go, and calculated_remote_test.go for coverage gaps
- [ ] Add edge case tests for CIDR matching, IPv6 handling, and malformed rule parsing in allow_list_test.go
- [ ] Add tests for bit boundary conditions and performance in bits_test.go
- [ ] Ensure tests cover the interaction between allow_list.go and the cert/ package for rule validation
- [ ] Run
go test -coverand target >90% coverage for these files
Add GitHub Actions workflow for code coverage reporting and enforcement
The repo has test.yml, gofmt.yml, and smoke tests, but no coverage reporting or enforcement workflow. With security-critical code like cert/, allow_list.go, and bits.go, enforcing minimum coverage thresholds (e.g., >80%) would prevent regressions. This workflow should integrate with tools like codecov or use built-in go test -cover.
- [ ] Create .github/workflows/coverage.yml that runs
go test -coverprofile=coverage.out ./... - [ ] Add coverage threshold checks (fail if coverage drops below 80% for modified files)
- [ ] Integrate with Codecov or Codacy for visual reports on PRs
- [ ] Add badge to README.md showing current coverage percentage
- [ ] Reference this workflow in CODEOWNERS to require checks before merge
Add missing documentation for cert/ package ASN.1 certificate format
The cert/ directory contains cert_v2.asn1 and cert_v2.go files, but cert/README.md lacks detailed documentation on the ASN.1 schema, migration path from v1 to v2, and certificate field validation rules. New contributors struggle to understand certificate generation and validation without this. The LOGGING.md file exists but no equivalent for certificate handling.
- [ ] Expand cert/README.md with ASN.1 schema documentation (parse and explain cert_v2.asn1)
- [ ] Document the difference between cert_v1.proto (protobuf) and cert_v2.asn1 formats with migration examples
- [ ] Add code examples showing how to validate certificates using cert/crypto.go
- [ ] Document the role of cert/ca_pool.go in certificate chain validation
- [ ] Add troubleshooting section for common certificate errors (expired, invalid signature, etc.)
🌿Good first issues
- Add unit tests for bits.go utility functions (bitwise operations for IP/CIDR handling) — tests exist but coverage is incomplete based on bits_test.go being present but minimal
- Write integration test for allow_list.go group-based filtering with realistic security group rules — core feature but test coverage could be more comprehensive
- Improve error messages in cert/cert.go certificate validation — current errors are generic; add context about which certificate field failed and why (helps debugging misconfiguration)
⭐Top contributors
Click to expand
Top contributors
- @nbrownus — 33 commits
- @dependabot[bot] — 30 commits
- @JackDoan — 14 commits
- @wadey — 7 commits
- @johnmaguire — 5 commits
📝Recent commits
Click to expand
Recent commits
398d67e— Windows code signing (#1718) (nbrownus)696903d— Add a way to set the network type on windows + tests (#1710) (nbrownus)c82db21— Change windows unsafe routes to link routes, fix sshd reload bug (#1709) (nbrownus)1ada3d4— Use DefinedNets fancy new netbsd10 vagrant box for smokes (#1711) (nbrownus)5f920fd— Remove the global noiseEndianness var (#1707) (nbrownus)cba9ea5— Bump github.com/gaissmai/bart from 0.26.0 to 0.26.1 (#1604) (dependabot[bot])83809a5— Bump actions/download-artifact from 7 to 8 (#1617) (dependabot[bot])23c67bd— Bump actions/upload-artifact from 6 to 7 (#1618) (dependabot[bot])dd3a7ad— Bump docker/setup-buildx-action from 3 to 4 (#1627) (dependabot[bot])dd2ac5d— Bump docker/login-action from 3 to 4 (#1628) (dependabot[bot])
🔒Security observations
- High · Outdated Go Version —
go.mod (go 1.25.0). The project specifies Go 1.25.0 which does not exist as a stable release. Go's latest stable version is 1.23.x. This suggests either a misconfiguration or use of an unreleased version, potentially missing critical security patches. Fix: Update to the latest stable Go version (1.23.x or later). Verify the go.mod file and update to a released version of Go. - High · Outdated Cryptographic Dependencies —
go.mod (golang.org/x/crypto, golang.org/x/net, golang.org/x/sys). Several cryptographic dependencies are significantly outdated: golang.org/x/crypto v0.50.0 (released 2024-01, current versions are 0.28+), golang.org/x/net v0.53.0, and golang.org/x/sys v0.43.0. These versions may contain known CVEs. Fix: Update all golang.org/x/* dependencies to the latest stable versions. Run 'go get -u golang.org/x/crypto golang.org/x/net golang.org/x/sys' and verify compatibility. - High · Protobuf Dependency Version Mismatch —
go.mod (github.com/gogo/protobuf and google.golang.org/protobuf). The project uses github.com/gogo/protobuf v1.3.2 alongside google.golang.org/protobuf v1.36.11. gogo/protobuf is deprecated since 2021 and no longer maintained. This can lead to security issues and compatibility problems. Fix: Migrate entirely to google.golang.org/protobuf. Remove gogo/protobuf dependency and regenerate protobuf code using the official compiler. - Medium · WireGuard Windows Binding Version Outdated —
go.mod (golang.zx2c4.com/wireguard/windows). golang.zx2c4.com/wireguard/windows v0.6.1 is specified but current versions are significantly newer. This may lack critical security patches for Windows networking code. Fix: Update to the latest version of wireguard/windows. Review release notes for security fixes and breaking changes. - Medium · YAML Dependency Duplication —
go.mod (go.yaml.in/yaml/v3 and gopkg.in/yaml.v3). The project includes both go.yaml.in/yaml/v3 v3.0.4 and gopkg.in/yaml.v3 v3.0.1, which are duplicate dependencies with different versions. This increases attack surface and may cause parsing inconsistencies. Fix: Standardize on a single YAML library. Use gopkg.in/yaml.v3 v3.0.1 (the more widely adopted version) and remove go.yaml.in/yaml/v3 entirely. - Medium · gVisor Dependency Far Behind Current Releases —
go.mod (gvisor.dev/gvisor). gvisor.dev/gvisor v0.0.0-20240423190808-9d7a357edefe is from April 2024. gVisor receives frequent security updates and this version may be significantly outdated relative to current releases. Fix: Check the current gVisor release and update to the latest stable version. Review security advisories for any vulnerabilities in the current version. - Medium · Noise Protocol Implementation Version —
go.mod (github.com/flynn/noise). github.com/flynn/noise v1.1.0 is used for the Noise protocol implementation. Verify this version has no known CVEs and is actively maintained. Fix: Audit the Noise protocol implementation. Check GitHub for any security advisories or issues. Consider if alternative maintained implementations are available. - Low · Development Dependencies in Production —
go.mod (go.uber.org/goleak). go.uber.org/goleak is listed as a dependency. This is a memory leak detection tool typically used only during testing, not in production binaries. Fix: Move go.uber
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.