Wheelhouse

Add-ons that are configuration#

The plugin system in the shape an OPNsense user expects, on a substrate that makes it behave better: an add-on is a container declared in the router's configuration tree.

Why that matters#

An install is a diff you review before it happens, a commit you can roll back with any other revision, and state that survives an image upgrade because /config is the persistent partition. Not an opaque package with a lifecycle of its own.

Stopping an app stages set container name <x> disable. Starting it deletes that node. Uninstalling deletes the subtree. Volumes under /config are deliberately not removed on uninstall, so a reinstall picks up where it left off and nobody loses a password vault to a mis-click.

The catalogue#

38 entries, embedded in the agent binary (agent/catalog.json): 36 containers and 2 built-in feature modules, across six categories — DNS and filtering, VPN and remote access, Monitoring, Security, Network services, Management. Every container image is verified against its registry out of band.

Installing is three steps, and only one is configuration#

VyOS validates a container at commit time and rejects it if either prerequisite is missing, so both happen before the working diff exists:

StepWhat happensWhy it is separate
1 · Directoriesmkdir -p for each volume sourceVyOS refuses a volume whose source path does not exist
2 · Pulladd container image <ref>VyOS refuses an image that is not local
3 · Stageset container name … into the Commit BarThis is the only part that is configuration

Step 1 works only when the agent is on the router. From another machine it has no access to the router's filesystem, so it hands you the exact mkdir -p line rather than pretending to have done something.

What makes it a plugin rather than a container#

Each entry declares what the interface should do once the app is running:

  • A left-navigation entry of its own, with a dot when the app is declared but not running.
  • An Open link built from the container's real address.
  • A health probe that is TCP, plus an HTTP request when the entry gives a path. Deliberately never an app-specific API call — the product does not claim knowledge of an app's internals it does not have.
  • Hints: an offer surfaced on another page, with the app's real address substituted and the exact operations attached. Install AdGuard Home and the DNS page grows a card offering to point the resolver at it, with one click to stage the change.

Anything router-specific in a hint is a placeholder filled in from the router the hint is offered on. The catalogue itself never names a network or a domain, and a test refuses one. A router that cannot fill a placeholder gets the advice without the commands, and the card says what is missing.

Hints stage. They never apply. The Commit Bar is still the only thing that commits.

Feature modules#

Two entries have kind: "builtin": they gate a native page instead of running a container. WireGuard and the Suricata IDS work this way, which is how a page can be absent from a router that does not use it and one click away on one that does. Configuration outranks the flag: a feature configured on the router shows its page regardless.

The honest limits#

There are no per-app dashboard widgets, and that is deliberate: a widget would mean calling an app's own API, which is exactly the knowledge the health probe declines to claim.

One entry exists to close a documented gap#

dnsmasq is in the catalogue because VyOS cannot express wildcard DNS records, per-host DHCP option overrides, or an architecture-conditional PXE boot file. The entry is labelled as such. UPnP has no such answer: the miniupnpd entry was removed when registry verification showed the reference did not exist and every published alternative was an unaudited personal build — not acceptable for a privileged host-network daemon. The Companions page says the gap is open.

Read on#

Updated 2026-09-02