Commit Graph

252 Commits

Author SHA1 Message Date
Christoph Haas b6a27616c1
allow setting a base-path for the web UI and API (#583) 2025-12-13 00:25:52 +01:00
h44z 8cc937b031
Custom templates (#594)
* allow custom mail templates (#533)

* allow to override embedded frontend (#533)
2025-12-10 23:10:43 +01:00
rwjack 54ca1d8aed
Add Pfsense backend (ALPHA) (#585)
* Add pfSense backend domain types and configuration

This adds the necessary domain types and configuration structures
for the pfSense backend support. Includes PfsenseInterfaceExtras and
PfsensePeerExtras structs, and the BackendPfsense configuration
with API URL, key, and timeout settings.

* Add low-level pfSense REST API client

Implements the HTTP client for interacting with the pfSense REST API.
Handles authentication via X-API-Key header, request/response parsing,
and error handling. Uses the pfSense REST API v2 endpoints as documented
at https://pfrest.org/.

* Implement pfSense WireGuard controller

This implements the InterfaceController interface for pfSense firewalls.
Handles WireGuard tunnel and peer management through the pfSense REST API.
Includes proper filtering of peers by interface (since API filtering doesn't
work) and parsing of the allowedips array structure with address/mask fields.

* Register pfSense controllers and update configuration

Registers the pfSense backend controllers in the controller manager
and adds example configuration to config.yml.sample. Also updates
README to mention pfSense backend support.

* Fix peer filtering and allowedips parsing for pfSense backend

The pfSense REST API doesn't support filtering peers by interface
via query parameters, so all peers are returned regardless of the
filter. This caused peers from all interfaces to be randomly assigned
to a single interface in wg-portal.

Additionally, the API returns allowedips as an array of objects with
"address" and "mask" fields instead of a comma-separated string,
which caused parsing failures.

Changes:
- Remove API filter from GetPeers() since it doesn't work
- Add client-side filtering by checking the "tun" field in peer responses
- Update convertWireGuardPeer() to parse allowedips array structure
- Add parseAddressArray() helper for parsing address objects
- Attempt to fetch interface addresses from /tunnel/{id}/address endpoint
  (endpoint may not be available in all pfSense versions)
- Add debug logging for peer filtering and address loading operations

Note: Interface addresses may still be empty if the address endpoint
is not available. Public Endpoint and Default DNS Servers are typically
configured manually in wg-portal as the pfSense API doesn't provide
this information.

* Extract endpoint, DNS, and peer names from pfSense peer data

The pfSense API provides endpoint, port, and description (descr) fields
in peer responses that can be used to populate interface defaults and
peer display names.

Changes:
- Extract endpoint and port from peers and combine them properly
- Fix peer name/description extraction to check "descr" field first
  (pfSense API uses "descr" instead of "description" or "comment")
- Add extractPfsenseDefaultsFromPeers() helper to extract common
  endpoint and DNS from peers during interface import
- Set PeerDefEndpoint and PeerDefDnsStr from peer data for pfSense
  backends during interface import
- Use most common endpoint/DNS values when multiple peers are present

* Fix interface display name to use descr field from pfSense API

The pfSense API uses "descr" field for tunnel descriptions, not
"description" or "comment". Updated convertWireGuardInterface()
to check "descr" first so that tunnel descriptions (e.g., "HQ VPN")
are displayed in the UI instead of just the tunnel name (e.g., "tun_wg0").

* Remove calls to non-working tunnel and peer detail endpoints

The pfSense REST API endpoints /api/v2/vpn/wireguard/tunnel/{id}
and /api/v2/vpn/wireguard/tunnel/{id}/address don't work and were
causing log spam. Removed these calls and use only the data from
the tunnel/peer list responses.

Also removed the peer detail endpoint call that was added for
statistics collection, as it likely doesn't work either.

* Fix unused variable compilation error

Removed unused deviceId variable that was causing build failure.

* Optimize tunnel address fetching to use /tunnel?id endpoint

Instead of using the separate /tunnel/address endpoint, now query
the specific tunnel endpoint /tunnel?id={id} which includes the
addresses array in the response. This avoids unnecessary API calls
and simplifies the code.

- GetInterface() now queries /tunnel?id={id} after getting tunnel ID
- loadInterfaceData() queries /tunnel?id={id} as fallback if addresses missing
- extractAddresses() properly parses addresses array from tunnel response
- Removed /tunnel/address endpoint calls

Signed-off-by: rwjack <jack@foss.family>

* Fix URL encoding issue in tunnel endpoint queries

Use Filters in PfsenseRequestOptions instead of passing query strings
directly in the path. This prevents the ? character from being encoded
as %3F, which was causing 404 errors.

- GetInterface() now uses Filters map for id parameter
- loadInterfaceData() now uses Filters map for id parameter

Signed-off-by: rwjack <jack@foss.family>

* update backend docs for pfsense

---------

Signed-off-by: rwjack <jack@foss.family>
2025-12-09 22:33:12 +01:00
Christoph a1fcce6fde set file permissions to 0600 for the sqlite database (#579) 2025-11-23 20:33:04 +01:00
Christoph Haas 907bb0599a
fix race condition during ldap initialization (#571) 2025-11-20 18:28:20 +01:00
Christoph d759fc7dc7 allow to log raw LDAP user data (#571) 2025-11-19 16:00:11 +01:00
Isak Wertwein 8f25bef050
feat: config by environment variables (#570)
* feat: config by environment variables without config file

Signed-off-by: Isak Wertwein <isak.wertwein@gmail.com>

* string slice by environment variable

Signed-off-by: Isak Wertwein <isak.wertwein@gmail.com>

---------

Signed-off-by: Isak Wertwein <isak.wertwein@gmail.com>
2025-11-16 18:33:25 +01:00
Christoph Haas 80dc7f290a
correct enum for User-Source in api doc (#562) 2025-11-13 20:00:37 +01:00
Christoph Haas bda99464f1
fix path parameter handling in REST api (#563) 2025-11-07 23:12:36 +01:00
h44z 3d923b328e
password change UI (#543) (#548) 2025-10-15 21:11:40 +02:00
Christoph Haas f53d0b3d7f
add the possibility to debug oauth or oidc login issues (#541) 2025-10-12 15:09:40 +02:00
h44z cdf3a49801
Cleanup route handling (#542)
* mikrotik: allow to set DNS, wip: handle routes in wg-controller

* replace old route handling for local controller

* cleanup route handling for local backend

* implement route handling for mikrotik controller
2025-10-12 14:31:19 +02:00
Christoph Haas 298c9405f6
add support for sending emails to peers without linked user accounts if their user-identifier is a valid email address 2025-10-12 14:31:01 +02:00
Christoph Haas 97b6c398e8
fix incorrect handling of client mode (#537) 2025-10-03 17:30:14 +02:00
Christoph Haas cc2d1f53c4
improve logging of LDAP login process even more (#529) 2025-09-24 18:39:45 +02:00
Christoph Haas ea26e56994
fix delayed setup of external auth providers (#529) 2025-09-21 21:16:12 +02:00
h44z 61bf349813
add user's display-name to peer view (#525) (#534) 2025-09-21 13:02:12 +02:00
Christoph Haas afb38b685c
improve logging of LDAP login process (#529) 2025-09-17 22:33:54 +02:00
h44z 7cd7d13dc7
fix peer creation if custom public key is set (#523) (#528) 2025-09-15 22:54:34 +02:00
h44z 765fb09770
Mikrotik improvements (#521)
* allow to specify ignored interfaces (#514)

* only set endpoint info for "responder" peers (#516)
2025-09-09 21:43:16 +02:00
Victor LEFEBVRE b61d84ec4f
allow disabling local admin user (#515) 2025-09-08 10:39:10 +02:00
h44z 0cbca61c15
ensure that LDAP filter values are escaped (#512) 2025-09-03 19:37:34 +02:00
h44z c79a6c83a8
allow setting the DisplayName property for newly provisioned peers (#507) (#511) 2025-09-03 19:34:58 +02:00
h44z 99df4ca3cd
ensure hooks run after restart (#494) (#497) 2025-08-12 21:47:04 +02:00
h44z 9884d8c002
fix migration tool (#495) (#496) 2025-08-11 19:05:33 +02:00
h44z 112f6bfb77
Mikrotik integration (#467)
Allow MikroTik routes as WireGuard backends
2025-08-10 14:42:02 +02:00
Christoph Haas a86f83a219
ensure that deleted peers are restored once the interface is re-enabled 2025-08-10 14:18:43 +02:00
Christoph Haas c20f17cddf
fix multi-peer generation, fix prefix handling (#491) 2025-08-09 15:55:29 +02:00
Marcin Woźniak 3f76aa416f
chore(logs): added more debug logs and reformated those files using gofmt (#490) 2025-07-27 23:32:34 +02:00
Christoph Haas 1794b8653a
add retry handling for auth provider setup (#484) 2025-07-19 23:29:05 +02:00
h44z f286840964
fix oauth domain check (#474) (#476) 2025-06-29 20:00:15 +02:00
h44z edb88b5768
new webhook models (#444) (#471)
warning: existing webhook receivers need to be adapted to the new models
2025-06-29 19:49:01 +02:00
h44z 588bbca141
only execute interface hooks if the state has changed (#469) (#472) 2025-06-29 19:48:46 +02:00
h44z f08740991b
support for raw-wireguard and wg-quick style peer configurations (#441) (#473) 2025-06-29 19:47:53 +02:00
h44z dd28a8dddf
allow to hide login form (#459) (#470)
use the `hide_login_form` parameter in the `auth` settings to configure this feature
2025-06-27 13:50:38 +02:00
h44z be29abd29a
add webhook event for peer state change (#444) (#468)
* add webhook event for peer state change (#444)

new event types: connect and disconnect

example payload:

```json
{
  "event": "connect",
  "entity": "peer",
  "identifier": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=",
  "payload": {
    "PeerId": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=",
    "IsConnected": true,
    "IsPingable": false,
    "LastPing": null,
    "BytesReceived": 1860,
    "BytesTransmitted": 10824,
    "LastHandshake": "2025-06-26T23:04:33.325216659+02:00",
    "Endpoint": "10.55.66.77:33874",
    "LastSessionStart": "2025-06-26T22:50:40.10221606+02:00"
  }
}
```

* add webhook docs (#444)
2025-06-27 12:37:10 +02:00
h44z 94785c10ec
use website title in mail templates (#448) (#466)
* use website title in mail templates (#448)

* change button font color to white (#448)
2025-06-27 11:45:44 +02:00
S.J. Louw f0be66aea4
Option to limit peer count that a normal user can create (#457) 2025-06-26 20:17:45 +02:00
Christoph Haas e3b65ca337
improve logging of OAuth login issues, decrease auth-code exchange timeout (#451) 2025-06-10 17:51:45 +02:00
Christoph Haas 61d8aa6589
fix self-provisioned peer-generation (#452) 2025-06-08 11:17:04 +02:00
Christoph Haas 7fd2bbad02
Merge branch 'passkey_support' 2025-05-17 19:22:44 +02:00
Christoph Haas e9005b1b90
add minimum password length check 2025-05-16 09:55:35 +02:00
Christoph Haas 8816165260
fix duplicate creation of default peer (#437) 2025-05-15 17:59:00 +02:00
Christoph Haas ab9995350f
sanitize external_url, remove trailing slashes 2025-05-15 17:58:34 +02:00
Christoph Haas 1394be2341 add webauthn (passkey) support 2025-05-12 22:53:43 +02:00
Christoph Haas 6a96925be7 add API endpoints to prepare fresh interfaces and peers (#432) 2025-05-09 16:19:36 +02:00
Vladimir Dombrovski 3eb84f0ee9
Enable allowed_domains in oauth and oidc providers (#416)
* Enable allowed_domains in oauth and oidc providers

Signed-off-by: Vladimir DOMBROVSKI <vladimir.dombrovski@bso.co>

* Domain check code cleanup

* Run gofmt on domain validation code

---------

Signed-off-by: Vladimir DOMBROVSKI <vladimir.dombrovski@bso.co>
2025-05-05 18:26:19 +02:00
Christoph Haas b4aa6f8ef3 fix gorm error if no encryption is used (#427) 2025-05-04 17:42:13 +02:00
Christoph Haas 923d4a6188 docs: add reverse-proxy example, improve docker examples, fix slow_query_threshold documentation; feat: allow config.yml and config.yaml as configuration files 2025-05-03 22:21:56 +02:00
Christoph Haas b9c4ca04f5 allow to encrypt keys in db, add browser-only key generator, add hints that private keys are stored on the server (#420) 2025-05-02 18:48:35 +02:00