Wireguard-UI is a web-based user interface to manage your WireGuard server setup written by ngoduykhanh using Go programming language. This is an alternative way to install and easily manage your WireGuard VPN server.
If you prefer to install WireGuard server “from scratch” and manage it manually, you can follow my previous article about “How to Set up Your Own WireGuard VPN Server”.
Prerequisites
- A VPS (Ubuntu
22.04
or24.04
) with Public IP address - Comfortable with Linux command-line.
- Basic knowledge of IPv4 subnetting (to be honest, I’m not familiar with IPv6 subnetting, so this article is for IPv4 only).
- Able to configure Nginx Virtual Host.
In this guide, our goals:
- Server run WireGuard daemon listen on port
51822/UDP
. - WireGuard UI run from
127.0.0.1
on port5000
. - Nginx acts as reverse proxy and serve WireGuard UI service using HTTPS.
Note:
- By default, WireGuard listens on UDP port 51820, and WireGuard-UI follows this configuration by default. If you don’t use port 51822 (like this article does), please adjust your firewall and WireGuard UI Server Settings configuration accordingly.
- The YouTube videos above are not in the order of this article. They also use different IPs & subnets, so adjust them to your needs.
Prepare Your Server
First, make sure your system is up-to-date and WireGuard is installed on your server.
1sudo apt update && sudo apt upgrade
2sudo apt install wireguard
Edit /etc/sysctl.conf
and add net.ipv4.ip_forward=1
to the end of the file,
then run sudo sysctl -p
to load the new /etc/sysctl.conf
values.
1sudo sysctl -p
This is required to allow packet forwarding on your server.
Setting up Firewall
By default, Ubuntu system use comes with UFW to manage system firewall. You need to add WireGuard listen port to firewall allow list.
1sudo ufw allow OpenSSH
2sudo ufw allow 80 comment "allow HTTP" # will be used by Nginx
3sudo ufw allow 443 comment "allow HTTPS" # will be used by Nginx
4sudo ufw allow proto udp to any port 443 comment "allow QUIC" # If your Nginx support QUIC
5# Adjust ufw command below according to your WireGuard listen port
6sudo ufw allow proto udp to any port 51820 comment "WireGuard default listen port"
7sudo ufw allow proto udp to any port 51822 comment "WireGuard tutorial listen port"
Note that I also add OpenSSH to allow list to avoid losing connection to SSH if you didn’t configure / activate it before.
Enable / restart your ufw
service using:
1sudo ufw enable # to enable firewall, or
2sudo ufw reload # to reload firewall
Download & Configure WireGuard-UI
Download Wireguard-UI from its latest release page to your server. Choose the one that match with your server OS and CPU architecture.
Extract downloaded .tar.gz
file:
1tar -xvzf wireguard-ui-*.tar.gz
Create new directory /opt/wireguard-ui
and move the wireguard-ui
binary
(from extracted .tar.gz
file) to /opt/wireguard-ui
.
1mkdir /opt/wireguard-ui
2mv wireguard-ui /opt/wireguard-ui/
Create environment file for WireGuard-UI (This will be loaded using
EnvironmentFile
from systemd
unit file later):
1# /opt/wireguard-ui/.env
2SESSION_SECRET=<YOUR_STRONG_RANDOM_SECRET_KEY>
3WGUI_USERNAME=<YOUR_WIREGUARD_UI_USERNAME>
4WGUI_PASSWORD=<YOUR_WIREGUARD_UI_PASSWORD>
If you want to enable email feature, you need to set up your SMTP_*
environment variable. See WireGuard UI Environment Variables
details for more information.
Finding Server Default Interface
Then, find out which network interface used by your server as its default
route. You can use ip route list default
to see that. Example output of my
ip route list default
command:
1default via 172.xxx.xxx.201 dev eth0 proto static
Write down the word after dev
output, that’s your default network interface.
We will need that information later. In this example, my default network
interface is eth0
.
Create /opt/wireguard-ui/postup.sh
, and fill with this example config:
1#!/usr/bin/bash
2# /opt/wireguard-ui/postup.sh
3ufw route allow in on wg0 out on eth0
4iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
The postup.sh
bash script above will be executed when WireGuard service is
started.
Create /opt/wireguard-ui/postdown.sh
, and fill with this example config:
1#!/usr/bin/bash
2# /opt/wireguard-ui/postdown.sh
3ufw route delete allow in on wg0 out on eth0
4iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
The postdown.sh
bash script above will be executed when WireGuard service is
stopped.
Replace eth0
value from those two bash script above with your default network
interface (see Finding Server Default Interface
section above).
Then, make those two bash script (/opt/wireguard-ui/postup.sh
and
/opt/wireguard-ui/postdown.sh
) executable:
1chmod +x /opt/wireguard-ui/post*.sh
WireGuard-UI daemon SystemD
To manage WireGuard-UI daemon (Web UI) using systemd
, create
/etc/systemd/system/wireguard-ui-daemon.service
systemd file, and fill with
this following configuration:
1[Unit]
2Description=WireGuard UI Daemon
3Wants=network-online.target
4After=network-online.target
5
6[Service]
7User=root
8Group=root
9Type=simple
10WorkingDirectory=/opt/wireguard-ui
11EnvironmentFile=/opt/wireguard-ui/.env
12ExecStart=/opt/wireguard-ui/wireguard-ui -bind-address "127.0.0.1:5000"
13
14[Install]
15WantedBy=multi-user.target
The systemd
configuration will run WireGuard UI daemon on 127.0.0.1:5000
.
Now reload your systemd
daemon configuration and try to start
wireguard-ui-daemon.service
.
1sudo systemctl daemon-reload
2sudo systemctl start wireguard-ui-daemon.service
Verify your wireguard-ui-daemon.service
is running properly by using
systemctl status wireguard-ui-daemon.service
:
1● wireguard-ui-daemon.service - WireGuard UI Daemon
2 Loaded: loaded (/etc/systemd/system/wireguard-ui-daemon.service; disabled; vendor preset: enabled)
3 Active: active (running) since Mon 2023-06-05 23:57:47 UTC; 5s ago
4 Main PID: 4388 (wireguard-ui)
5 Tasks: 4 (limit: 1115)
6 Memory: 17.1M
7 CPU: 1.243s
8 CGroup: /system.slice/wireguard-ui-daemon.service
9 └─4388 /opt/wireguard-ui/wireguard-ui -bind-address 127.0.0.1:5000
10
11Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Git Ref : refs/tags/v0.5.1
12Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Build Time : 06-05-2023 23:57:47
13Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Git Repo : https://github.com/ngoduykhanh/wireguard-ui
14Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Authentication : true
15Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Bind address : 127.0.0.1:5000
16Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Email from :
17Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Email from name : WireGuard UI
18Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Custom wg.conf :
19Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Base path : /
20Jun 05 23:57:49 fra1-do1 wireguard-ui[4388]: ⇨ http server started on 127.0.0.1:5000
If everything works well, you can see that WireGuard-UI is listening on
127.0.0.1:5000
(but, for now, you cannot access the web UI from remote
machine until you finished the Configuring Nginx for WireGuard-UI
section below).
Make wireguard-ui-daemon.service
run at start up:
1sudo systemctl enable wireguard-ui-daemon.service
Auto Restart WireGuard Daemon
Because WireGuard-UI only takes care of WireGuard configuration generation,
another systemd
is required to watch for the changes and restart the
WireGuard service. Create /etc/systemd/system/wgui.service
and fill with
this following example:
1[Unit]
2Description=Restart WireGuard
3After=network.target
4
5[Service]
6Type=oneshot
7ExecStart=/usr/bin/systemctl restart [email protected]
8
9[Install]
10RequiredBy=wgui.path
Then, create /etc/systemd/system/wgui.path
:
1[Unit]
2Description=Watch /etc/wireguard/wg0.conf for changes
3
4[Path]
5PathModified=/etc/wireguard/wg0.conf
6
7[Install]
8WantedBy=multi-user.target
Apply systemd
configurations changes by issuing this following commands:
1systemctl daemon-reload
2systemctl enable wgui.{path,service}
3systemctl start wgui.{path,service}
Configuring Nginx for WireGuard-UI
If Nginx not installed on your server, you need to install it first. You can use Nginx from Ubuntu default repository or using Nginx official repository for Ubuntu.
After Nginx installed, create Nginx virtual host server block for WireGuard UI:
1server {
2 listen 80;
3 server_name wgui.example.com;
4 root /usr/share/nginx;
5 access_log off;
6 location /.well-known/acme-challenge/ { allow all; }
7 location / { return 301 https://$host$request_uri; }
8}
9
10server {
11 listen 443 ssl http2;
12 server_name wgui.example.com;
13 access_log off;
14
15 ssl_certificate /path/to/your/ssl/cert/fullchain.pem;
16 ssl_certificate_key /path/to/your/ssl/cert/privkey.pem;
17
18 root /usr/share/nginx;
19 location / {
20 add_header Cache-Control no-cache;
21
22 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
23 proxy_set_header X-Forwarded-Proto $scheme;
24 proxy_set_header X-Real-IP $remote_addr;
25 proxy_set_header Host $http_host;
26 proxy_pass http://127.0.0.1:5000/;
27 }
28}
- Replace
wgui.example.com
with your (sub)domain name. - Replace
ssl_certificate
andssl_certificate_key
with your certificate files.
Now restart your nginx configuration sudo systemctl restart nginx
.
Please note that Nginx server block configuration above is very basic
config. If you need recommended SSL configuration for Nginx, follow this
Mozilla SSL Configuration Generator. If you want to use
Let’s Encrypt certificate, install python3-certbot-nginx
and
request your certificate using certbot --nginx -d wgui.example.com
.
Using WireGuard-UI
Now after configuring all those required services, it’s time to configure our
WireGuard config using WireGuard-UI. Go to your WireGuard-UI (sub)domain and
login with username and password you’ve configured before from
/etc/wireguard-ui/.env
.
Do not press “Apply Config” before you finished configuring your WireGuard setting from WireGuard UI.
Go to “WireGuard Server” page and configure WireGuard config:
- Server Interface Addresses:
10.10.88.1/24
- Listen Port:
51822
- Post Up Script:
/opt/wireguard-ui/postup.sh
- Post Down Script:
/opt/wireguard-ui/postdown.sh
Then go to “Global Settings”, verify that all your config is correct (especially for “Endpoint Address” and “WireGuard Config File Path”).
After that, try to Apply your configuration.
Verify that everything is running (try to check using wg show
or ss -ulnt
from command-line).
Creating Peer (client)
Creating peers using WireGuard UI is pretty simple, all you need to do is press "+ New Client" button from the top right of the page and fill required information. You only need to fill “Name” field for most use case.
After adding your peers (clients), press “Apply Config” and try to connect to your WireGuard VPN server from your devices. The configuration file for your devices can be downloaded from WireGuard UI. You can also easily scan configuration for your mobile devices by scanning configuration QR code.
What next? How about Configure WireGuard VPN Clients?