This tutorial will tell you how you can run your own Wireguard VPN server with a webgui in an LXC container. Wireguard is a relatively new VPN protocoll which is just as secure as the long-established OpenVPN, but simpler to configure and easier on the hardware which results in faster speeds. The webgui will allow you to easily create configs for each client to grand access to your VPN to all the devices you want.
This guide is largely based on this article on Nix vs Evil.
- Proxmox 6.2 or newer as the host
- Ubuntu 18.04 or newer in the container
- Have docker-compose installed and configured (i.e. nesting activated) in the container
Though it should also work on any other host and client OS.
Install the kernel headers
sudo apt update sudo apt upgrade sudo apt install pve-headers
This one depends on your distribution and version, because wireguard is part of the 5.6 kernel and may be in your default repository. For Proxmox you have to add it to your repository list though. So open your
sudo nano /etc/apt/sources.list
and add the following line
deb http://deb.debian.org/debian buster-backports main
sudo apt update sudo apt install -t buster-backports wireguard-dkms
If you haven't restarted after the last time you updated the kernel, you have to restart now as the headers get install for the newest installed kernel and not the one you are currently running.
Enable the kernel module
modprobe wireguard echo "wireguard" >> /etc/modules-load.d/modules.conf
If you want to use regular wireguard in the LXC this step is not needed for the host (but maybe for the container. I don't know tbh). But when you want to use the access server via docker you need to do this for the host.
sudo nano /etc/sysctl.conf
and uncomment (i.e. remove the
#) from the line
sudo sysctl -p
Forward the tun device
In my case I want to run wireguard in the LXC with the number 100. If yours has a different number, you need to change the following command accordingly.
Open the config of the container. It is usually located under
sudo nano /etc/pve/lxc/100.conf
and add the line
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
This completes the steps for the host. Let's switch to the container.
You may try this step first without adding the repository as the packet is now usually included in the official repositories. If that fails you can still add the repo and try the installation again.
sudo apt update sudo apt install software-properties-common sudo add-apt-repository ppa:wireguard/wireguard sudo apt install --no-install-recommends wireguard-tools
Create the docker-compose.yml
Create an empty
docker-compose.yml where you usually store them (e.g.
~/docker/wg-access-server/) and paste the example docker-compose.yml into it, but uncomment the second volume and set a admin password under environment.
Set a private key
and put that output also in the
docker-compose.yml as your
WG_WIREGUARD_PRIVATE_KEY. If you are unsure you did it corrent, compare to my example compose file at the end.
Create a config
In the same directory as the docker-compose.yml create a
config.yaml (notice the silghtly different extension) and paste
loglevel: info storage: sqlite3:///data/db.sqlite3 dns: upstream: - "18.104.22.168"
into it. If you want to know what all this does, have a look at the documentation of wg-access-server.
You are now ready to fire it up.
docker-compose up -d
In case docker-compose complains about an unsupported version of the docker-compose file, you can either update your docker-compose or just reduce the version number of your file to 3.6 of even 3.0. More information about this issue con be found on github.
If you now visit your server on port 8000 you can add a device to your VPN with two clicks.
version: "3.7" services: wg-access-server: # to build the docker image from the source # build: # dockerfile: Dockerfile # context: . image: place1/wg-access-server container_name: wg-access-server cap_add: - NET_ADMIN volumes: - "wg-access-server-data:/data" - "./config.yaml:/config.yaml" # if you have a custom config file environment: - "WG_ADMIN_USERNAME=admin" - "WG_ADMIN_PASSWORD=mysupersecurepassword" - "WG_WIREGUARD_PRIVATE_KEY=cB6grOG+NReoxjXXAqQOP5gm6KHgxkaljTHQ8GmQ40U=" ports: - "8000:8000/tcp" - "51820:51820/udp" devices: - "/dev/net/tun:/dev/net/tun" # shared volumes with the host volumes: wg-access-server-data: driver: local