2023-06-06 23:48:31 +07:00
---
title: "Installing WireGuard-UI to Manage Your WireGuard VPN Server"
2023-06-18 01:20:54 +07:00
description: "To manage WireGuard peers (client) on a single server easily, you can use WireGuard-UI, a web-based user interface to manage your WireGuard setup written in Go."
2024-10-13 21:37:36 +07:00
summary: "To manage WireGuard peers (client) on a single server easily, you can use WireGuard-UI, a web-based user interface to manage your WireGuard setup written in Go."
2023-06-06 23:48:31 +07:00
# linkTitle:
date: 2023-06-06T04:20:43+07:00
lastmod:
draft: false
noindex: false
# comments: false
nav_weight: 1000
# nav_icon:
# vendor: bootstrap
# name: toggles
# color: '#e24d0e'
series:
2024-10-13 21:37:36 +07:00
- WireGuard VPN
2023-06-06 23:48:31 +07:00
categories:
2024-10-13 21:37:36 +07:00
- Privacy
- SysAdmin
- Networking
- Self-Hosted
2023-06-06 23:48:31 +07:00
tags:
2024-10-13 21:37:36 +07:00
- WireGuard
- WireGuard UI
- Nginx
2023-06-06 23:48:31 +07:00
images:
authors:
2024-10-13 21:37:36 +07:00
- ditatompel
2023-06-06 23:48:31 +07:00
---
2024-10-13 21:37:36 +07:00
[Wireguard-UI][wireguard_ui_gh] is a _web-based_ user interface to manage your
**WireGuard** server setup written by [ngoduykhanh][ngoduykhanh] using **Go**
programming language. This is an alternative way to install and easily manage
your WireGuard VPN server.
2023-06-06 23:48:31 +07:00
2024-10-13 21:37:36 +07:00
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]({{< ref " / tutorials / how-to-setup-your-own-wireguard-vpn-server / index . md " > }})".
## Prerequisites
2023-06-06 23:48:31 +07:00
2024-10-13 21:37:36 +07:00
- A **VPS** (**Ubuntu** `22.04` or `24.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_ .
2023-06-06 23:48:31 +07:00
2024-10-13 21:37:36 +07:00
In this guide, our goals:
2024-04-07 19:44:13 +07:00
2024-10-13 21:37:36 +07:00
- Server run _**WireGuard** daemon_ listen on port `51822/UDP` .
- **WireGuard UI** run from `127.0.0.1` on port `5000` .
- **Nginx** acts as _reverse proxy_ and serve **WireGuard UI** service using
**HTTPS** .
2023-06-06 23:48:31 +07:00
2024-10-13 21:37:36 +07:00
{{< youtube o_JcLMjYI1A > }}
2023-06-06 23:48:31 +07:00
2024-10-13 21:37:36 +07:00
> Note: The YouTube videos above are not in the order of this article. They
> also use different IPs & subnets, so adjust them to your needs.
2023-06-06 23:48:31 +07:00
## Prepare Your Server
2024-10-13 21:37:36 +07:00
First, make sure your system is _up-to-date_ and **WireGuard is installed**
on your server.
2023-06-06 23:48:31 +07:00
```shell
sudo apt update & & sudo apt upgrade
sudo apt install wireguard
```
2024-10-13 21:37:36 +07:00
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.
2023-06-06 23:48:31 +07:00
```shell
sudo sysctl -p
```
2024-10-13 21:37:36 +07:00
This is required to allow **packet forwarding** on your server.
2023-06-06 23:48:31 +07:00
### Setting up Firewall
2024-10-13 21:37:36 +07:00
By default, **Ubuntu** system use comes with **UFW** to manage system
_firewall_. You need to **add WireGuard listen port to firewall allow list** .
2023-06-06 23:48:31 +07:00
```shell
sudo ufw allow OpenSSH
sudo ufw allow 80 comment "allow HTTP" # will be used by Nginx
sudo ufw allow 443 comment "allow HTTPS" # will be used by Nginx
sudo ufw allow proto udp to any port 443 comment "allow QUIC" # If your Nginx support QUIC
sudo ufw allow proto udp to any port 51822 comment "WireGuard listen port"
2024-11-24 03:33:00 +07:00
sudo ufw allow proto udp to any port 51820 comment "WireGuard listen port"
2023-06-06 23:48:31 +07:00
```
2024-10-13 21:37:36 +07:00
> _Note that I also add **OpenSSH** to allow list to avoid losing connection to
> SSH if you didn't configure / activate it before._
2023-06-06 23:48:31 +07:00
Enable / restart your `ufw` service using:
2024-10-13 21:37:36 +07:00
2023-06-06 23:48:31 +07:00
```shell
sudo ufw enable # to enable firewall, or
sudo ufw reload # to reload firewall
```
## Download & Configure WireGuard-UI
2024-10-13 21:37:36 +07:00
Download [Wireguard-UI from its latest release page][wireguard_ui_release] to
your server. Choose the one that match with your **server OS** and **CPU
architecture**.
2023-06-06 23:48:31 +07:00
Extract downloaded `.tar.gz` file:
2024-10-13 21:37:36 +07:00
2023-06-06 23:48:31 +07:00
```shell
tar -xvzf wireguard-ui-*.tar.gz
```
2024-10-13 21:37:36 +07:00
Create new directory `/opt/wireguard-ui` and move the `wireguard-ui` _binary_
(from extracted `.tar.gz` file) to `/opt/wireguard-ui` .
2023-06-06 23:48:31 +07:00
```shell
mkdir /opt/wireguard-ui
mv wireguard-ui /opt/wireguard-ui/
```
2024-10-13 21:37:36 +07:00
Create environment file for WireGuard-UI (This will be loaded using
`EnvironmentFile` from `systemd` unit file later):
2023-06-06 23:48:31 +07:00
```plain
# /opt/wireguard-ui/.env
SESSION_SECRET=< YOUR_STRONG_RANDOM_SECRET_KEY >
WGUI_USERNAME=< YOUR_WIREGUARD_UI_USERNAME >
WGUI_PASSWORD=< YOUR_WIREGUARD_UI_PASSWORD >
```
2024-10-13 21:37:36 +07:00
If you want to enable email feature, you need to set up your `SMTP_*`
environment variable. See [WireGuard UI Environment Variables
details][wireguard_ui_env] for more information.
2023-06-06 23:48:31 +07:00
### Finding Server Default Interface
2024-10-13 21:37:36 +07:00
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:
2023-06-06 23:48:31 +07:00
```plain
2024-10-13 21:37:36 +07:00
default via 172.xxx.xxx.201 dev eth0 proto static
2023-06-06 23:48:31 +07:00
```
2024-10-13 21:37:36 +07:00
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` .
2023-06-06 23:48:31 +07:00
Create `/opt/wireguard-ui/postup.sh` , and fill with this example config:
2024-10-13 21:37:36 +07:00
2023-06-06 23:48:31 +07:00
```bash
#!/usr/bin/bash
# /opt/wireguard-ui/postup.sh
ufw route allow in on wg0 out on eth0
iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
```
2024-10-13 21:37:36 +07:00
The `postup.sh` bash script above will be executed when WireGuard service is
**started**.
2023-06-06 23:48:31 +07:00
2024-02-24 00:19:46 +07:00
Create `/opt/wireguard-ui/postdown.sh` , and fill with this example config:
2024-10-13 21:37:36 +07:00
2023-06-06 23:48:31 +07:00
```bash
#!/usr/bin/bash
# /opt/wireguard-ui/postdown.sh
ufw route delete allow in on wg0 out on eth0
iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
```
2024-10-13 21:37:36 +07:00
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](#finding-server-default-interface) above_).
Then, make those two bash script (`/opt/wireguard-ui/postup.sh` and
`/opt/wireguard-ui/postdown.sh` ) executable:
2023-06-06 23:48:31 +07:00
```shell
chmod +x /opt/wireguard-ui/post*.sh
```
### WireGuard-UI daemon SystemD
2024-10-13 21:37:36 +07:00
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:
2023-06-06 23:48:31 +07:00
```systemd
[Unit]
Description=WireGuard UI Daemon
Wants=network-online.target
After=network-online.target
[Service]
User=root
Group=root
Type=simple
WorkingDirectory=/opt/wireguard-ui
EnvironmentFile=/opt/wireguard-ui/.env
ExecStart=/opt/wireguard-ui/wireguard-ui -bind-address "127.0.0.1:5000"
[Install]
WantedBy=multi-user.target
```
2024-10-13 21:37:36 +07:00
2023-06-06 23:48:31 +07:00
The `systemd` configuration will run WireGuard UI daemon on `127.0.0.1:5000` .
2024-10-13 21:37:36 +07:00
Now reload your `systemd` daemon configuration and try to start
`wireguard-ui-daemon.service` .
2023-06-06 23:48:31 +07:00
```shell
sudo systemctl daemon-reload
sudo systemctl start wireguard-ui-daemon.service
```
2024-10-13 21:37:36 +07:00
Verify your `wireguard-ui-daemon.service` is running properly by using
`systemctl status wireguard-ui-daemon.service` :
2023-06-06 23:48:31 +07:00
```plain
● wireguard-ui-daemon.service - WireGuard UI Daemon
Loaded: loaded (/etc/systemd/system/wireguard-ui-daemon.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 2023-06-05 23:57:47 UTC; 5s ago
Main PID: 4388 (wireguard-ui)
Tasks: 4 (limit: 1115)
Memory: 17.1M
CPU: 1.243s
CGroup: /system.slice/wireguard-ui-daemon.service
└─4388 /opt/wireguard-ui/wireguard-ui -bind-address 127.0.0.1:5000
Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Git Ref : refs/tags/v0.5.1
Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Build Time : 06-05-2023 23:57:47
Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Git Repo : https://github.com/ngoduykhanh/wireguard-ui
Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Authentication : true
Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Bind address : 127.0.0.1:5000
Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Email from :
Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Email from name : WireGuard UI
Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Custom wg.conf :
Jun 05 23:57:47 fra1-do1 wireguard-ui[4388]: Base path : /
Jun 05 23:57:49 fra1-do1 wireguard-ui[4388]: ⇨ http server started on 127.0.0.1:5000
```
2024-10-13 21:37:36 +07:00
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](#configuring-nginx-for-wireguard-ui)_ below).
2023-06-06 23:48:31 +07:00
Make `wireguard-ui-daemon.service` run at start up:
2024-10-13 21:37:36 +07:00
2023-06-06 23:48:31 +07:00
```shell
sudo systemctl enable wireguard-ui-daemon.service
```
### Auto Restart WireGuard Daemon
2024-10-13 21:37:36 +07:00
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:
2023-06-06 23:48:31 +07:00
```systemd
[Unit]
Description=Restart WireGuard
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl restart wg-quick@wg0.service
[Install]
RequiredBy=wgui.path
```
Then, create `/etc/systemd/system/wgui.path` :
2024-10-13 21:37:36 +07:00
2023-06-06 23:48:31 +07:00
```systemd
[Unit]
Description=Watch /etc/wireguard/wg0.conf for changes
[Path]
PathModified=/etc/wireguard/wg0.conf
[Install]
WantedBy=multi-user.target
```
Apply `systemd` configurations changes by issuing this following commands:
2024-10-13 21:37:36 +07:00
2023-06-06 23:48:31 +07:00
```shell
2023-06-18 01:20:54 +07:00
systemctl daemon-reload
2023-06-06 23:48:31 +07:00
systemctl enable wgui.{path,service}
systemctl start wgui.{path,service}
```
### Configuring Nginx for WireGuard-UI
2024-10-13 21:37:36 +07:00
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][nginx_official_ubuntu].
After Nginx installed, create **Nginx virtual host server block** for
WireGuard UI:
2023-06-06 23:48:31 +07:00
```nginx
server {
listen 80;
server_name wgui.example.com;
root /usr/share/nginx;
access_log off;
location /.well-known/acme-challenge/ { allow all; }
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl http2;
server_name wgui.example.com;
access_log off;
ssl_certificate /path/to/your/ssl/cert/fullchain.pem;
ssl_certificate_key /path/to/your/ssl/cert/privkey.pem;
root /usr/share/nginx;
location / {
add_header Cache-Control no-cache;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:5000/;
}
}
```
2024-10-13 21:37:36 +07:00
- Replace `wgui.example.com` with your (sub)domain name.
- Replace `ssl_certificate` and `ssl_certificate_key` with your certificate
files.
2023-06-06 23:48:31 +07:00
Now restart your nginx configuration `sudo systemctl restart nginx` .
2024-10-13 21:37:36 +07:00
**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][mozilla_ssl_config]. If you want to use
[Let's Encrypt][letsencrypt] certificate, install `python3-certbot-nginx` and
request your certificate using `certbot --nginx -d wgui.example.com` .
2023-06-06 23:48:31 +07:00
## Using WireGuard-UI
2024-10-13 21:37:36 +07:00
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._
2023-06-06 23:48:31 +07:00
Go to ** "WireGuard Server"** page and configure WireGuard config:
2024-10-13 21:37:36 +07:00
- **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`
2023-06-06 23:48:31 +07:00
2024-02-24 00:19:46 +07:00
![WireGuard-UI Server Settings ](wg-ui-server-config.png#center )
2023-06-06 23:48:31 +07:00
2024-10-13 21:37:36 +07:00
Then go to ** "Global Settings"**, verify that all your config is correct
(especially for ** "Endpoint Address"** and ** "WireGuard Config File Path"**).
2023-06-06 23:48:31 +07:00
After that, try to **Apply** your configuration.
2024-10-13 21:37:36 +07:00
Verify that everything is running (try to check using `wg show` or `ss -ulnt`
from _command-line_ ).
2023-06-06 23:48:31 +07:00
### Creating Peer (client)
2024-10-13 21:37:36 +07:00
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** .
2023-06-06 23:48:31 +07:00
![WireGuard UI clients page ](wg-ui-clients.png#center )
2023-06-07 06:39:41 +07:00
What next? How about [Configure WireGuard VPN Clients ]({{< ref "/tutorials/configure-wireguard-vpn-clients/index.md" >}} )?
2024-10-13 21:37:36 +07:00
[wireguard_ui_gh]: https://github.com/ngoduykhanh/wireguard-ui "WireGuard-UI GitHub Repo"
[ngoduykhanh]: https://github.com/ngoduykhanh "ngoduykhanh GitHub profile"
[wireguard_ui_release]: https://github.com/ngoduykhanh/wireguard-ui/releases "WireGuard UI release page"
[wireguard_ui_env]: https://github.com/ngoduykhanh/wireguard-ui#environment-variables "WireGuard UI environment variable"
[nginx_official_ubuntu]: https://nginx.org/en/linux_packages.html#Ubuntu "Nginx official repository for Ubuntu"
[mozilla_ssl_config]: https://ssl-config.mozilla.org/ "Mozilla SSL config"
[letsencrypt]: https://letsencrypt.org/ "LetsEncrypt Website"