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."
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**.
[Wireguard-UI](https://github.com/ngoduykhanh/wireguard-ui) is a *web-based* user interface to manage your **WireGuard** server setup written by [ngoduykhanh](https://github.com/ngoduykhanh) using **Go** programming language. This is an alternative way to install and easily manage your WireGuard VPN server.
If you have some technical difficulties setting up your own WireGuard server, {{<bs/alert-link"IcanhelpyoutosetupWireGuardVPNserver""https://www.fiverr.com/s/4vzPGR">}} including configuring Nginx, and SSL for WireGuard UI for small amount of money.
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">}})".
First, make sure your system is *up-to-date* and **WireGuard is installed** on your server.
```shell
sudo apt update && sudo apt upgrade
sudo 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.
```shell
sudo sysctl -p
```
This is required to allow **IP 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**.
```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"
```
> _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:
```shell
sudo ufw enable # to enable firewall, or
sudo ufw reload # to reload firewall
```
## Download & Configure WireGuard-UI
Download [Wireguard-UI from its latest release page](https://github.com/ngoduykhanh/wireguard-ui/releases) to your server. Choose the one that match with your **server OS** and **CPU architecture**.
Extract downloaded `.tar.gz` file:
```shell
tar -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`.
```shell
mkdir /opt/wireguard-ui
mv wireguard-ui /opt/wireguard-ui/
```
Create environment file for WireGuard-UI (This will be loaded using `EnvironmentFile` from `systemd` unit file later):
If you want to enable email feature, you need to set up your `SMTP_*` environment variable. See [WireGuard UI Environment Variables details](https://github.com/ngoduykhanh/wireguard-ui#environment-variables) for more information.
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:
```plain
default via 164.90.160.1 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:
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:
```shell
chmod +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:
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
```
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).
Make `wireguard-ui-daemon.service` run at start up:
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:
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](https://nginx.org/en/linux_packages.html#Ubuntu).
After Nginx installed, create **Nginx virtual host server block** for WireGuard UI:
- Replace `wgui.example.com` with your (sub)domain name.
- Replace `ssl_certificate` and `ssl_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](https://ssl-config.mozilla.org/). If you want to use [Let's Encrypt](https://letsencrypt.org/) certificate, install `python3-certbot-nginx` and request your certificate using `certbot --nginx -d wgui.example.com`.
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`.
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**.
- If you have some technical difficulties setting up your own WireGuard server, [I can help you to setup WireGuard VPN server](https://www.fiverr.com/s/4vzPGR) for small amount of money.