opnsense-controller¶
The OPNsense firewall controller for TAPPaaS. It drives the OPNsense firewall over its REST API to converge the network plane onto a desired state: VLANs/zones, DHCP, split-horizon DNS, the Caddy reverse proxy, NAT port-forwards, firewall rules, ACME/TLS certificates, and syslog.
It is a single Python package that ships a family of CLIs, one per concern. Each is its own command on PATH.
A long worked-example reference (per-command examples, credential setup, port auto-detection) lives in
CLI-REFERENCE.md. This README is the overview/index of every command.
| Command | Purpose |
|---|---|
opnsense-controller | Low-level example/driver for VLAN, DHCP and firewall managers. |
zone-manager | Reconcile VLANs + DHCP + firewall rules from zones.json. The everyday network reconcile. |
dns-manager | DNS host entries in OPNsense Dnsmasq (and static DHCP reservations). |
dhcp-manager | DHCP scope options — PXE next-server/bootfile for node provisioning (pxe enable/disable/status, design N3). |
unbound-manager | Unbound host overrides (split-horizon / internal DNS), DNSSEC, DNS blocklists. |
caddy-manager | The Caddy reverse proxy: domains, handlers, access lists. |
nat-manager | Destination-NAT (port-forward) rules. |
opnsense-firewall | Individual firewall rules (create/list/delete/apply); wan and segments read what the firewall holds. |
rules-manager | Per-module firewall rules compiled from module JSON + zones.json. |
acme-manager | ACME (Let's Encrypt) wildcard certificates via DNS-01. |
syslog-manager | OPNsense built-in syslog destinations. |
ipv6-manager | The site's IPv6: Allow IPv6, the WAN, each zone's network and advertisements, AAAA records and access lists for published names. |
mdns-manager | mDNS discovery across zones: the repeater's zones and its rule, from zones.json mdns and modules' discoveryMdns. |
test-network-manager | A throwaway isolated test network (create/delete/status). |
Credentials & common flags¶
Credentials live in ~/.opnsense-credentials.txt (token on line 1, secret on line 2). Most commands share these flags:
--firewall <host>— firewall hostname (defaultfirewall.mgmt.internal; envOPNSENSE_HOST).--port <n>/--api-port <n>— API port (default: probe 443 then 8443).--credential-file <path>— override the credential file.--no-ssl-verify— skip TLS verification.--debug— debug logging.--check-mode(most managers) or--execute(opnsense-controller) — dry-run vs apply.
Most managers default to dry-run / check mode and require an explicit apply (--execute, or simply running without --check-mode, depending on the command — check --help).
The commands¶
zone-manager — VLANs, DHCP and firewall from zones.json¶
Reads zones.json and configures VLANs, DHCP scopes and access-based firewall rules to match. Key flags: --zones-file, --execute (apply; default is dry-run), --interface <if> (physical interface, default vtnet1), --vlans-only / --dhcp-only / --rules-only / --no-rules, --summary (zone summary + pinhole report), --list-zones, --no-assign, --reconcile-labels, --skip-health-gate / --skip-egress-probe.
zone-manager # dry-run: show what would change
zone-manager --execute # apply VLANs + DHCP + rules
zone-manager --summary # zone summary + which pinholes are allowed
dns-manager — Dnsmasq host entries¶
dns-manager add <hostname> <domain> <ip> [--description <d>] [--mac <mac>]
dns-manager delete <hostname> <domain>
dns-manager list
dns-manager check-range <ip> # exit 1 if <ip> is inside a DHCP pool
--mac makes the entry a static DHCP reservation (MAC → IP). --check-mode for dry-run. unbound-manager — split-horizon host overrides¶
unbound-manager add <hostname> <domain> <ip> [--description <d>]
unbound-manager delete <hostname> <domain>
unbound-manager list
unbound-manager dnssec --set true|false # site.json dnssec
unbound-manager dnsbl [--config-dir <dir>] # site.json dnsBlocklists
* as the hostname for a wildcard override. --check-mode for dry-run. A wildcard is an Unbound redirect zone, which may hold no other record below it: add skips a name a wildcard already answers with the same IP, and refuses any other nested record (or a wildcard over existing ones). A write that still stops the resolver is rolled back. dnssec and dnsbl are what the network module's update runs. dnsbl writes the entries described TAPPaaS: site blocklists… (one per address family) and leaves hand-made ones alone; see network/DESIGN.md.
caddy-manager — reverse proxy¶
caddy-manager add-domain <domain> [--description <d>] [--dns-challenge | --custom-certificate <refid>]
caddy-manager add-handler <domain> (--upstream <host> | --redir <url>)
[--redir-path <p>] [--port <n>] [--description <d>] [--access-list <name>]
[--upstream-tls] [--upstream-http1] [--preserve-host] [--forward-auth]
caddy-manager add-accesslist <name> --clients <ip,cidr,...>
[--matcher remote_ip|client_ip] [--invert] [--response-code <n>] [--description <d>]
caddy-manager delete-accesslist <name>
caddy-manager delete-domain <domain>
caddy-manager delete-handler <domain> (--description <d> | --uuid <u>)
caddy-manager list
caddy-manager reconfigure
--forward-auth (route unauthenticated clients to the identity outpost), --upstream-tls (HTTPS upstream), --upstream-http1 + --preserve-host (needed for some WebSocket apps). nat-manager — destination-NAT / port-forward¶
nat-manager add-rule --description <d> --external-port <p> --target <ip> --internal-port <p>
[--protocol tcp|udp] [--interface <if>] [--destination <addr>] [--source <addr>]
[--ip-protocol inet|inet6|inet46] [--disabled] [--no-apply]
nat-manager list-rules [--search <s>]
nat-manager delete-rule (--description <d> | --uuid <u>) [--no-apply]
nat-manager apply
nat-manager test
--description is the idempotency key. opnsense-firewall — individual firewall rules¶
opnsense-firewall create --description <d> --interface <if> [--action pass|block|reject]
[--direction in|out] [--protocol <p>] [--source <s>] [--destination <d>]
[--source-port <p>] [--destination-port <p>] [--sequence <n>] [--disabled] [...]
opnsense-firewall list [--search <s>]
opnsense-firewall delete (--description <d> | --uuid <u>) [--no-apply]
opnsense-firewall apply
opnsense-firewall test
opnsense-firewall wan [--json] # the addresses the WAN interface holds
opnsense-firewall segments [--json] # every VLAN device and assigned interface: tag, label, IPv4 network (#862)
rules-manager — per-module firewall rules¶
Compiles a module's firewall rules from its module JSON + zones.json + aliases.json.
rules-manager add-rules <module> # compile and apply
rules-manager reconcile <module> # diff live vs module.json; apply + prune
rules-manager remove-rules <module> # remove all rules/aliases owned by a module
rules-manager verify-rules <module> [--deep] [--detect-overlap] # presence (+ probes, + overlaps)
rules-manager list-rules [--module <m>] [--orphans]
rules-manager overlaps [--module <m>] # shadowed / redundant / conflicting rules (read-only)
rules-manager list-slots # the sequence map: slots, rules in use, rules left out
rules-manager recheck-covered # rewrite rules a narrowed access-to no longer covers
rules-manager create-alias <name> --addresses <a,...> [--type host] [--description <d>]
rules-manager remove-alias <name>
--zones-file, --aliases-file, --modules-dir, --check-mode, --output text|json, --firewall-type opnsense|NONE. acme-manager — wildcard TLS via DNS-01¶
acme-manager setup --domain <d> --email <e> [--provider cloudflare]
[--provider-field KEY=VALUE ...] [--staging] [--no-include-apex]
[--dns-sleep <s>] [--timeout <s>] [--key-length key_2048] [...]
acme-manager status --domain <d>
acme-manager delete --domain <d> [--dry-run]
delete removes the *.<domain> certificate request and its issued certificate in the Trust store (#790) — never the shared account, validation, action or renewal cron. environment-manager delete calls it. setup idempotently provisions the LE account + DNS-01 validation + caddy-reload action and issues a *.<domain> certificate. syslog-manager — syslog destinations¶
syslog-manager add-destination --hostname <h> --description <d>
[--port 514] [--transport tcp4|...] [--rfc5424] [--level <a,b>] [--facility <...>]
[--program <...>] [--certificate <uuid>]
syslog-manager delete-destination (--description <d> | --uuid <u>)
syslog-manager list
syslog-manager reconfigure
ipv6-manager — the site's IPv6¶
ipv6-manager apply [--check-mode] [--config-dir <dir>] # converge to site.json + zones.json
ipv6-manager status # does the firewall allow IPv6
ipv6-manager gateway <zone> # the firewall's IPv6 address in a zone (exit 3: none)
apply is what the network module's update runs: Allow IPv6 from site.json ipv6, the WAN from network.wan.ipv6, and every zone with an ipv6Subnet its /64, router advertisements and AAAA names; then the AAAA records of published names and the IPv6 networks in Caddy's access lists, from what the interfaces hold. Switching off withdraws each zone's IPv6 route before removing it. What it all means for an operator: IPV6.md.
mdns-manager — mDNS discovery across zones¶
mdns-manager apply [--check-mode] [--config-dir <dir>] [--without <module>]
mdns-manager status # the repeater's interfaces and the rule
apply is what the network module's update runs, and what network:discovery runs for a module: the zones with "mdns": true plus every module's zone0 and discoveryMdns zones form one group; the os-mdns-repeater plugin (installed when first needed) relays among them, and the rule TAPPaaS: mDNS to the repeater (sequence 975) lets each reach it. Fewer than two zones switches the repeater off and removes the rule. --without leaves one module out — its delete-service. The operator view: ZONES.md.
test-network-manager — isolated test network¶
test-network-manager create --device <dev> [--cidr <gw/prefix>]
[--dhcp-start <ip>] [--dhcp-end <ip>] [--mgmt-net <cidr>] [--mgmt-iface <if>]
[--domain test.internal] [--check-mode] [...]
test-network-manager delete
test-network-manager status
opnsense-controller — low-level driver¶
The base CLI used mostly for examples/diagnostics: --mode vlan|dhcp|firewall, --example <name>, --execute (default is check/dry-run), --interface, --assign. Day-to-day work uses the higher-level commands above.