diff --git a/master/documentation/configuration/examples/index.html b/master/documentation/configuration/examples/index.html index 43dfad0..e7f4d37 100644 --- a/master/documentation/configuration/examples/index.html +++ b/master/documentation/configuration/examples/index.html @@ -10,11 +10,11 @@ # default backend decides where new interfaces are created default: mikrotik - # A prefix for resolvconf. Usually it is "tun.". If you are using systemd, the prefix should be empty. - local_resolvconf_prefix: "tun." + # A prefix for resolvconf. Usually it is "tun.". If you are using systemd, the prefix should be empty. + local_resolvconf_prefix: "tun." mikrotik: - - id: mikrotik # unique id, not "local" + - id: mikrotik # unique id, not "local" display_name: RouterOS RB5009 # optional nice name api_url: https://10.10.10.10/rest api_user: wgportal @@ -78,7 +78,7 @@ registration_enabled: true # Restrict interface access based on LDAP filters interface_filter: - wg0: "(memberOf=CN=VPNUsers,OU=Groups,DC=COMPANY,DC=LOCAL)" + wg0: "(memberOf=CN=VPNUsers,OU=Groups,DC=COMPANY,DC=LOCAL)" log_user_info: true

OpenID Connect (OIDC) Authentication

# ... (basic configuration)
 
@@ -89,11 +89,11 @@
     - provider_name: azure
       display_name: Login with</br>Entra ID
       registration_enabled: true
-      base_url: "https://login.microsoftonline.com/${AZURE_TENANT_ID}/v2.0"
-      client_id: "${AZURE_CLIENT_ID}"
-      client_secret: "${AZURE_CLIENT_SECRET}"
+      base_url: "https://login.microsoftonline.com/${AZURE_TENANT_ID}/v2.0"
+      client_id: "${AZURE_CLIENT_ID}"
+      client_secret: "${AZURE_CLIENT_SECRET}"
       allowed_domains:
-        - "outlook.com"
+        - "outlook.com"
       extra_scopes:
         - profile
         - email
diff --git a/master/documentation/configuration/overview/index.html b/master/documentation/configuration/overview/index.html
index 48bc524..4152866 100644
--- a/master/documentation/configuration/overview/index.html
+++ b/master/documentation/configuration/overview/index.html
@@ -1,7 +1,7 @@
  Overview - WireGuard Portal     
Skip to content

Overview

This page provides an overview of all available configuration options for WireGuard Portal.

You can supply these configurations in a YAML file when starting the Portal. The path of the configuration file defaults to config/config.yaml (or config/config.yml) in the working directory of the executable.
It is possible to override the configuration filepath using the environment variable WG_PORTAL_CONFIG. For example: WG_PORTAL_CONFIG=/etc/wg-portal/config.yaml ./wg-portal.
Also, environment variable substitution in the config file is supported. Refer to the syntax.

Configuration examples are available on the Examples page.

Default configuration
core:
   admin_user: admin@wgportal.local
   admin_password: wgportal-default
-  admin_api_token: ""
+  admin_api_token: ""
   disable_admin_user: false
   editable_keys: true
   create_default_peer: false
@@ -25,7 +25,7 @@
   start_cidr_v4: 10.11.12.0/24
   start_cidr_v6: fdfd:d3ad:c0de:1234::0/64
   use_ip_v6: true
-  config_storage_path: ""
+  config_storage_path: ""
   expiry_check_interval: 15m
   rule_prio_offset: 20000
   route_table_offset: 20000
@@ -34,10 +34,10 @@
 
 database:
   debug: false
-  slow_query_threshold: "0"
+  slow_query_threshold: "0"
   type: sqlite
   dsn: data/sqlite.db
-  encryption_passphrase: ""
+  encryption_passphrase: ""
 
 statistics:
   use_ping_checks: true
@@ -55,13 +55,13 @@
   port: 25
   encryption: none
   cert_validation: true
-  username: ""
-  password: ""
+  username: ""
+  password: ""
   auth_type: plain
   from: Wireguard Portal <noreply@wireguard.local>
   link_only: false
   allow_peer_email: false
-  templates_path: ""
+  templates_path: ""
 
 auth:
   oidc: []
@@ -75,7 +75,7 @@
 web:
   listening_address: :8888
   external_url: http://localhost:8888
-  base_path: ""
+  base_path: ""
   site_company_name: WireGuard Portal
   site_title: WireGuard Portal
   session_identifier: wgPortalSession
@@ -83,19 +83,19 @@
   csrf_secret: extremely_secret
   request_logging: false
   expose_host_info: false
-  cert_file: ""
-  key_File: ""
-  frontend_filepath: ""
+  cert_file: ""
+  key_File: ""
+  frontend_filepath: ""
 
 webhook:
-  url: ""
-  authentication: ""
+  url: ""
+  authentication: ""
   timeout: 10s
 

Below you will find sections like core, backend, advanced, database, statistics, mail, auth, web and webhook.
Each section describes the individual configuration keys, their default values, and a brief explanation of their purpose.


Core

These are the primary configuration options that control fundamental WireGuard Portal behavior. More advanced options are found in the subsequent Advanced section.

admin_user

  • Default: admin@wgportal.local
  • Environment Variable: WG_PORTAL_CORE_ADMIN_USER
  • Description: The administrator user. This user will be created as a default admin if it does not yet exist.

admin_password

  • Default: wgportal-default
  • Environment Variable: WG_PORTAL_CORE_ADMIN_PASSWORD
  • Description: The administrator password. The default password should be changed immediately!
  • Important: The password should be strong and secure. The minimum password length is specified in auth.min_password_length. By default, it is 16 characters.

disable_admin_user

  • Default: false
  • Environment Variable: WG_PORTAL_CORE_DISABLE_ADMIN_USER
  • Description: If true, no admin user is created. This is useful if you plan to manage users exclusively through external authentication providers such as LDAP or OAuth.

admin_api_token

  • Default: (empty)
  • Environment Variable: WG_PORTAL_CORE_ADMIN_API_TOKEN
  • Description: An API token for the admin user. If a token is provided, the REST API can be accessed using this token. If empty, the API is initially disabled for the admin user.

editable_keys

  • Default: true
  • Environment Variable: WG_PORTAL_CORE_EDITABLE_KEYS
  • Description: Allow editing of WireGuard key-pairs directly in the UI.

create_default_peer (deprecated)

  • Default: false
  • Environment Variable: WG_PORTAL_CORE_CREATE_DEFAULT_PEER
  • Description: DEPRECATED in favor of create_default_peer_on_login. If set to true, this option is equivalent to enabling create_default_peer_on_login. It will be removed in a future release (2.4).

create_default_peer_on_creation (deprecated)

create_default_peer_on_login

  • Default: false
  • Environment Variable: WG_PORTAL_CORE_CREATE_DEFAULT_PEER
  • Description: If a user logs in for the first time with no existing peers, automatically create a new WireGuard peer for all server interfaces where the "Create default peer" flag is set.
  • Important: This option is only effective for interfaces where the "Create default peer" flag is set (via the UI).

create_default_peer_on_user_creation

  • Default: false
  • Environment Variable: WG_PORTAL_CORE_CREATE_DEFAULT_PEER_ON_USER_CREATION
  • Description: If a new user is created (e.g., through LDAP sync or registration) and has no peers, automatically create a new WireGuard peer for all server interfaces where the "Create default peer" flag is set.
  • Important: This option is only effective for interfaces where the "Create default peer" flag is set (via the UI).

create_default_peer_on_interface_creation

  • Default: false
  • Environment Variable: WG_PORTAL_CORE_CREATE_DEFAULT_PEER_ON_INTERFACE_CREATION
  • Description: When a new server interface is created with the "Create default peer" flag set, automatically create a default WireGuard peer on that interface for every existing user who does not yet have a peer on it.
  • Important: This option is only effective for interfaces where the "Create default peer" flag is set (via the UI).

re_enable_peer_after_user_enable

  • Default: true
  • Environment Variable: WG_PORTAL_CORE_RE_ENABLE_PEER_AFTER_USER_ENABLE
  • Description: Re-enable all peers that were previously disabled if the associated user is re-enabled.

delete_peer_after_user_deleted

  • Default: false
  • Environment Variable: WG_PORTAL_CORE_DELETE_PEER_AFTER_USER_DELETED
  • Description: If a user is deleted, remove all linked peers. Otherwise, peers remain but are disabled.

self_provisioning_allowed

  • Default: false
  • Environment Variable: WG_PORTAL_CORE_SELF_PROVISIONING_ALLOWED
  • Description: Allow registered (non-admin) users to self-provision peers from their profile page.

import_existing

  • Default: true
  • Environment Variable: WG_PORTAL_CORE_IMPORT_EXISTING
  • Description: On startup, import existing WireGuard interfaces and peers into WireGuard Portal.

restore_state

  • Default: true
  • Environment Variable: WG_PORTAL_CORE_RESTORE_STATE
  • Description: Restore the WireGuard interface states (up/down) that existed before WireGuard Portal started.

Backend

Configuration options for the WireGuard backend, which manages the WireGuard interfaces and peers. 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.

rekey_timeout_interval

  • Default: 180s
  • Environment Variable: WG_PORTAL_BACKEND_REKEY_TIMEOUT_INTERVAL
  • Description: The interval after which a WireGuard peer is considered disconnected if no handshake updates are received. This corresponds to the WireGuard rekey timeout setting of 120 seconds plus a 60-second buffer to account for latency or retry handling. Uses Go duration format (e.g., 10s, 1m). If omitted, a default of 180 seconds is used.

local_resolvconf_prefix

  • Default: tun.
  • Environment Variable: WG_PORTAL_BACKEND_LOCAL_RESOLVCONF_PREFIX
  • Description: Interface name prefix for WireGuard interfaces on the local system which is used to configure DNS servers with resolvconf. It depends on the resolvconf implementation you are using, most use a prefix of tun., but some have an empty prefix (e.g., systemd).

ignored_local_interfaces

  • Default: (empty)
  • Environment Variable: WG_PORTAL_BACKEND_IGNORED_LOCAL_INTERFACES (comma-separated values)
  • Description: A list of interface names to exclude when enumerating local interfaces. This is useful if you want to prevent certain interfaces from being imported from the local system.

Mikrotik

The mikrotik array contains a list of MikroTik backend definitions. Each entry describes how to connect to a MikroTik RouterOS instance that hosts WireGuard interfaces.

Below are the properties for each entry inside backend.mikrotik:

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 MikroTik REST API, including scheme and path, e.g., https://10.10.10.10:8729/rest.

api_user

  • Default: (empty)
  • Description: Username for authenticating against the MikroTik API. Ensure that the user has sufficient permissions to manage WireGuard interfaces and peers.

api_password

  • Default: (empty)
  • Description: Password for the specified API user.

api_verify_tls

  • Default: false
  • Description: Whether to verify the TLS certificate of the MikroTik 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 MikroTik device. Uses Go duration format (e.g., 10s, 1m). If omitted, a default of 30 seconds is used.

concurrency

  • Default: 5
  • Description: Maximum number of concurrent API requests the backend will issue when enumerating interfaces and their details. If 0 or negative, a sane default of 5 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 MikroTik device.

debug

  • Default: false
  • Description: Enable verbose debug logging for the MikroTik backend.

For more details on configuring the MikroTik backend, see the Backends documentation.


Advanced

Additional or more specialized configuration options for logging and interface creation details.

log_level

  • Default: info
  • Environment Variable: WG_PORTAL_ADVANCED_LOG_LEVEL
  • Description: The log level used by the application. Valid options are: trace, debug, info, warn, error.

log_pretty

  • Default: false
  • Environment Variable: WG_PORTAL_ADVANCED_LOG_PRETTY
  • Description: If true, log messages are colorized and formatted for readability (pretty-print).

log_json

  • Default: false
  • Environment Variable: WG_PORTAL_ADVANCED_LOG_JSON
  • Description: If true, log messages are structured in JSON format.

start_listen_port

  • Default: 51820
  • Environment Variable: WG_PORTAL_ADVANCED_START_LISTEN_PORT
  • Description: The first port to use when automatically creating new WireGuard interfaces.

start_cidr_v4

  • Default: 10.11.12.0/24
  • Environment Variable: WG_PORTAL_ADVANCED_START_CIDR_V4
  • Description: The initial IPv4 subnet to use when automatically creating new WireGuard interfaces.

start_cidr_v6

  • Default: fdfd:d3ad:c0de:1234::0/64
  • Environment Variable: WG_PORTAL_ADVANCED_START_CIDR_V6
  • Description: The initial IPv6 subnet to use when automatically creating new WireGuard interfaces.

use_ip_v6

  • Default: true
  • Environment Variable: WG_PORTAL_ADVANCED_USE_IP_V6
  • Description: Enable or disable IPv6 support.

config_storage_path

  • Default: (empty)
  • Environment Variable: WG_PORTAL_ADVANCED_CONFIG_STORAGE_PATH
  • Description: Path to a directory where wg-quick style configuration files will be stored (if you need local filesystem configs).

expiry_check_interval

  • Default: 15m
  • Environment Variable: WG_PORTAL_ADVANCED_EXPIRY_CHECK_INTERVAL
  • Description: Interval after which existing peers are checked if they are expired. Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration.

rule_prio_offset

  • Default: 20000
  • Environment Variable: WG_PORTAL_ADVANCED_RULE_PRIO_OFFSET
  • Description: Offset for IP route rule priorities when configuring routing.

route_table_offset

  • Default: 20000
  • Environment Variable: WG_PORTAL_ADVANCED_ROUTE_TABLE_OFFSET
  • Description: Offset for IP route table IDs when configuring routing.

api_admin_only

  • Default: true
  • Environment Variable: WG_PORTAL_ADVANCED_API_ADMIN_ONLY
  • Description: If true, the public REST API is accessible only to admin users. The API docs live at /api/v1/doc.html.

limit_additional_user_peers

  • Default: 0
  • Environment Variable: WG_PORTAL_ADVANCED_LIMIT_ADDITIONAL_USER_PEERS
  • Description: Limit additional peers a normal user can create. 0 means unlimited.

Database

Configuration for the underlying database used by WireGuard Portal. Supported databases include SQLite, MySQL, Microsoft SQL Server, and Postgres.

If sensitive values (like private keys) should be stored in an encrypted format, set the encryption_passphrase option.

debug

  • Default: false
  • Environment Variable: WG_PORTAL_DATABASE_DEBUG
  • Description: If true, logs all database statements (verbose).

slow_query_threshold

  • Default: "0"
  • Environment Variable: WG_PORTAL_DATABASE_SLOW_QUERY_THRESHOLD
  • Description: A time threshold (e.g., 100ms) above which queries are considered slow and logged as warnings. If zero, slow query logging is disabled. Format uses s, ms for seconds, milliseconds, see time.ParseDuration. The value must be a string.

type

  • Default: sqlite
  • Environment Variable: WG_PORTAL_DATABASE_TYPE
  • Description: The database type. Valid options: sqlite, mssql, mysql, postgres.

dsn

  • Default: data/sqlite.db
  • Environment Variable: WG_PORTAL_DATABASE_DSN
  • Description: The Data Source Name (DSN) for connecting to the database.
    For example:
    user:pass@tcp(1.2.3.4:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local
     

encryption_passphrase

  • Default: (empty)
  • Environment Variable: WG_PORTAL_DATABASE_ENCRYPTION_PASSPHRASE
  • Description: Passphrase for encrypting sensitive values such as private keys in the database. Encryption is only applied if this passphrase is set. Important: Once you enable encryption by setting this passphrase, you cannot disable it or change it afterward. New or updated records will be encrypted; existing data remains in plaintext until it’s next modified.

Statistics

Controls how WireGuard Portal collects and reports usage statistics, including ping checks and Prometheus metrics.

use_ping_checks

  • Default: true
  • Environment Variable: WG_PORTAL_STATISTICS_USE_PING_CHECKS
  • Description: Enable periodic ping checks to verify that peers remain responsive.

ping_check_workers

  • Default: 10
  • Environment Variable: WG_PORTAL_STATISTICS_PING_CHECK_WORKERS
  • Description: Number of parallel worker processes for ping checks.

ping_unprivileged

  • Default: false
  • Environment Variable: WG_PORTAL_STATISTICS_PING_UNPRIVILEGED
  • Description: If false, ping checks run without root privileges. This is currently considered BETA.

ping_check_interval

  • Default: 1m
  • Environment Variable: WG_PORTAL_STATISTICS_PING_CHECK_INTERVAL
  • Description: Interval between consecutive ping checks for all peers. Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration.

data_collection_interval

  • Default: 1m
  • Environment Variable: WG_PORTAL_STATISTICS_DATA_COLLECTION_INTERVAL
  • Description: Interval between data collection cycles (bytes sent/received, handshake times, etc.). Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration.

collect_interface_data

  • Default: true
  • Environment Variable: WG_PORTAL_STATISTICS_COLLECT_INTERFACE_DATA
  • Description: If true, collects interface-level data (bytes in/out) for monitoring and statistics.

collect_peer_data

  • Default: true
  • Environment Variable: WG_PORTAL_STATISTICS_COLLECT_PEER_DATA
  • Description: If true, collects peer-level data (bytes, last handshake, endpoint, etc.).

collect_audit_data

  • Default: true
  • Environment Variable: WG_PORTAL_STATISTICS_COLLECT_AUDIT_DATA
  • Description: If true, logs certain portal events (such as user logins) to the database.

listening_address

  • Default: :8787
  • Environment Variable: WG_PORTAL_STATISTICS_LISTENING_ADDRESS
  • Description: Address and port for the integrated Prometheus metric server (e.g., :8787 or 127.0.0.1:8787).

Mail

Options for configuring email notifications or sending peer configurations via email. By default, emails will only be sent to peers that have a valid user record linked. To send emails to all peers that have a valid email-address as user-identifier, set allow_peer_email to true.

host

  • Default: 127.0.0.1
  • Environment Variable: WG_PORTAL_MAIL_HOST
  • Description: Hostname or IP of the SMTP server.

port

  • Default: 25
  • Environment Variable: WG_PORTAL_MAIL_PORT
  • Description: Port number for the SMTP server.

encryption

  • Default: none
  • Environment Variable: WG_PORTAL_MAIL_ENCRYPTION
  • Description: SMTP encryption type. Valid values: none, tls, starttls.

cert_validation

  • Default: true
  • Environment Variable: WG_PORTAL_MAIL_CERT_VALIDATION
  • Description: If true, validate the SMTP server certificate (relevant if encryption = tls).

username

  • Default: (empty)
  • Environment Variable: WG_PORTAL_MAIL_USERNAME
  • Description: Optional SMTP username for authentication.

password

  • Default: (empty)
  • Environment Variable: WG_PORTAL_MAIL_PASSWORD
  • Description: Optional SMTP password for authentication.

auth_type

  • Default: plain
  • Environment Variable: WG_PORTAL_MAIL_AUTH_TYPE
  • Description: SMTP authentication type. Valid values: plain, login, crammd5.

from

  • Default: Wireguard Portal <noreply@wireguard.local>
  • Environment Variable: WG_PORTAL_MAIL_FROM
  • Description: The default "From" address when sending emails.
  • Default: false
  • Environment Variable: WG_PORTAL_MAIL_LINK_ONLY
  • Description: If true, emails only contain a link to WireGuard Portal, rather than attaching the full configuration.

allow_peer_email

  • Default: false
  • Environment Variable: WG_PORTAL_MAIL_ALLOW_PEER_EMAIL
  • Description: If true, and a peer has no valid user record linked, but the user-identifier of the peer is a valid email address, emails will be sent to that email address. If false, and the peer has no valid user record linked, emails will not be sent. If a peer has linked a valid user, the email address is always taken from the user record.

templates_path

  • Default: (empty)
  • Environment Variable: WG_PORTAL_MAIL_TEMPLATES_PATH
  • Description: Path to the email template files that override embedded templates. Check usage documentation for an example.`

Auth

WireGuard Portal supports multiple authentication strategies, including OpenID Connect (oidc), OAuth (oauth), Passkeys (webauthn) and LDAP (ldap). Each can have multiple providers configured. Below are the relevant keys.

Some core authentication options are shared across all providers, while others are specific to each provider type.

min_password_length

  • Default: 16
  • Environment Variable: WG_PORTAL_AUTH_MIN_PASSWORD_LENGTH
  • Description: Minimum password length for local authentication. This is not enforced for LDAP authentication. The default admin password strength is also enforced by this setting.
  • Important: The password should be strong and secure. It is recommended to use a password with at least 16 characters, including uppercase and lowercase letters, numbers, and special characters.

hide_login_form

  • Default: false
  • Environment Variable: WG_PORTAL_AUTH_HIDE_LOGIN_FORM
  • Description: If true, the login form is hidden and only the OIDC, OAuth, LDAP, or WebAuthn providers are shown. This is useful if you want to enforce a specific authentication method. If no social login providers are configured, the login form is always shown, regardless of this setting.
  • Important: You can still access the login form by adding the ?all query parameter to the login URL (e.g. https://wg.portal/#/login?all).

OIDC

The oidc array contains a list of OpenID Connect providers. Below are the properties for each OIDC provider entry inside auth.oidc:

provider_name

  • Default: (empty)
  • Description: A unique name for this provider. Must not conflict with other providers. This name is used to derive the callback URL for the OIDC provider: <external_url>/api/v0/auth/login/<provider_name>/callback.

display_name

  • Default: (empty)
  • Description: A user-friendly name shown on the login page (e.g., "Login with Google").

base_url

  • Default: (empty)
  • Description: The OIDC provider’s base URL (e.g., https://accounts.google.com).

client_id

  • Default: (empty)
  • Description: The OAuth client ID from the OIDC provider.

client_secret

  • Default: (empty)
  • Description: The OAuth client secret from the OIDC provider.

extra_scopes

  • Default: (empty)
  • Description: A list of additional OIDC scopes (e.g., profile, email).

allowed_domains

  • Default: (empty)
  • Description: A list of allowlisted domains. Only users with email addresses in these domains can log in or register. This is useful for restricting access to specific organizations or groups.

allowed_user_groups

  • Default: (empty)
  • Description: A list of allowlisted user groups. If configured, at least one entry in the mapped user_groups claim must match one of these values.

field_map

  • Default: (empty)
  • Description: Maps OIDC claims to WireGuard Portal user fields.
  • Available fields: user_identifier, email, firstname, lastname, phone, department, is_admin, user_groups.

    Field Typical OIDC Claim Explanation
    user_identifier sub or preferred_username A unique identifier for the user. Often the OIDC sub claim is used because it’s guaranteed to be unique for the user within the IdP. Some providers also support preferred_username if it’s unique.
    email email The user’s email address as provided by the IdP. Not always verified, depending on IdP settings.
    firstname given_name The user’s first name, typically provided by the IdP in the given_name claim.
    lastname family_name The user’s last (family) name, typically provided by the IdP in the family_name claim.
    phone phone_number The user’s phone number. This may require additional scopes/permissions from the IdP to access.
    department Custom claim (e.g., department) If the IdP can provide organizational data, it may store it in a custom claim. Adjust accordingly (e.g., department, org, or another attribute).
    is_admin Custom claim or derived role If the IdP returns a role or admin flag, you can map that to is_admin. Often this is managed through custom claims or group membership.
    user_groups groups or another custom claim A list of group memberships for the user. Some IdPs provide groups out of the box; others require custom claims or directory lookups.

admin_mapping

  • Default: (empty)
  • Description: WgPortal can grant a user admin rights by matching the value of the is_admin claim against a regular expression. Alternatively, a regular expression can be used to check if a user is member of a specific group listed in the user_group claim. The regular expressions are defined in admin_value_regex and admin_group_regex.
    • admin_value_regex: A regular expression to match the is_admin claim. By default, this expression matches the string "true" (^true$).
    • admin_group_regex: A regular expression to match the user_groups claim. Each entry in the user_groups claim is checked against this regex.
      • To identify which claim to match against, set log_level: debug and reload the config. Log in with the intended admin account and inspect the logs for the OIDC user info payload. If the required claim is missing it must be added by the OIDC provider. If it is present, use its value as the pattern for admin_group_regex.

registration_enabled

  • Default: false
  • Description: If true, a new user will be created in WireGuard Portal if not already present.

log_user_info

  • Default: false
  • Description: If true, OIDC user data is logged at the trace level upon login (for debugging).

log_sensitive_info

  • Default: false
  • Description: If true, sensitive OIDC user data, such as tokens and raw responses, will be logged at the trace level upon login (for debugging).
  • Important: Keep this setting disabled in production environments! Remove logs once you finished debugging authentication issues.

use_pkce

  • Default: true
  • Description: If true, Proof Key for Code Exchange (PKCE) is used for the OIDC authorization code flow. A fresh code_verifier is generated per login request, the matching code_challenge is sent with the authorization request, and the code_verifier is included in the token exchange. Set to false only for providers that do not support PKCE.

pkce_method

  • Default: S256
  • Description: PKCE challenge method to use when use_pkce is enabled. Supported values are S256 and plain. S256 is recommended; use plain only for providers that explicitly require it.

logout_idp_session

  • Default: true
  • Description: If true (default), WireGuard Portal will redirect the user to the OIDC provider's end_session_endpoint after local logout, terminating the session at the IdP as well. Set to false to only invalidate the local WireGuard Portal session without touching the IdP session.

OAuth

The oauth array contains a list of plain OAuth2 providers. Below are the properties for each OAuth provider entry inside auth.oauth:

provider_name

  • Default: (empty)
  • Description: A unique name for this provider. Must not conflict with other providers. This name is used to derive the callback URL for the OAuth provider: <external_url>/api/v0/auth/login/<provider_name>/callback.

display_name

  • Default: (empty)
  • Description: A user-friendly name shown on the login page.

client_id

  • Default: (empty)
  • Description: The OAuth client ID for the provider.

client_secret

  • Default: (empty)
  • Description: The OAuth client secret for the provider.

auth_url

  • Default: (empty)
  • Description: URL of the authentication endpoint.

token_url

  • Default: (empty)
  • Description: URL of the token endpoint.

user_info_url

  • Default: (empty)
  • Description: URL of the user information endpoint.

scopes

  • Default: (empty)
  • Description: A list of OAuth scopes.

allowed_domains

  • Default: (empty)
  • Description: A list of allowlisted domains. Only users with email addresses in these domains can log in or register. This is useful for restricting access to specific organizations or groups.

allowed_user_groups

  • Default: (empty)
  • Description: A list of allowlisted user groups. If configured, at least one entry in the mapped user_groups claim must match one of these values.

field_map

  • Default: (empty)
  • Description: Maps OAuth attributes to WireGuard Portal fields.
  • Available fields: user_identifier, email, firstname, lastname, phone, department, is_admin, user_groups.

    Field Typical Claim Explanation
    user_identifier sub or preferred_username A unique identifier for the user. Often the OIDC sub claim is used because it’s guaranteed to be unique for the user within the IdP. Some providers also support preferred_username if it’s unique.
    email email The user’s email address as provided by the IdP. Not always verified, depending on IdP settings.
    firstname given_name The user’s first name, typically provided by the IdP in the given_name claim.
    lastname family_name The user’s last (family) name, typically provided by the IdP in the family_name claim.
    phone phone_number The user’s phone number. This may require additional scopes/permissions from the IdP to access.
    department Custom claim (e.g., department) If the IdP can provide organizational data, it may store it in a custom claim. Adjust accordingly (e.g., department, org, or another attribute).
    is_admin Custom claim or derived role If the IdP returns a role or admin flag, you can map that to is_admin. Often this is managed through custom claims or group membership.
    user_groups groups or another custom claim A list of group memberships for the user. Some IdPs provide groups out of the box; others require custom claims or directory lookups.

admin_mapping

  • Default: (empty)
  • Description: WgPortal can grant a user admin rights by matching the value of the is_admin claim against a regular expression. Alternatively, a regular expression can be used to check if a user is member of a specific group listed in the user_group claim. The regular expressions are defined in admin_value_regex and admin_group_regex.
  • admin_value_regex: A regular expression to match the is_admin claim. By default, this expression matches the string "true" (^true$).
  • admin_group_regex: A regular expression to match the user_groups claim. Each entry in the user_groups claim is checked against this regex.

registration_enabled

  • Default: false
  • Description: If true, new users are created automatically on successful login.

log_user_info

  • Default: false
  • Description: If true, logs user info at the trace level upon login.

log_sensitive_info

  • Default: false
  • Description: If true, sensitive OIDC user data, such as tokens and raw responses, will be logged at the trace level upon login (for debugging).
  • Important: Keep this setting disabled in production environments! Remove logs once you finished debugging authentication issues.

use_pkce

  • Default: true
  • Description: If true, Proof Key for Code Exchange (PKCE) is used for the OIDC authorization code flow. A fresh code_verifier is generated per login request, the matching code_challenge is sent with the authorization request, and the code_verifier is included in the token exchange. Set to false only for providers that do not support PKCE.

pkce_method

  • Default: S256
  • Description: PKCE challenge method to use when use_pkce is enabled. Supported values are S256 and plain. S256 is recommended; use plain only for providers that explicitly require it.

LDAP

The ldap array contains a list of LDAP authentication providers. Below are the properties for each LDAP provider entry inside auth.ldap:

provider_name

  • Default: (empty)
  • Description: A unique name for this provider. Must not conflict with other providers.

url

  • Default: (empty)
  • Description: The LDAP server URL (e.g., ldap://srv-ad01.company.local:389).

start_tls

  • Default: false
  • Description: If true, use STARTTLS to secure the LDAP connection.

cert_validation

  • Default: false
  • Description: If true, validate the LDAP server’s TLS certificate.

tls_certificate_path

  • Default: (empty)
  • Description: Path to a TLS certificate if needed for LDAP connections.

tls_key_path

  • Default: (empty)
  • Description: Path to the corresponding TLS certificate key.

base_dn

  • Default: (empty)
  • Description: The base DN for user searches (e.g., DC=COMPANY,DC=LOCAL).

bind_user

  • Default: (empty)
  • Description: The bind user for LDAP (e.g., company\\ldap_wireguard or ldap_wireguard@company.local).

bind_pass

  • Default: (empty)
  • Description: The bind password for LDAP authentication.

field_map

  • Default: (empty)
  • Description: Maps LDAP attributes to WireGuard Portal fields.

    • Available fields: user_identifier, email, firstname, lastname, phone, department, memberof.
    WireGuard Portal Field Typical LDAP Attribute Short Description
    user_identifier sAMAccountName / uid Uniquely identifies the user within the LDAP directory.
    email mail / userPrincipalName Stores the user's primary email address.
    firstname givenName Contains the user's first (given) name.
    lastname sn Contains the user's last (surname) name.
    phone telephoneNumber / mobile Holds the user's phone or mobile number.
    department departmentNumber / ou Specifies the department or organizational unit of the user.
    memberof memberOf Lists the groups and roles to which the user belongs.

login_filter

  • Default: (empty)
  • Description: An LDAP filter to restrict which users can log in. Use {{login_identifier}} to insert the username. For example:
    (&(objectClass=organizationalPerson)(mail={{login_identifier}})(!userAccountControl:1.2.840.113556.1.4.803:=2))
     
  • Important: The login_filter must always be a valid LDAP filter. It should at most return one user. If the filter returns multiple or no users, the login will fail.

interface_filter

  • Default: (empty)
  • Description: A map of LDAP filters to restrict access to specific WireGuard interfaces. The map keys are the interface identifiers (e.g., wg0), and the values are LDAP filters. Only users matching the filter will be allowed to provision peers for the respective interface. For example:
    interface_filter:
    -  wg0: "(memberOf=CN=VPNUsers,OU=Groups,DC=COMPANY,DC=LOCAL)"
    -  wg1: "(description=special-access)"
    +  wg0: "(memberOf=CN=VPNUsers,OU=Groups,DC=COMPANY,DC=LOCAL)"
    +  wg1: "(description=special-access)"
     

admin_group

  • Default: (empty)
  • Description: A specific LDAP group whose members are considered administrators in WireGuard Portal. For example:
    CN=WireGuardAdmins,OU=Some-OU,DC=YOURDOMAIN,DC=LOCAL
     

sync_interval

  • Default: (empty)
  • Description: How frequently (in duration, e.g. 30m) to synchronize users from LDAP. Empty or 0 disables sync. Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration. Only users that match the sync_filter are synchronized, if disable_missing is true, users not found in LDAP are disabled.

sync_filter

  • Default: (empty)
  • Description: An LDAP filter to select which users get synchronized into WireGuard Portal. For example:
    (&(objectClass=organizationalPerson)(!userAccountControl:1.2.840.113556.1.4.803:=2)(mail=*))
     

sync_log_user_info

  • Default: false
  • Description: If true, logs LDAP user data at the trace level during synchronization.

disable_missing

  • Default: false
  • Description: If true, any user not found in LDAP (during sync) is disabled in WireGuard Portal.

auto_re_enable

  • Default: false
  • Description: If true, users that where disabled because they were missing (see disable_missing) will be re-enabled once they are found again.

registration_enabled

  • Default: false
  • Description: If true, new user accounts are created in WireGuard Portal upon first login.

log_user_info

  • Default: false
  • Description: If true, logs LDAP user data at the trace level upon login.

WebAuthn (Passkeys)

The webauthn section contains configuration options for WebAuthn authentication (passkeys).

enabled

  • Default: true
  • Environment Variable: WG_PORTAL_AUTH_WEBAUTHN_ENABLED
  • Description: If true, Passkey authentication is enabled. If false, WebAuthn is disabled. Users are encouraged to use Passkeys for secure authentication instead of passwords. If a passkey is registered, the password login is still available as a fallback. Ensure that the password is strong and secure.

Web

The web section contains configuration options for the web server, including the listening address, session management, and CSRF protection. It is important to specify a valid external_url for the web server, especially if you are using a reverse proxy. Without a valid external_url, the login process may fail due to CSRF protection.

listening_address

  • Default: :8888
  • Environment Variable: WG_PORTAL_WEB_LISTENING_ADDRESS
  • Description: The listening address and port for the web server (e.g., :8888 to bind on all interfaces or 127.0.0.1:8888 to bind only on the loopback interface). Ensure that access to WireGuard Portal is protected against unauthorized access, especially if binding to all interfaces.

external_url

  • Default: http://localhost:8888
  • Environment Variable: WG_PORTAL_WEB_EXTERNAL_URL
  • Description: The URL where a client can access WireGuard Portal. This URL is used for generating links in emails and for performing OAUTH redirects. The external URL must not contain a path component or trailing slash. If you want to serve WireGuard Portal on a subpath, use the base_path setting. Important: If you are using a reverse proxy, set this to the external URL of the reverse proxy, otherwise login will fail. If you access the portal via IP address, set this to the IP address of the server.

base_path

  • Default: (empty)
  • Environment Variable: WG_PORTAL_WEB_BASE_PATH
  • Description: The base path for the web server (e.g., /wgportal). By default (meaning an empty value), the portal will be served from the root path /.

site_company_name

  • Default: WireGuard Portal
  • Environment Variable: WG_PORTAL_WEB_SITE_COMPANY_NAME
  • Description: The company name that is shown at the bottom of the web frontend.

site_title

  • Default: WireGuard Portal
  • Environment Variable: WG_PORTAL_WEB_SITE_TITLE
  • Description: The title that is shown in the web frontend.

session_identifier

  • Default: wgPortalSession
  • Environment Variable: WG_PORTAL_WEB_SESSION_IDENTIFIER
  • Description: The session identifier for the web frontend.

session_secret

  • Default: very_secret
  • Environment Variable: WG_PORTAL_WEB_SESSION_SECRET
  • Description: The session secret for the web frontend.

csrf_secret

  • Default: extremely_secret
  • Environment Variable: WG_PORTAL_WEB_CSRF_SECRET
  • Description: The CSRF secret.

request_logging

  • Default: false
  • Environment Variable: WG_PORTAL_WEB_REQUEST_LOGGING
  • Description: Log all HTTP requests.

expose_host_info

  • Default: false
  • Environment Variable: WG_PORTAL_WEB_EXPOSE_HOST_INFO
  • Description: Expose the hostname and version of the WireGuard Portal server in an HTTP header. This is useful for debugging but may expose sensitive information.

cert_file

  • Default: (empty)
  • Environment Variable: WG_PORTAL_WEB_CERT_FILE
  • Description: (Optional) Path to the TLS certificate file.

key_file

  • Default: (empty)
  • Environment Variable: WG_PORTAL_WEB_KEY_FILE
  • Description: (Optional) Path to the TLS certificate key file.

frontend_filepath

  • Default: (empty)
  • Environment Variable: WG_PORTAL_WEB_FRONTEND_FILEPATH
  • Description: Optional base directory from which the web frontend is served. Check out the building documentation for more information on how to compile the frontend assets.
  • If the directory contains at least one file (recursively), these files are served at /app, overriding the embedded frontend assets.
  • If the directory is empty or does not exist on startup, the embedded frontend is copied into this directory automatically and then served.
  • If left empty, the embedded frontend is served and no files are written to disk.

Webhook

The webhook section allows you to configure a webhook that is called on certain events in WireGuard Portal. Further details can be found in the usage documentation.

url

  • Default: (empty)
  • Environment Variable: WG_PORTAL_WEBHOOK_URL
  • Description: The POST endpoint to which the webhook is sent. The URL must be reachable from the WireGuard Portal server. If the URL is empty, the webhook is disabled.

authentication

  • Default: (empty)
  • Environment Variable: WG_PORTAL_WEBHOOK_AUTHENTICATION
  • Description: The Authorization header for the webhook endpoint. The value is send as-is in the header. For example: Bearer <token>.

timeout

  • Default: 10s
  • Environment Variable: WG_PORTAL_WEBHOOK_TIMEOUT
  • Description: The timeout for the webhook request. If the request takes longer than this, it is aborted.
\ No newline at end of file diff --git a/master/documentation/getting-started/binaries/index.html b/master/documentation/getting-started/binaries/index.html index 935a609..a428147 100644 --- a/master/documentation/getting-started/binaries/index.html +++ b/master/documentation/getting-started/binaries/index.html @@ -1,6 +1,6 @@ Binaries - WireGuard Portal
Skip to content

Binaries

Starting from v2, each release includes compiled binaries for supported platforms. These binary versions can be manually downloaded and installed.

Download

Make sure that you download the correct binary for your architecture. The available binaries are:

  • wg-portal_linux_amd64 - Linux x86_64
  • wg-portal_linux_arm64 - Linux ARM 64-bit
  • wg-portal_linux_arm_v7 - Linux ARM 32-bit

Released versions

To download a specific version, replace ${WG_PORTAL_VERSION} with the desired version (or set an environment variable). All official release versions can be found on the GitHub Releases Page.

With curl:

curl -L -o wg-portal https://github.com/h44z/wg-portal/releases/download/${WG_PORTAL_VERSION}/wg-portal_linux_amd64 
 

With wget:

wget -O wg-portal https://github.com/h44z/wg-portal/releases/download/${WG_PORTAL_VERSION}/wg-portal_linux_amd64
-

with gh cli:

gh release download ${WG_PORTAL_VERSION} --repo h44z/wg-portal --output wg-portal --pattern '*amd64'
+

with gh cli:

gh release download ${WG_PORTAL_VERSION} --repo h44z/wg-portal --output wg-portal --pattern '*amd64'
 

The downloaded file will be named wg-portal and can be moved to a directory of your choice, see Install for more information.

Unreleased versions (master branch builds)

Unreleased versions can be fetched directly from the artifacts section of the GitHub Workflow.

Install

The following command can be used to install the downloaded binary (wg-portal) to /opt/wg-portal/wg-portal. It ensures that the binary is executable.

sudo mkdir -p /opt/wg-portal
 sudo install wg-portal /opt/wg-portal/
 

To handle tasks such as restarting the service or configuring automatic startup, it is recommended to use a process manager like systemd. Refer to Systemd Service Setup for instructions.

Systemd Integration

Note: To run WireGuard Portal as systemd service, you need to download the binary for your architecture beforehand.

The following examples assume that you downloaded the binary to /opt/wg-portal/wg-portal. The configuration file is expected to be located at /opt/wg-portal/config.yml.

Limit Systemd-Networkd Management Scope

If you are using systemd-networkd to manage the rest of your network configuration, you will need to ensure it doesn't remove routing policy created by wg-portal when it restarts:

sudo mkdir --parents /etc/systemd/networkd.conf.d/
diff --git a/master/documentation/getting-started/docker/index.html b/master/documentation/getting-started/docker/index.html
index fab9161..1610563 100644
--- a/master/documentation/getting-started/docker/index.html
+++ b/master/documentation/getting-started/docker/index.html
@@ -6,12 +6,12 @@
     restart: unless-stopped
     logging:
       options:
-        max-size: "10m"
-        max-file: "3"
+        max-size: "10m"
+        max-file: "3"
     cap_add:
       - NET_ADMIN
     # Use host network mode for WireGuard and the UI. Ensure that access to the UI is properly secured.
-    network_mode: "host"
+    network_mode: "host"
     volumes:
       # left side is the host path, right side is the container path
       - /etc/wireguard:/etc/wireguard
@@ -20,7 +20,7 @@
 

By default, the webserver for the UI is listening on port 8888 on all available interfaces.

Volumes for /app/data and /app/config should be used ensure data persistence across container restarts.

WireGuard Interface Handling

WireGuard Portal supports managing WireGuard interfaces through three distinct deployment methods, providing flexibility based on your system architecture and operational preferences:

  • Directly on the host system: WireGuard Portal can control WireGuard interfaces natively on the host, without using containers. This setup is ideal for environments where direct access to system networking is preferred. To use this method, you need to set the network mode to host in your docker-compose.yml file.
    services:
       wg-portal:
         ...
    -    network_mode: "host"
    +    network_mode: "host"
         ...
     

    âš  If host networking is used, the WireGuard Portal UI will be accessible on all the host's IP addresses if the listening address is set to :8888 in the configuration file. To avoid this, you can bind the listening address to a specific IP address, for example, the loopback address (127.0.0.1:8888). It is also possible to deploy firewall rules to restrict access to the WireGuard Portal UI.

âš  If the host is running systemd-networkd, routes managed by WireGuard Portal may be removed whenever systemd-networkd restarts, as it will clean up routes it considers "foreign". To prevent this, add the following to your host's network configuration (e.g. /etc/systemd/networkd.conf or a drop-in file):

[Network]
 ManageForeignRoutingPolicyRules=no
@@ -35,9 +35,9 @@
     ports:
       # host port : container port
       # WireGuard port, needs to match the port in wg-portal interface config (add one port mapping for each interface)
-      - "51820:51820/udp" 
+      - "51820:51820/udp" 
       # Web UI port
-      - "8888:8888/tcp"
+      - "8888:8888/tcp"
     sysctls:
       - net.ipv4.conf.all.src_valid_mark=1
     volumes:
@@ -51,7 +51,7 @@
     ...
     cap_add:
       - NET_ADMIN
-    network_mode: "service:wireguard" # So we ensure to stay on the same network as the wireguard container.
+    network_mode: "service:wireguard" # So we ensure to stay on the same network as the wireguard container.
     volumes:
       # host path : container path
       - ./wg/etc:/etc/wireguard
@@ -66,8 +66,8 @@
       - NET_ADMIN
     ports:
       # host port : container port
-      - "51820:51820/udp" # WireGuard port, needs to match the port in wg-portal interface config
-      - "8888:8888/tcp" # Noticed that the port of the web UI is exposed in the wireguard container.
+      - "51820:51820/udp" # WireGuard port, needs to match the port in wg-portal interface config
+      - "8888:8888/tcp" # Noticed that the port of the web UI is exposed in the wireguard container.
     volumes:
       - ./wg/etc:/config/wg_confs # We share the configuration (wgx.conf) between wg-portal and wireguard
     sysctls:
diff --git a/master/documentation/getting-started/reverse-proxy/index.html b/master/documentation/getting-started/reverse-proxy/index.html
index aecf6f2..c255da3 100644
--- a/master/documentation/getting-started/reverse-proxy/index.html
+++ b/master/documentation/getting-started/reverse-proxy/index.html
@@ -3,17 +3,17 @@
     image: traefik:v3.3
     restart: unless-stopped
     command:
-      #- '--log.level=DEBUG'
-      - '--providers.docker.endpoint=unix:///var/run/docker.sock'
-      - '--providers.docker.exposedbydefault=false'
-      - '--entrypoints.web.address=:80'
-      - '--entrypoints.websecure.address=:443'
-      - '--entrypoints.websecure.http3'
-      - '--certificatesresolvers.letsencryptresolver.acme.httpchallenge=true'
-      - '--certificatesresolvers.letsencryptresolver.acme.httpchallenge.entrypoint=web'
-      - '--certificatesresolvers.letsencryptresolver.acme.email=your.email@domain.com'
-      - '--certificatesresolvers.letsencryptresolver.acme.storage=/letsencrypt/acme.json'
-      #- '--certificatesresolvers.letsencryptresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory'  # just for testing
+      #- '--log.level=DEBUG'
+      - '--providers.docker.endpoint=unix:///var/run/docker.sock'
+      - '--providers.docker.exposedbydefault=false'
+      - '--entrypoints.web.address=:80'
+      - '--entrypoints.websecure.address=:443'
+      - '--entrypoints.websecure.http3'
+      - '--certificatesresolvers.letsencryptresolver.acme.httpchallenge=true'
+      - '--certificatesresolvers.letsencryptresolver.acme.httpchallenge.entrypoint=web'
+      - '--certificatesresolvers.letsencryptresolver.acme.email=your.email@domain.com'
+      - '--certificatesresolvers.letsencryptresolver.acme.storage=/letsencrypt/acme.json'
+      #- '--certificatesresolvers.letsencryptresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory'  # just for testing
     ports:
       - 80:80 # for HTTP
       - 443:443/tcp  # for HTTPS
@@ -22,12 +22,12 @@
       - acme-certs:/letsencrypt
       - /var/run/docker.sock:/var/run/docker.sock:ro
     labels:
-      - 'traefik.enable=true'
+      - 'traefik.enable=true'
       # HTTP Catchall for redirecting HTTP -> HTTPS
-      - 'traefik.http.routers.dashboard-catchall.rule=Host(`wg.domain.com`) && PathPrefix(`/`)'
-      - 'traefik.http.routers.dashboard-catchall.entrypoints=web'
-      - 'traefik.http.routers.dashboard-catchall.middlewares=redirect-to-https'
-      - 'traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https'
+      - 'traefik.http.routers.dashboard-catchall.rule=Host(`wg.domain.com`) && PathPrefix(`/`)'
+      - 'traefik.http.routers.dashboard-catchall.entrypoints=web'
+      - 'traefik.http.routers.dashboard-catchall.middlewares=redirect-to-https'
+      - 'traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https'
 
   wg-portal:
     image: wgportal/wg-portal:v2
@@ -35,16 +35,16 @@
     restart: unless-stopped
     logging:
       options:
-        max-size: "10m"
-        max-file: "3"
+        max-size: "10m"
+        max-file: "3"
     cap_add:
       - NET_ADMIN
     ports:
       # host port : container port
       # WireGuard port, needs to match the port in wg-portal interface config (add one port mapping for each interface)
-      - "51820:51820/udp"
+      - "51820:51820/udp"
       # Web UI port (only available on localhost, Traefik will handle the HTTPS)
-      - "127.0.0.1:8888:8888/tcp"
+      - "127.0.0.1:8888:8888/tcp"
     sysctls:
       - net.ipv4.conf.all.src_valid_mark=1
     volumes:
@@ -52,12 +52,12 @@
       - ./wg/data:/app/data
       - ./wg/config:/app/config
     labels:
-      - 'traefik.enable=true'
-      - 'traefik.http.routers.wgportal.rule=Host(`wg.domain.com`)'
-      - 'traefik.http.routers.wgportal.entrypoints=websecure'
-      - 'traefik.http.routers.wgportal.tls.certresolver=letsencryptresolver'
-      - 'traefik.http.routers.wgportal.service=wgportal'
-      - 'traefik.http.services.wgportal.loadbalancer.server.port=8888'
+      - 'traefik.enable=true'
+      - 'traefik.http.routers.wgportal.rule=Host(`wg.domain.com`)'
+      - 'traefik.http.routers.wgportal.entrypoints=websecure'
+      - 'traefik.http.routers.wgportal.tls.certresolver=letsencryptresolver'
+      - 'traefik.http.routers.wgportal.service=wgportal'
+      - 'traefik.http.services.wgportal.loadbalancer.server.port=8888'
 
 volumes:
   acme-certs:
diff --git a/master/documentation/upgrade/v1/index.html b/master/documentation/upgrade/v1/index.html
index b39e3ba..0f43154 100644
--- a/master/documentation/upgrade/v1/index.html
+++ b/master/documentation/upgrade/v1/index.html
@@ -1,9 +1,9 @@
  Upgrade - WireGuard Portal      

Upgrade

Major upgrades between different versions may require special procedures, which are described in the following sections.

Upgrade from v1 to v2

âš  Before upgrading from V1, make sure that you have a backup of your currently working configuration files and database!

To start the upgrade process, start the wg-portal binary with the -migrateFrom parameter. The configuration (config.yaml) for WireGuard Portal must be updated and valid before starting the upgrade.

To upgrade from a previous SQLite database, start wg-portal like:

./wg-portal-amd64 -migrateFrom=old_wg_portal.db
-

You can also specify the database type using the parameter -migrateFromType. Supported database types: mysql, mssql, postgres or sqlite.

For example:

./wg-portal-amd64 -migrateFromType=mysql -migrateFrom='user:pass@tcp(1.2.3.4:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local'
+

You can also specify the database type using the parameter -migrateFromType. Supported database types: mysql, mssql, postgres or sqlite.

For example:

./wg-portal-amd64 -migrateFromType=mysql -migrateFrom='user:pass@tcp(1.2.3.4:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local'
 

The upgrade will transform the old, existing database and store the values in the new database specified in the config.yaml configuration file. Ensure that the new database does not contain any data!

If you are using Docker, you can adapt the docker-compose.yml file to start the upgrade process:

services:
   wg-portal:
     image: wgportal/wg-portal:v2
     # ... other settings
     restart: no
-    command: ["-migrateFrom=/app/data/old_wg_portal.db"]
+    command: ["-migrateFrom=/app/data/old_wg_portal.db"]
 
\ No newline at end of file diff --git a/master/documentation/usage/authentication/index.html b/master/documentation/usage/authentication/index.html index 8eda9ae..38a84da 100644 --- a/master/documentation/usage/authentication/index.html +++ b/master/documentation/usage/authentication/index.html @@ -1,53 +1,53 @@ Authentication - WireGuard Portal

Authentication

WireGuard Portal supports multiple authentication mechanisms to manage user access. This includes

  • Local user accounts
  • LDAP authentication
  • OAuth2 and OIDC authentication
  • Passkey authentication (WebAuthn)

Users can have two roles which limit their permissions in WireGuard Portal:

  • User: Can manage their own account and peers.
  • Admin: Can manage all users and peers, including the ability to manage WireGuard interfaces.

In general, each user is identified by a unique identifier. If the same user identifier exists across multiple authentication sources, WireGuard Portal automatically merges those accounts into a single user record. When a user is associated with multiple authentication sources, their information in WireGuard Portal is updated based on the most recently logged-in source. For more details, see User Synchronization documentation.

Password Authentication

WireGuard Portal supports username and password authentication for both local and LDAP-backed accounts. Local users are stored in the database, while LDAP users are authenticated against an external LDAP server.

On initial startup, WireGuard Portal automatically creates a local admin account with the password wgportal-default.

âš  This password must be changed immediately after the first login.

The minimum password length for all local users can be configured in the auth section of the configuration file. The default value is 16 characters, see min_password_length. The minimum password length is also enforced for the default admin user.

Passkey (WebAuthn) Authentication

Besides the standard authentication mechanisms, WireGuard Portal supports Passkey authentication. This feature is enabled by default and can be configured in the webauthn section of the configuration file.

Users can register multiple Passkeys to their account. These Passkeys can be used to log in to the web UI as long as the user is not locked.

âš  Passkey authentication does not disable password authentication. The password can still be used to log in (e.g., as a fallback).

To register a Passkey, open the settings page (1) in the web UI and click on the "Register Passkey" (2) button.

Passkey UI

OAuth2 and OIDC Authentication

WireGuard Portal supports OAuth2 and OIDC authentication. You can use any OAuth2 or OIDC provider that supports the authorization code flow, such as Google, GitHub, or Keycloak.

For OAuth2 or OIDC to work, you need to configure the external_url property in the web section of the configuration file. If you are planning to expose the portal to the internet, make sure that the external_url is configured to use HTTPS.

To add OIDC or OAuth2 authentication to WireGuard Portal, create a Client-ID and Client-Secret in your OAuth2 provider and configure a new authentication provider in the auth section of the configuration file. Make sure that each configured provider has a unique provider_name property set. Samples can be seen here.

When registering the OAuth2 or OIDC application with your provider, configure the callback/redirect URL as follows:

<external_url>/api/v0/auth/login/<provider_name>/callback
 

Replace <external_url> with the value configured in external_url and <provider_name> with the exact provider_name from the matching OAuth2 or OIDC provider configuration.

Limiting Login to Specific Domains

You can limit the login to specific domains by setting the allowed_domains property for OAuth2 or OIDC providers. This property is a comma-separated list of domains that are allowed to log in. The user's email address is checked against this list. For example, if you want to allow only users with an email address ending in outlook.com to log in, set the property as follows:

auth:
   oidc:
-    - provider_name: "oidc1"
+    - provider_name: "oidc1"
       # ... other settings
       allowed_domains:
-        - "outlook.com"
+        - "outlook.com"
 

Limiting Login to Specific User Groups

You can limit the login to specific user groups by setting the allowed_user_groups property for OAuth2 or OIDC providers. If this property is not empty, the user's user_groups claim must contain at least one matching group.

To use this feature, ensure your group claim is mapped via field_map.user_groups.

auth:
   oidc:
-    - provider_name: "oidc1"
+    - provider_name: "oidc1"
       # ... other settings
       allowed_user_groups:
-        - "wg-users"
-        - "wg-admins"
+        - "wg-users"
+        - "wg-admins"
       field_map:
-        user_groups: "groups"
+        user_groups: "groups"
 

If allowed_user_groups is configured and the authenticated user has no matching group in user_groups, login is denied.

Minimal deny-by-group example:

auth:
   oauth:
-    - provider_name: "oauth1"
+    - provider_name: "oauth1"
       # ... other settings
       allowed_user_groups:
-        - "vpn-users"
+        - "vpn-users"
       field_map:
-        user_groups: "groups"
+        user_groups: "groups"
 

Limit Login to Existing Users

You can limit the login to existing users only by setting the registration_enabled property to false for OAuth2 or OIDC providers. If registration is enabled, new users will be created in the database when they log in for the first time.

Admin Mapping

You can map users to admin roles based on their attributes in the OAuth2 or OIDC provider. To do this, set the admin_mapping property for the provider. Administrative access can either be mapped by a specific attribute or by group membership.

Attribute specific mapping can be achieved by setting the admin_value_regex and the is_admin property. The admin_value_regex property is a regular expression that is matched against the value of the is_admin attribute. The user is granted admin access if the regex matches the attribute value.

Example:

auth:
   oidc:
-    - provider_name: "oidc1"
+    - provider_name: "oidc1"
       # ... other settings
       field_map:
-        is_admin: "wg_admin_prop"
+        is_admin: "wg_admin_prop"
       admin_mapping:
-        admin_value_regex: "^true$"
+        admin_value_regex: "^true$"
 
The example above will grant admin access to users with the wg_admin_prop attribute set to true.

Group membership mapping can be achieved by setting the admin_group_regex and user_groups property. The admin_group_regex property is a regular expression that is matched against the group names of the user. The user is granted admin access if the regex matches any of the group names.

Example:

auth:
   oidc:
-    - provider_name: "oidc1"
+    - provider_name: "oidc1"
       # ... other settings
       field_map:
-        user_groups: "groups"
+        user_groups: "groups"
       admin_mapping:
-        admin_group_regex: "^the-admin-group$"
+        admin_group_regex: "^the-admin-group$"
 
The example above will grant admin access to users who are members of the the-admin-group group.

LDAP Authentication

WireGuard Portal supports LDAP authentication. You can use any LDAP server that supports the LDAP protocol, such as Active Directory or OpenLDAP. Multiple LDAP servers can be configured in the auth section of the configuration file. WireGuard Portal remembers the authentication provider of the user and therefore avoids conflicts between multiple LDAP providers.

To configure LDAP authentication, create a new ldap authentication provider in the auth section of the configuration file.

Limiting Login to Specific Users

You can limit the login to specific users by setting the login_filter property for LDAP provider. This filter uses the LDAP search filter syntax. The username can be inserted into the query by placing the {{login_identifier}} placeholder in the filter. This placeholder will then be replaced with the username entered by the user during login.

For example, if you want to allow only users with the objectClass attribute set to organizationalPerson to log in, set the property as follows:

auth:
   ldap:
-    - provider_name: "ldap1"
+    - provider_name: "ldap1"
       # ... other settings
-      login_filter: "(&(objectClass=organizationalPerson)(uid={{login_identifier}}))"
+      login_filter: "(&(objectClass=organizationalPerson)(uid={{login_identifier}}))"
 

The login_filter should always be designed to return at most one user.

Limit Login to Existing Users

You can limit the login to existing users only by setting the registration_enabled property to false for LDAP providers. If registration is enabled, new users will be created in the database when they log in for the first time.

Admin Mapping

You can map users to admin roles based on their group membership in the LDAP server. To do this, set the admin_group and memberof property for the provider. The admin_group property defines the distinguished name of the group that is allowed to log in as admin. All groups that are listed in the memberof attribute of the user will be checked against this group. If one of the groups matches, the user is granted admin access.

Interface-specific Provisioning Filters

You can restrict which users are allowed to provision peers for specific WireGuard interfaces by setting the interface_filter property. This property is a map where each key corresponds to a WireGuard interface identifier, and the value is an LDAP filter. A user will only be able to see and provision peers for an interface if they match the specified LDAP filter for that interface.

Example:

auth:
   ldap:
-    - provider_name: "ldap1"
+    - provider_name: "ldap1"
       # ... other settings
       interface_filter:
-        wg0: "(memberOf=CN=VPNUsers,OU=Groups,DC=COMPANY,DC=LOCAL)"
-        wg1: "(department=IT)"
+        wg0: "(memberOf=CN=VPNUsers,OU=Groups,DC=COMPANY,DC=LOCAL)"
+        wg1: "(department=IT)"
 

This feature works by materializing the list of authorized users for each interface during the periodic LDAP synchronization. Even if a user bypasses the UI, the backend will enforce these restrictions at the service layer.

User Synchronization

\ No newline at end of file diff --git a/master/documentation/usage/backends/index.html b/master/documentation/usage/backends/index.html index 60afd17..244a3f1 100644 --- a/master/documentation/usage/backends/index.html +++ b/master/documentation/usage/backends/index.html @@ -3,7 +3,7 @@ default: mikrotik-prod mikrotik: - - id: mikrotik-prod # unique id, not "local" + - id: mikrotik-prod # unique id, not "local" display_name: RouterOS RB5009 # optional nice name api_url: https://10.10.10.10/rest api_user: wgportal @@ -17,7 +17,7 @@ default: pfsense1 pfsense: - - id: pfsense1 # unique id, not "local" + - id: pfsense1 # unique id, not "local" display_name: Main pfSense # optional nice name api_url: https://pfsense.example.com # no trailing /api/v2 api_key: your-api-key diff --git a/master/documentation/usage/mail-templates/index.html b/master/documentation/usage/mail-templates/index.html index 6ef77a6..b80287c 100644 --- a/master/documentation/usage/mail-templates/index.html +++ b/master/documentation/usage/mail-templates/index.html @@ -4,5 +4,5 @@ # If the directory is empty on startup, the default embedded templates # will be written there so you can modify them. # Leave empty to use embedded templates only. - templates_path: "/opt/wg-portal/mail-templates" + templates_path: "/opt/wg-portal/mail-templates"

Template files and names

The system expects the following template names. Place files with these names in your templates_path to override the defaults. You do not need to override all templates, only the ones you want to customize should be present.

  • Text templates (.gotpl):
  • mail_with_link.gotpl
  • mail_with_attachment.gotpl
  • HTML templates (.gohtml):
  • mail_with_link.gohtml
  • mail_with_attachment.gohtml

Both text and HTML templates are standard Go templates and receive the following data fields, depending on the email type:

  • Common fields:
  • PortalUrl (string) - external URL of the Portal
  • PortalName (string) - site title/company name
  • User (*domain.User) - the recipient user (may be partially populated when sending to a peer email)
  • Link email (mail_with_link.*):
  • Link (string) - the download link
  • Attachment email (mail_with_attachment.*):
  • ConfigFileName (string) - filename of the attached WireGuard config
  • QrcodePngName (string) - CID content-id of the embedded QR code image

Tip: You can inspect the embedded templates in the repository under internal/app/mail/tpl_files/ for reference. When the directory at templates_path is empty, these files are copied to your folder so you can edit them in place.

\ No newline at end of file diff --git a/master/documentation/usage/webhooks/index.html b/master/documentation/usage/webhooks/index.html index 86cc240..c6bbbf0 100644 --- a/master/documentation/usage/webhooks/index.html +++ b/master/documentation/usage/webhooks/index.html @@ -2,92 +2,92 @@ url: https://your-service.example.com/webhook

Security

Webhooks can be secured by using a shared secret. This secret is included in the Authorization header of the webhook request, allowing your service to verify the authenticity of the request. You can set the shared secret in the webhook configuration:

webhook:
   url: https://your-service.example.com/webhook
-  secret: "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
+  secret: "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
 

You should also make sure that your webhook endpoint is secured with HTTPS to prevent eavesdropping and tampering.

Available Events

WireGuard Portal supports various events that can trigger webhooks. The following events are available:

The following entity models are supported for webhook events:

Payload Structure

All webhook events send a JSON payload containing relevant data. The structure of the payload depends on the event type and entity involved. A common shell structure for webhook payloads is as follows:

{
-  "event": "create", // The event type, e.g. "create", "update", "delete", "connect", "disconnect"
-  "entity": "user",  // The entity type, e.g. "user", "peer", "peer_metric", "interface"
-  "identifier": "the-user-identifier", // Unique identifier of the entity, e.g. user ID or peer ID
-  "payload": {
+  "event": "create", // The event type, e.g. "create", "update", "delete", "connect", "disconnect"
+  "entity": "user",  // The entity type, e.g. "user", "peer", "peer_metric", "interface"
+  "identifier": "the-user-identifier", // Unique identifier of the entity, e.g. user ID or peer ID
+  "payload": {
     // The payload of the event, e.g. a Peer model.
     // Detailed model descriptions are provided below.
   }
 }
 

Payload Models

All payload models are encoded as JSON objects. Fields with empty values might be omitted in the payload.

User Payload (entity: user)

JSON Field Type Description
CreatedBy string Creator identifier
UpdatedBy string Last updater identifier
CreatedAt time.Time Time of creation
UpdatedAt time.Time Time of last update
Identifier string Unique user identifier
Email string User email
AuthSources []AuthSource Authentication sources
IsAdmin bool Whether user has admin privileges
Firstname string User's first name (optional)
Lastname string User's last name (optional)
Phone string Contact phone number (optional)
Department string User's department (optional)
Notes string Additional notes (optional)
Disabled *time.Time When user was disabled
DisabledReason string Reason for deactivation
Locked *time.Time When user account was locked
LockedReason string Reason for being locked

AuthSource:

JSON Field Type Description
Source string The authentication source (e.g. LDAP, OAuth, or DB)
ProviderName string The identifier of the authentication provider

Peer Payload (entity: peer)

JSON Field Type Description
CreatedBy string Creator identifier
UpdatedBy string Last updater identifier
CreatedAt time.Time Creation timestamp
UpdatedAt time.Time Last update timestamp
Endpoint string Peer endpoint address
EndpointPublicKey string Public key of peer endpoint
AllowedIPsStr string Allowed IPs
ExtraAllowedIPsStr string Extra allowed IPs
PresharedKey string Pre-shared key for encryption
PersistentKeepalive int Keepalive interval in seconds
DisplayName string Display name of the peer
Identifier string Unique identifier
UserIdentifier string Associated user ID (optional)
InterfaceIdentifier string Interface this peer is attached to
Disabled *time.Time When the peer was disabled
DisabledReason string Reason for being disabled
ExpiresAt *time.Time Expiration date
Notes string Notes for this peer
AutomaticallyCreated bool Whether peer was auto-generated
PrivateKey string Peer private key
PublicKey string Peer public key
InterfaceType string Type of the peer interface
Addresses []string IP addresses
CheckAliveAddress string Address used for alive checks
DnsStr string DNS servers
DnsSearchStr string DNS search domains
Mtu int MTU (Maximum Transmission Unit)
FirewallMark uint32 Firewall mark (optional)
RoutingTable string Custom routing table (optional)
PreUp string Command before bringing up interface
PostUp string Command after bringing up interface
PreDown string Command before bringing down interface
PostDown string Command after bringing down interface

Interface Payload (entity: interface)

JSON Field Type Description
CreatedBy string Creator identifier
UpdatedBy string Last updater identifier
CreatedAt time.Time Creation timestamp
UpdatedAt time.Time Last update timestamp
Identifier string Unique identifier
PrivateKey string Private key for the interface
PublicKey string Public key for the interface
ListenPort int Listening port
Addresses []string IP addresses
DnsStr string DNS servers
DnsSearchStr string DNS search domains
Mtu int MTU (Maximum Transmission Unit)
FirewallMark uint32 Firewall mark
RoutingTable string Custom routing table
PreUp string Command before bringing up interface
PostUp string Command after bringing up interface
PreDown string Command before bringing down interface
PostDown string Command after bringing down interface
SaveConfig bool Whether to save config to file
DisplayName string Human-readable name
Type string Type of interface
DriverType string Driver used
Disabled *time.Time When the interface was disabled
DisabledReason string Reason for being disabled
PeerDefNetworkStr string Default peer network configuration
PeerDefDnsStr string Default peer DNS servers
PeerDefDnsSearchStr string Default peer DNS search domains
PeerDefEndpoint string Default peer endpoint
PeerDefAllowedIPsStr string Default peer allowed IPs
PeerDefMtu int Default peer MTU
PeerDefPersistentKeepalive int Default keepalive value
PeerDefFirewallMark uint32 Default firewall mark for peers
PeerDefRoutingTable string Default routing table for peers
PeerDefPreUp string Default peer pre-up command
PeerDefPostUp string Default peer post-up command
PeerDefPreDown string Default peer pre-down command
PeerDefPostDown string Default peer post-down command

Peer Metrics Payload (entity: peer_metric)

JSON Field Type Description
Status PeerStatus Current status of the peer
Peer Peer Peer data

PeerStatus sub-structure:

JSON Field Type Description
UpdatedAt time.Time Time of last status update
IsConnected bool Is peer currently connected
IsPingable bool Can peer be pinged
LastPing *time.Time Time of last successful ping
BytesReceived uint64 Bytes received from peer
BytesTransmitted uint64 Bytes sent to peer
Endpoint string Last known endpoint
LastHandshake *time.Time Last successful handshake
LastSessionStart *time.Time Time the last session began

Example Payloads

The following payload is an example of a webhook event when a peer connects to the VPN:

{
-  "event": "connect",
-  "entity": "peer_metric",
-  "identifier": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=",
-  "payload": {
-    "Status": {
-      "UpdatedAt": "2025-06-27T22:20:08.734900034+02:00",
-      "IsConnected": true,
-      "IsPingable": false,
-      "BytesReceived": 212,
-      "BytesTransmitted": 2884,
-      "Endpoint": "10.55.66.77:58756",
-      "LastHandshake": "2025-06-27T22:19:46.580842776+02:00",
-      "LastSessionStart": "2025-06-27T22:19:46.580842776+02:00"
+  "event": "connect",
+  "entity": "peer_metric",
+  "identifier": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=",
+  "payload": {
+    "Status": {
+      "UpdatedAt": "2025-06-27T22:20:08.734900034+02:00",
+      "IsConnected": true,
+      "IsPingable": false,
+      "BytesReceived": 212,
+      "BytesTransmitted": 2884,
+      "Endpoint": "10.55.66.77:58756",
+      "LastHandshake": "2025-06-27T22:19:46.580842776+02:00",
+      "LastSessionStart": "2025-06-27T22:19:46.580842776+02:00"
     },
-    "Peer": {
-      "CreatedBy": "admin@wgportal.local",
-      "UpdatedBy": "admin@wgportal.local",
-      "CreatedAt": "2025-06-26T21:43:49.251839574+02:00",
-      "UpdatedAt": "2025-06-27T22:18:39.67763985+02:00",
-      "Endpoint": "10.55.66.1:51820",
-      "EndpointPublicKey": "eiVibpi3C2PUPcx2kwA5s09OgHx7AEaKMd33k0LQ5mM=",
-      "AllowedIPsStr": "10.11.12.0/24,fdfd:d3ad:c0de:1234::/64",
-      "ExtraAllowedIPsStr": "",
-      "PresharedKey": "p9DDeLUSLOdQcjS8ZsBAiqUzwDIUvTyzavRZFuzhvyE=",
-      "PersistentKeepalive": 16,
-      "DisplayName": "Peer Fb5TaziA",
-      "Identifier": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=",
-      "UserIdentifier": "admin@wgportal.local",
-      "InterfaceIdentifier": "wgTesting",
-      "AutomaticallyCreated": false,
-      "PrivateKey": "QBFNBe+7J49ergH0ze2TGUJMFrL/2bOL50Z2cgluYW8=",
-      "PublicKey": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=",
-      "InterfaceType": "client",
-      "Addresses": [
-        "10.11.12.10/32",
-        "fdfd:d3ad:c0de:1234::a/128"
+    "Peer": {
+      "CreatedBy": "admin@wgportal.local",
+      "UpdatedBy": "admin@wgportal.local",
+      "CreatedAt": "2025-06-26T21:43:49.251839574+02:00",
+      "UpdatedAt": "2025-06-27T22:18:39.67763985+02:00",
+      "Endpoint": "10.55.66.1:51820",
+      "EndpointPublicKey": "eiVibpi3C2PUPcx2kwA5s09OgHx7AEaKMd33k0LQ5mM=",
+      "AllowedIPsStr": "10.11.12.0/24,fdfd:d3ad:c0de:1234::/64",
+      "ExtraAllowedIPsStr": "",
+      "PresharedKey": "p9DDeLUSLOdQcjS8ZsBAiqUzwDIUvTyzavRZFuzhvyE=",
+      "PersistentKeepalive": 16,
+      "DisplayName": "Peer Fb5TaziA",
+      "Identifier": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=",
+      "UserIdentifier": "admin@wgportal.local",
+      "InterfaceIdentifier": "wgTesting",
+      "AutomaticallyCreated": false,
+      "PrivateKey": "QBFNBe+7J49ergH0ze2TGUJMFrL/2bOL50Z2cgluYW8=",
+      "PublicKey": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=",
+      "InterfaceType": "client",
+      "Addresses": [
+        "10.11.12.10/32",
+        "fdfd:d3ad:c0de:1234::a/128"
       ],
-      "CheckAliveAddress": "",
-      "DnsStr": "",
-      "DnsSearchStr": "",
-      "Mtu": 1420
+      "CheckAliveAddress": "",
+      "DnsStr": "",
+      "DnsSearchStr": "",
+      "Mtu": 1420
     }
   }
 }
 

Here is another example of a webhook event when a peer is updated:

{
-  "event": "update",
-  "entity": "peer",
-  "identifier": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=",
-  "payload": {
-    "CreatedBy": "admin@wgportal.local",
-    "UpdatedBy": "admin@wgportal.local",
-    "CreatedAt": "2025-06-26T21:43:49.251839574+02:00",
-    "UpdatedAt": "2025-06-27T22:18:39.67763985+02:00",
-    "Endpoint": "10.55.66.1:51820",
-    "EndpointPublicKey": "eiVibpi3C2PUPcx2kwA5s09OgHx7AEaKMd33k0LQ5mM=",
-    "AllowedIPsStr": "10.11.12.0/24,fdfd:d3ad:c0de:1234::/64",
-    "ExtraAllowedIPsStr": "",
-    "PresharedKey": "p9DDeLUSLOdQcjS8ZsBAiqUzwDIUvTyzavRZFuzhvyE=",
-    "PersistentKeepalive": 16,
-    "DisplayName": "Peer Fb5TaziA",
-    "Identifier": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=",
-    "UserIdentifier": "admin@wgportal.local",
-    "InterfaceIdentifier": "wgTesting",
-    "AutomaticallyCreated": false,
-    "PrivateKey": "QBFNBe+7J49ergH0ze2TGUJMFrL/2bOL50Z2cgluYW8=",
-    "PublicKey": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=",
-    "InterfaceType": "client",
-    "Addresses": [
-      "10.11.12.10/32",
-      "fdfd:d3ad:c0de:1234::a/128"
+  "event": "update",
+  "entity": "peer",
+  "identifier": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=",
+  "payload": {
+    "CreatedBy": "admin@wgportal.local",
+    "UpdatedBy": "admin@wgportal.local",
+    "CreatedAt": "2025-06-26T21:43:49.251839574+02:00",
+    "UpdatedAt": "2025-06-27T22:18:39.67763985+02:00",
+    "Endpoint": "10.55.66.1:51820",
+    "EndpointPublicKey": "eiVibpi3C2PUPcx2kwA5s09OgHx7AEaKMd33k0LQ5mM=",
+    "AllowedIPsStr": "10.11.12.0/24,fdfd:d3ad:c0de:1234::/64",
+    "ExtraAllowedIPsStr": "",
+    "PresharedKey": "p9DDeLUSLOdQcjS8ZsBAiqUzwDIUvTyzavRZFuzhvyE=",
+    "PersistentKeepalive": 16,
+    "DisplayName": "Peer Fb5TaziA",
+    "Identifier": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=",
+    "UserIdentifier": "admin@wgportal.local",
+    "InterfaceIdentifier": "wgTesting",
+    "AutomaticallyCreated": false,
+    "PrivateKey": "QBFNBe+7J49ergH0ze2TGUJMFrL/2bOL50Z2cgluYW8=",
+    "PublicKey": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=",
+    "InterfaceType": "client",
+    "Addresses": [
+      "10.11.12.10/32",
+      "fdfd:d3ad:c0de:1234::a/128"
     ],
-    "CheckAliveAddress": "",
-    "DnsStr": "",
-    "DnsSearchStr": "",
-    "Mtu": 1420
+    "CheckAliveAddress": "",
+    "DnsStr": "",
+    "DnsSearchStr": "",
+    "Mtu": 1420
   }
 }
 
\ No newline at end of file diff --git a/master/sitemap.xml b/master/sitemap.xml index 64dc1da..e8d08b6 100644 --- a/master/sitemap.xml +++ b/master/sitemap.xml @@ -2,78 +2,78 @@ https://wgportal.org/master/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/overview/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/configuration/examples/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/configuration/overview/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/getting-started/binaries/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/getting-started/docker/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/getting-started/helm/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/getting-started/reverse-proxy/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/getting-started/sources/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/monitoring/prometheus/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/rest-api/api-doc/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/upgrade/v1/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/usage/authentication/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/usage/backends/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/usage/general/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/usage/mail-templates/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/usage/security/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/usage/user-sync/ - 2026-08-11 + 2026-08-27 https://wgportal.org/master/documentation/usage/webhooks/ - 2026-08-11 + 2026-08-27 \ No newline at end of file diff --git a/master/sitemap.xml.gz b/master/sitemap.xml.gz index d8f0a1b..a8dc9df 100644 Binary files a/master/sitemap.xml.gz and b/master/sitemap.xml.gz differ