net/nebula: new plugin — Slack Nebula mesh overlay VPN#5504
Open
hstern wants to merge 17 commits into
Open
Conversation
Removing the master toggle field from the model and pointing the start / restart / apply paths at per-instance enabled. Matches WireGuard's model where each instance is its own daemon and there is no global subsystem enable. Fixes a UX dead-end on a fresh install: the model had a general.enabled field with no UI surface, so the instances page Apply / Start widgets did nothing (serviceEnabled() returned false, the service-control widget did not render, setup.php apply silently no-op'd) until the field was poked via the API or config.xml. The plugin's installed PLUGIN_DEPENDS=nebula binary alone meant a user could not enable the daemon at all without already knowing the internal model layout. Changes: - src/opnsense/mvc/app/models/OPNsense/Nebula/Nebula.xml: drop the <general><enabled> field (the only field under <general>). - src/opnsense/mvc/app/controllers/OPNsense/Nebula/Api/ServiceController.php: drop \$internalServiceEnabled; override serviceEnabled() to return true when at least one instance is enabled, so the standard reconfigure / status / widget plumbing works. - src/etc/inc/plugins.inc.d/nebula.inc: nebula_enabled() now iterates instances (same semantic for the services / devices / interface hooks). - src/opnsense/scripts/OPNsense/Nebula/setup.php: strip \$general_enabled from nebula_apply(), nebula_restart_instance(), and the CLI dispatcher; per-instance enabled is the only gate. - tools/reseed_demo.php: drop the now-unused general.enabled seed.
hstern
added a commit
to hstern/plugins
that referenced
this pull request
Jun 16, 2026
… drop PR sequencing gate Adds docs/README (index), overview.md, clients.md, widget.md, and architecture.md following Diataxis (how-to / reference / explanation). architecture.md covers the multi-controller model, token cache, read-only posture + rationale, the ARP/DHCP enrichment join, out-of-scope (VPN/hosting), and the pagination/v1 API quirks. Drops the net/nebula (opnsense#5504) sequencing gate from AGENTS.md — the two plugins are independent and net/omada's PR need not wait.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
A new plugin
net/nebulathat brings Slack Nebula — a scalable certificate-authenticated mesh overlay VPN — into the OPNsense web GUI. Each Nebula tunnel becomes a first-class assignable OPNsense interface (like WireGuard'swgN); PKI, daemon lifecycle, overlay firewall, routing and live monitoring are all managed from the UI.Coverage
tools/audit_knobs.pyreportsdeferred=0against Nebula 1.10.x — every documented knob is either modelled as a typed field or rendered through the per-instance YAML generator. Lighthouse allow-lists (remote/local +remote_allow_ranges/calculated_remotes) and the stats (graphite/prometheus) block are surfaced as hand-edited textareas.nebula_devices()/nebula_interfaces()plugin hooks registernebulaXXXXXXtun devices for Interfaces → Assignments and anebulagroup in Firewall → Rules. Device names are stable (md5(uuid)-derived, never re-used) so freed names can't inherit firewall settings.list-hostmapfan-out), per-instance Status page, dashboard widget.setup.php applyreloads in place via the debug server (Nebulareload= SIGHUP) and only full-restarts when a structural key (listen.host/port,cipher,tun.dev) changed — so a firewall or route edit doesn't drop live tunnels.Dependency
PLUGIN_DEPENDS = nebula→security/nebula, which is already inopnsense/portsat 1.10.3 (commit 2e30ee5a, 2026-06-11). 1.10.x is required for the encrypted-CA passphrase,pki.blocklist, andpki.initiating_versionfeatures the plugin exposes.Tests
tools/gen_knobs_test.py— 111 cases. Drives the config generator against every documented knob and asserts the rendered YAML.src/opnsense/mvc/tests/app/models/OPNsense/Nebula/GenerateConfigTest.php— 42 cases. Round-trips model XML → generated YAML.Verification
Built and deployed end-to-end on a fresh OPNsense 26.1.6 dev VM (FreeBSD 14.3-RELEASE-p10): instance create + CA + cert sign + Apply → daemon starts, tunnel device comes up and is assignable, dashboard widget populates, Tunnels page shows live state.
License + maintainership
BSD 2-Clause throughout. Maintained by henry@stern.ca.
What this isn't
This is the standalone OPNsense plugin for upstream Nebula. It is not affiliated with Slack; it just uses their open-source
nebula/nebula-certbinaries.