mirror of
https://github.com/h44z/wg-portal.git
synced 2026-10-08 06:26:41 +00:00
feat(backend): add OPNsense backend (#743)
Manages interfaces and peers on OPNsense through the WireGuard API in
OPNsense core, so a stock appliance needs nothing installed. OPNsense
calls a tunnel a "server" and a peer on it a "client"; those map to
PhysicalInterface and PhysicalPeer.
Reads go through searchXxx because getXxx returns select fields as
{value, selected} maps that cannot be posted back to a write. Validation
failures arrive as HTTP 200 with a "result": "failed" body, so the body
is checked and not the status code.
Firewall rules are not managed, matching the pfSense backend: a new
tunnel handshakes but carries no traffic until a pass rule exists.
Alpha, and documented as such.
Signed-off-by: clark-ja <37738506+clark-ja@users.noreply.github.com>
This commit is contained in:
@@ -219,7 +219,7 @@ The current MikroTik backend is in **BETA** and may not support all features.
|
||||
### `default`
|
||||
- **Default:** `local`
|
||||
- **Description:** The default backend to use for managing WireGuard interfaces.
|
||||
Valid options are: `local`, or other backend id's configured in the `mikrotik` section.
|
||||
Valid options are: `local`, or other backend id's configured in the `mikrotik`, `pfsense` or `opnsense` sections.
|
||||
|
||||
### `rekey_timeout_interval`
|
||||
- **Default:** `180s`
|
||||
@@ -293,6 +293,58 @@ Below are the properties for each entry inside `backend.mikrotik`:
|
||||
|
||||
For more details on configuring the MikroTik backend, see the [Backends](../usage/backends.md) documentation.
|
||||
|
||||
### OPNsense
|
||||
|
||||
The `opnsense` array contains a list of OPNsense backend definitions. Each entry describes how to connect to an OPNsense firewall that hosts WireGuard interfaces.
|
||||
The WireGuard API used here is part of OPNsense core, so no add-on package needs to be installed on the firewall.
|
||||
|
||||
Below are the properties for each entry inside `backend.opnsense`:
|
||||
|
||||
#### `id`
|
||||
- **Default:** *(empty)*
|
||||
- **Description:** A unique identifier for this backend.
|
||||
This value can be referenced by `backend.default` to use this backend as default.
|
||||
The identifier must be unique across all backends and must not use the reserved keyword `local`.
|
||||
|
||||
#### `display_name`
|
||||
- **Default:** *(empty)*
|
||||
- **Description:** A human-friendly display name for this backend. If omitted, the `id` will be used as the display name.
|
||||
|
||||
#### `api_url`
|
||||
- **Default:** *(empty)*
|
||||
- **Description:** Base URL of the OPNsense appliance, including scheme, e.g., `https://opnsense.example.com`.
|
||||
Do not append `/api`; the backend adds the API paths itself.
|
||||
|
||||
#### `api_key`
|
||||
- **Default:** *(empty)*
|
||||
- **Description:** API key, created under `System -> Access -> Users -> <user> -> API keys`.
|
||||
|
||||
#### `api_secret`
|
||||
- **Default:** *(empty)*
|
||||
- **Description:** The secret belonging to `api_key`. OPNsense authenticates the pair as HTTP Basic credentials.
|
||||
The secret is shown only once, when the key is created.
|
||||
|
||||
#### `api_verify_tls`
|
||||
- **Default:** `false`
|
||||
- **Description:** Whether to verify the TLS certificate of the OPNsense API endpoint. Set to `false` to allow self-signed certificates (not recommended for production).
|
||||
|
||||
#### `api_timeout`
|
||||
- **Default:** `30s`
|
||||
- **Description:** Timeout for API requests to the OPNsense firewall. Uses Go duration format (e.g., `10s`, `1m`). If omitted, a default of 30 seconds is used.
|
||||
|
||||
#### `ignored_interfaces`
|
||||
- **Default:** *(empty)*
|
||||
- **Description:** A list of interface names to exclude during interface enumeration.
|
||||
This is useful if you want to prevent specific interfaces from being imported from the OPNsense firewall.
|
||||
|
||||
#### `debug`
|
||||
- **Default:** `false`
|
||||
- **Description:** Enable verbose debug logging for the OPNsense backend.
|
||||
|
||||
> There is deliberately no `concurrency` option for this backend. The MikroTik and pfSense backends issue one request per interface when enumerating details; the OPNsense search endpoints return every record with its fields already populated, so enumeration costs a fixed number of requests regardless of how many tunnels exist.
|
||||
|
||||
For more details on configuring the OPNsense backend, see the [Backends](../usage/backends.md) documentation.
|
||||
|
||||
---
|
||||
|
||||
## Advanced
|
||||
|
||||
@@ -9,9 +9,10 @@ A global default backend determines where newly created interfaces go (unless yo
|
||||
- **Local** (default): Manages interfaces on the host running WireGuard Portal (Linux WireGuard via wgctrl). Use this when the portal should directly configure wg devices on the same server.
|
||||
- **MikroTik** RouterOS (_beta_): Manages interfaces and peers on MikroTik devices via the RouterOS REST API. Use this to control WG interfaces on RouterOS v7+.
|
||||
- **pfSense** (_alpha_): Manages interfaces and peers on pfSense firewalls via the pfSense REST API.
|
||||
- **OPNsense** (_alpha_): Manages interfaces and peers on OPNsense firewalls via the WireGuard API built into OPNsense core. Unlike the pfSense backend, no add-on package is required on the firewall.
|
||||
|
||||
How backend selection works:
|
||||
- The default backend is configured at `backend.default` (_local_ or the id of a defined MikroTik backend).
|
||||
- The default backend is configured at `backend.default` (_local_ or the id of a defined MikroTik, pfSense or OPNsense backend).
|
||||
New interfaces created in the UI will use this backend by default.
|
||||
- Each interface stores its backend. You can select a different backend when creating a new interface.
|
||||
|
||||
@@ -89,3 +90,47 @@ backend:
|
||||
### Known limitations:
|
||||
- Alpha quality: behavior and API coverage may change.
|
||||
- Statistics (rx/tx bytes, last handshake) are not available from the pfSense REST API today.
|
||||
|
||||
## Configuring OPNsense backends
|
||||
|
||||
> :warning: The OPNsense backend is currently **alpha**. Interface and peer CRUD are supported, as are **per-peer** traffic statistics (rx/tx bytes and last handshake), which the pfSense backend cannot provide. Interface-level byte counters are not reported, because OPNsense exposes counters per peer only. Interface hooks, DNS push and ping are not supported.
|
||||
|
||||
The OPNsense backend talks to the WireGuard API that is part of **OPNsense core**. Unlike the pfSense backend, no add-on package needs to be installed — a stock OPNsense install already answers `/api/wireguard/*`.
|
||||
|
||||
Point `api_url` at the appliance root (for example `https://opnsense.example.com`); the portal appends the API paths itself.
|
||||
|
||||
### Prerequisites on OPNsense:
|
||||
- OPNsense 24.1 or newer, where WireGuard is part of the base system. Developed and tested against 26.7.
|
||||
- An API key/secret pair, created under `System -> Access -> Users -> <user> -> API keys`. OPNsense shows the secret only once, at creation time.
|
||||
- The user needs permission for the WireGuard and firewall pages it should manage.
|
||||
- HTTPS recommended; set `api_verify_tls: false` only for lab/self-signed setups.
|
||||
|
||||
Example WireGuard Portal configuration:
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
# default backend decides where new interfaces are created
|
||||
default: opnsense1
|
||||
|
||||
opnsense:
|
||||
- id: opnsense1 # unique id, not "local"
|
||||
display_name: Edge firewall # optional nice name
|
||||
api_url: https://opnsense.example.com # appliance root, no /api suffix
|
||||
api_key: your-api-key
|
||||
api_secret: your-api-secret
|
||||
api_verify_tls: true
|
||||
api_timeout: 30s
|
||||
debug: false
|
||||
```
|
||||
|
||||
### Behaviour worth knowing:
|
||||
- **Interface naming.** An OPNsense tunnel has both an instance number and a free-text name. WireGuard Portal uses the resulting device name (`wg0`, `wg1`, ...) as the interface identifier, so an interface imported from OPNsense looks the same as one managed by the `local` backend. The free-text name becomes the display name.
|
||||
- **Changes are staged.** OPNsense applies WireGuard configuration only when the service is reconfigured, which the backend does after every change. Reconfiguring does **not** drop or rekey sessions of peers that are already connected, so adding a peer is safe against a live VPN.
|
||||
- **The service is enabled automatically.** Bringing an interface up switches on the global WireGuard service if it is off, because a tunnel configured while the service is disabled stays down without reporting an error anywhere. The backend never disables the service.
|
||||
- **Firewall rules are not managed.** A newly created tunnel has no pass rule, so peers will complete a handshake but carry no traffic until you add a rule on the `WireGuard (Group)` interface. This matches the pfSense backend, which also leaves firewall rules to the administrator.
|
||||
|
||||
### Known limitations:
|
||||
- Alpha quality: behavior and API coverage may change.
|
||||
- Interface hooks (`PreUp`/`PostUp`/...) are not supported; OPNsense has no API equivalent.
|
||||
- DNS settings pushed to clients are a property of the tunnel in OPNsense and are not managed by the portal.
|
||||
- `PingAddresses` is not implemented.
|
||||
|
||||
Reference in New Issue
Block a user