A simple, web based configuration portal for WireGuard. The portal uses the WireGuard wgctrl library to manage existing VPN interfaces. This allows for seamless activation or deactivation of new users, without disturbing existing VPN connections.
The configuration portal currently supports using SQLite and MySQL as a user source for authentication and profile data. It also supports LDAP (Active Directory or OpenLDAP) as authentication provider.
- Self-hosted and web based
- Automatically select IP from the network pool assigned to client
- QR-Code for convenient mobile client configuration
- Sent email to client with QR-code and client config
- Enable / Disable clients seamlessly
- Generation of
wgX.conf
after any modification - IPv6 ready
- User authentication (SQLite/MySQL and LDAP)
- Dockerized
- Responsive template
- One single binary
- Can be used with existing WireGuard setups
- Support for multiple WireGuard interfaces
- REST API for management and client deployment
Make sure that your host system has at least one WireGuard interface (for example wg0) available. If you did not start up a WireGuard interface yet, take a look at wg-quick in order to get started.
The easiest way to run WireGuard Portal is to use the Docker image provided.
HINT: the latest tag always refers to the master branch and might contain unstable or incompatible code!
Docker Compose snippet with some sample configuration values:
version: '3.6'
services:
wg-portal:
image: h44z/wg-portal:latest
container_name: wg-portal
restart: unless-stopped
cap_add:
- NET_ADMIN
network_mode: "host"
volumes:
- /etc/wireguard:/etc/wireguard
- ./data:/app/data
ports:
- '8123:8123'
environment:
# WireGuard Settings
- WG_DEVICES=wg0
- WG_DEFAULT_DEVICE=wg0
- WG_CONFIG_PATH=/etc/wireguard
# Core Settings
- EXTERNAL_URL=https://vpn.company.com
- WEBSITE_TITLE=WireGuard VPN
- COMPANY_NAME=Your Company Name
- [email protected]
- ADMIN_PASS=supersecret
# Mail Settings
- MAIL_FROM=WireGuard VPN <[email protected]>
- EMAIL_HOST=10.10.10.10
- EMAIL_PORT=25
# LDAP Settings
- LDAP_ENABLED=true
- LDAP_URL=ldap://srv-ad01.company.local:389
- LDAP_BASEDN=DC=COMPANY,DC=LOCAL
- [email protected]
- LDAP_PASSWORD=supersecretldappassword
- LDAP_ADMIN_GROUP=CN=WireGuardAdmins,OU=Users,DC=COMPANY,DC=LOCAL
Please note that mapping /etc/wireguard
to /etc/wireguard
inside the docker, will erase your host's current configuration.
If needed, please make sure to back up your files from /etc/wireguard
.
For a full list of configuration options take a look at the source file internal/server/configuration.go.
For a standalone application, use the Makefile provided in the repository to build the application. Go version 1.16 or higher has to be installed to build WireGuard Portal.
make
# To build for arm architecture as well use:
make build-cross-plat
The compiled binary will be located in the dist folder. A detailed description for using this software with a raspberry pi can be found in the README-RASPBERRYPI.md.
You can configure WireGuard Portal using either environment variables or a yaml configuration file.
The filepath of the yaml configuration file defaults to config.yml in the working directory of the executable.
It is possible to override the configuration filepath using the environment variable CONFIG_FILE.
For example: CONFIG_FILE=/home/test/config.yml ./wg-portal-amd64
.
The following configuration options are available:
environment | yaml | yaml_parent | default_value | description |
---|---|---|---|---|
LISTENING_ADDRESS | listeningAddress | core | :8123 | The address on which the web server is listening. Optional IP address and port, e.g.: 127.0.0.1:8080. |
EXTERNAL_URL | externalUrl | core | http://localhost:8123 | The external URL where the web server is reachable. This link is used in emails that are created by the WireGuard Portal. |
WEBSITE_TITLE | title | core | WireGuard VPN | The website title. |
COMPANY_NAME | company | core | WireGuard Portal | The company name (for branding). |
MAIL_FROM | mailFrom | core | WireGuard VPN [email protected] | The email address from which emails are sent. |
LOGO_URL | logoUrl | core | /img/header-logo.png | The logo displayed in the page's header. |
ADMIN_USER | adminUser | core | [email protected] | The administrator user. Must be a valid email address. |
ADMIN_PASS | adminPass | core | wgportal | The administrator password. If unchanged, a random password will be set on first startup. |
EDITABLE_KEYS | editableKeys | core | true | Allow to edit key-pairs in the UI. |
CREATE_DEFAULT_PEER | createDefaultPeer | core | false | If an LDAP user logs in for the first time, a new WireGuard peer will be created on the WG_DEFAULT_DEVICE if this option is enabled. |
SELF_PROVISIONING | selfProvisioning | core | false | Allow registered users to automatically create peers via the RESTful API. |
WG_EXPORTER_FRIENDLY_NAMES | wgExporterFriendlyNames | core | false | Enable integration with prometheus_wireguard_exporter friendly name. |
LDAP_ENABLED | ldapEnabled | core | false | Enable or disable the LDAP backend. |
SESSION_SECRET | sessionSecret | core | secret | Use a custom secret to encrypt session data. |
DATABASE_TYPE | typ | database | sqlite | Either mysql or sqlite. |
DATABASE_HOST | host | database | The mysql server address. | |
DATABASE_PORT | port | database | The mysql server port. | |
DATABASE_NAME | database | database | data/wg_portal.db | For sqlite database: the database file-path, otherwise the database name. |
DATABASE_USERNAME | user | database | The mysql user. | |
DATABASE_PASSWORD | password | database | The mysql password. | |
EMAIL_HOST | host | 127.0.0.1 | The email server address. | |
EMAIL_PORT | port | 25 | The email server port. | |
EMAIL_TLS | tls | false | Use STARTTLS. DEPRECATED: use EMAIL_ENCRYPTION instead. | |
EMAIL_ENCRYPTION | encryption | none | Either none, tls or starttls. | |
EMAIL_CERT_VALIDATION | certcheck | false | Validate the email server certificate. | |
EMAIL_USERNAME | user | An optional username for SMTP authentication. | ||
EMAIL_PASSWORD | pass | An optional password for SMTP authentication. | ||
EMAIL_AUTHTYPE | auth | plain | Either plain, login or crammd5. If username and password are empty, this value is ignored. | |
WG_DEVICES | devices | wg | wg0 | A comma separated list of WireGuard devices. |
WG_DEFAULT_DEVICE | defaultDevice | wg | wg0 | This device is used for auto-created peers (if CREATE_DEFAULT_PEER is enabled). |
WG_CONFIG_PATH | configDirectory | wg | /etc/wireguard | If set, interface configuration updates will be written to this path, filename: .conf. |
MANAGE_IPS | manageIPAddresses | wg | true | Handle IP address setup of interface, only available on linux. |
LDAP_URL | url | ldap | ldap://srv-ad01.company.local:389 | The LDAP server url. |
LDAP_STARTTLS | startTLS | ldap | true | Use STARTTLS. |
LDAP_CERT_VALIDATION | certcheck | ldap | false | Validate the LDAP server certificate. |
LDAP_BASEDN | dn | ldap | DC=COMPANY,DC=LOCAL | The base DN for searching users. |
LDAP_USER | user | ldap | company\\ldap_wireguard | The bind user. |
LDAP_PASSWORD | pass | ldap | SuperSecret | The bind password. |
LDAP_LOGIN_FILTER | loginFilter | ldap | (&(objectClass=organizationalPerson)(mail={{login_identifier}})(!userAccountControl:1.2.840.113556.1.4.803:=2)) | {{login_identifier}} will be replaced with the login email address. |
LDAP_SYNC_FILTER | syncFilter | ldap | (&(objectClass=organizationalPerson)(!userAccountControl:1.2.840.113556.1.4.803:=2)(mail=*)) | The filter string for the LDAP synchronization service. |
LDAP_ADMIN_GROUP | adminGroup | ldap | CN=WireGuardAdmins,OU=_O_IT,DC=COMPANY,DC=LOCAL | Users in this group are marked as administrators. |
LDAP_ATTR_EMAIL | attrEmail | ldap | User email attribute. | |
LDAP_ATTR_FIRSTNAME | attrFirstname | ldap | givenName | User firstname attribute. |
LDAP_ATTR_LASTNAME | attrLastname | ldap | sn | User lastname attribute. |
LDAP_ATTR_PHONE | attrPhone | ldap | telephoneNumber | User phone number attribute. |
LDAP_ATTR_GROUPS | attrGroups | ldap | memberOf | User groups attribute. |
OAUTH_REDIRECT_URL | redirectURL | oauth | /callback | Redirect URL for all the OAuth2 and OpenID login services. |
OAUTH_BITBUCKET_CLIENT_ID | bitbucket.clientID | oauth | clientid | ClientID for OAuth2 authentication with BitBucket. |
OAUTH_BITBUCKET_CLIENT_SECRET | bitbucket.clientSecret | oauth | supersecret | ClientSecret for OAuth2 authentication with BitBucket. |
OAUTH_BITBUCKET_CREATE_USERS | bitbucket.createUsers | oauth | false | A user logged in with BitBucket OAuth2 should be created automatically when it doesn't exist before. |
OAUTH_BITBUCKET_ENABLED | bitbucket.enabled | oauth | false | Enable BitBucket OAuth2 authentication. |
OAUTH_GITHUB_CLIENT_ID | github.clientID | oauth | clientid | ClientID for OAuth2 authentication with GitHub. |
OAUTH_GITHUB_CLIENT_SECRET | github.clientSecret | oauth | supersecret | ClientSecret for OAuth2 authentication with GitHub. |
OAUTH_GITHUB_CREATE_USERS | github.createUsers | oauth | false | A user logged in with Google OAuth2 should be created automatically when it doesn't exist before. |
OAUTH_GITHUB_ENABLED | github.enabled | oauth | false | Enable GitHub OAuth2 authentication. |
OAUTH_GITLAB_CLIENT_ID | gitlab.clientID | oauth | clientid | ClientID for OAuth2 authentication with Gitlab. |
OAUTH_GITLAB_CLIENT_SECRET | gitlab.clientSecret | oauth | supersecret | ClientSecret for OAuth2 authentication with Gitlab. |
OAUTH_GITLAB_CREATE_USERS | gitlab.createUsers | oauth | false | A user logged in with Gitlab OAuth2 should be created automatically when it doesn't exist before. |
OAUTH_GITLAB_ENABLED | gitlab.enabled | oauth | false | Enable Gitlab OAuth2 authentication. |
OAUTH_GOOGLE_CLIENT_ID | google.clientID | oauth | clientid | ClientID for OAuth2 authentication with Google. |
OAUTH_GOOGLE_CLIENT_SECRET | google.clientSecret | oauth | supersecret | ClientSecret for OAuth2 authentication with Google. |
OAUTH_GOOGLE_CREATE_USERS | google.createUsers | oauth | false | A user logged in with Google OAuth2 should be created automatically when it doesn't exist before. |
OAUTH_GOOGLE_ENABLED | google.enabled | oauth | false | Enable Google OAuth2 authentication. |
LOG_LEVEL | debug | Specify log level, one of: trace, debug, info, off. | ||
LOG_JSON | false | Format log output as JSON. | ||
LOG_COLOR | true | Colorize log output. | ||
CONFIG_FILE | config.yml | The config file path. |
config.yml:
core:
listeningAddress: :8123
externalUrl: https://wg-test.test.com
adminUser: [email protected]
adminPass: test
editableKeys: true
createDefaultPeer: false
ldapEnabled: true
mailFrom: WireGuard VPN <[email protected]>
ldap:
url: ldap://10.10.10.10:389
dn: DC=test,DC=test
startTLS: false
user: [email protected]
pass: test
adminGroup: CN=WireGuardAdmins,CN=Users,DC=test,DC=test
database:
typ: sqlite
database: data/wg_portal.db
oauth:
redirectURL: /callback # will become https://wg-test.test.com/oauth/callback
bitbucket:
enabled: false
createUsers: false
clientID: clientid
clientSecret: supersecret
github:
enabled: false
createUsers: false
clientID: clientid
clientSecret: supersecret
gitlab:
enabled: false
createUsers: false
clientID: clientid
clientSecret: supersecret
google:
enabled: false
createUsers: false
clientID: clientid
clientSecret: supersecret
oidc:
# example for Keycloak as OIDC provider
- discoveryURL: https://keycloakserver/auth/realms/realmname
createUsers: false
verifyEmail: false
clientID: clientid
clientSecret: supersecret
button:
icon: keycloak
label: Sign In with Keycloak
# example for Google as OIDC provider
- discoveryURL: https://accounts.google.com
createUsers: false
verifyEmail: false
clientID: clientid
clientSecret: supersecret
button:
icon: openid
label: Sign In with Google
email:
host: smtp.gmail.com
port: 587
tls: true
user: [email protected]
pass: topsecret
wg:
devices:
- wg0
- wg1
defaultDevice: wg0
configDirectory: /etc/wireguard
manageIPAddresses: true
When you activate OAuth2 or an OpenID service, you must provide a valid redirectURL
in the authentication server configuration.
The redirect URL is the same for all the login service you want to support (OAuth2 and OpenID): ${externalUrl}/oauth/callback
You can customize the value changing the /callback
part at the end.
To do so you must use the configuration parameter oauth.redirectURL
, or the environment variable OAUTH_REDIRECT_URL
.
The configuration for the OpenID services cannot be passed using environment variables, so if you want to use OpenID, you need to use the YAML configuration file.
This is the example of a OpenID service configuration:
- discoveryURL: https://accounts.google.com
createUsers: false
verifyEmail: false
clientID: clientid
clientSecret: supersecret
button:
icon: openid
label: Sign In with Google
discoveryURL
is the discovery URL of the service you want to configure.createUsers
if set tofalse
(default), a user not already present in the local database will be rejected, if set totrue
, the user will be automatically created in the local database.verifyEmail
if set tofalse
(default), theemail_verified
claim of the user will be ignored, if set totrue
theemail_verified
claim will be enforced and the user will be rejected if the email is not verifiedclientID
is the clientID of the OpenID serviceclientSecret
is the clientSecret of the OpenID servicebutton.icon
is the icon used for the login button, at the moment the supported values areopenid
andkeycloak
button.label
is the text used in the login button
WireGuard Portal offers a RESTful API to interact with.
The API is documented using OpenAPI 2.0, the Swagger UI can be found
under the URL http://<your wg-portal ip/domain>/swagger/index.html?displayOperationId=true
.
The API's unittesting may serve as an example how to make use of the API with python3 & pyswagger.
- Creating or removing WireGuard (wgX) interfaces.
- Generation or application of any
iptables
ornftables
rules. - Setting up or changing IP-addresses of the WireGuard interface on operating systems other than linux.
- Importing private keys of an existing WireGuard setup.
- Gin, HTTP web framework written in Go
- go-template, data-driven templates for generating textual output
- Bootstrap, for the HTML templates
- JQuery, for some nice JavaScript effects ;)
- MIT License. MIT or https://opensource.org/licenses/MIT
This project was inspired by wg-gen-web.