WireGuard is an exciting, new, extremely simple VPN system that uses state-of-the-art cryptography. Its Linux implementation runs in the kernel, which provides a significant performance boost compared to traditional userspace VPN implementations
The WireGuard kernel module is great, but sometimes you might not be able to install new kernel modules. One example scenario is on a VPS that uses OpenVZ or LXC. For these cases, we can use wireguard-go, a userspace implementation of WireGuard. This is the same implementation used on MacOS, Windows, and the WireGuard mobile apps. This implementation is slower than the kernel module, but still plenty fast.
This post focuses on Debian, however the instructions should mostly work on other Linux distros too.
Install WireGuard Tools
We need to install the WireGuard tools (wg-quick
). On Debian, you can run this as root:
echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list
printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' > /etc/apt/preferences.d/limit-unstable
apt update
apt install wireguard-tools --no-install-recommends
(see the WireGuard site for instructions if you're not on Debian)
Install Go
Unfortunately, since wireguard-go is not packaged for Debian, we need to compile it ourselves. To compile it, we first need to install the latest version of the Go programming language (currently version 1.13.4):
cd /tmp
wget https://dl.google.com/go/go1.13.4.linux-amd64.tar.gz
tar zvxf go1.13.4.linux-amd64.tar.gz
sudo mv go /opt/go1.13.4
sudo ln -s /opt/go1.13.4/bin/go /usr/local/bin/go
Now, running go version
should show the version number.
Compile wireguard-go
Now that we've got Go, we can download and compile wireguard-go. Download the latest release version:
cd /usr/local/src
wget https://git.zx2c4.com/wireguard-go/snapshot/wireguard-go-0.0.20191012.tar.xz
tar xvf wireguard-go-0.0.20191012.tar.xz
cd wireguard-go-0.0.20191012
If you are on a system with limited RAM (such as a 256 MB or lower "LowEndSpirit" VPS), you will need to do a small tweak to the wireguard-go code to make it use less RAM. Open device/queueconstants_default.go
and replace this:
MaxSegmentSize = (1 << 16) - 1 // largest possible UDP datagram
PreallocatedBuffersPerPool = 0 // Disable and allow for infinite memory growth
With these values (taken from device/queueconstants_ios.go
):
MaxSegmentSize = 1700
PreallocatedBuffersPerPool = 1024
This will make it use a fixed amount of RAM (~20 MB max), rather than allowing memory usage to grow infinitely.
Now we can compile it:
make
# "Install" it
sudo cp wireguard-go /usr/local/bin
Running wireguard-go --version
should work and show the version number.
If you have multiple VPSes that use the same OS version and architecture (eg. Debian 10, 64-bit), you can compile it on one of them and then just copy the wireguard-go
binary to all the others.
Configuration
wg0.conf
You'll need to configure /etc/wireguard/wg0.conf
to contain the configuration for your peer. This post won't go into significant detail about this; please refer to another general WireGuard guide (like this one) for more details. The basic jist is that you need to run:
wg genkey | tee privatekey | wg pubkey > publickey
to generate a public/private key pair for each peer, then configure the [Interface]
with the private key for the peer, and a [Peer]
section for each peer that can connect to it.
Your wg0.conf
should end up looking something like:
[Interface]
Address = 10.123.0.2
PrivateKey = 12345678912345678912345678912345678912345678
ListenPort = 51820
[Peer]
PublicKey = 987654321987654321987654321987654321987654321
AllowedIPs = 10.123.0.1/32
Endpoint = 198.51.100.1:51820
systemd
We need to modify the systemd unit to pass the WG_I_PREFER_BUGGY_USERSPACE_TO_POLISHED_KMOD
flag to wireguard-go, to allow it to run on Linux. Open /lib/systemd/system/wg-quick@.service
, find:
Environment=WG_ENDPOINT_RESOLUTION_RETRIES=infinity
and add this line directly below:
Environment=WG_I_PREFER_BUGGY_USERSPACE_TO_POLISHED_KMOD=1
Finally, enable and start the systemd service:
systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0
Enabling the systemd service will connect the VPN on boot, and starting the systemd service will connect it right now.
You're Done
Now, everything should be working! You can check the status of wg-quick
by running systemctl status wg-quick@wg0
, which should return something like:
● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
Loaded: loaded (/lib/systemd/system/wg-quick@.service; enabled; vendor preset: enabled)
Active: active (exited) since Mon 2019-07-01 06:30:30 UTC; 1 day 22h ago
Running wg
will give you a list of all the peers, and some details about them:
interface: wg0
public key: 987654321987654321987654321987654321987654321
private key: (hidden)
listening port: 38917
peer: 987654321987654321987654321987654321987654321
endpoint: 198.51.100.1:51820
allowed ips: 10.123.0.1/32
latest handshake: 1 day, 22 hours, 59 minutes, 34 seconds ago
transfer: 2.75 KiB received, 2.83 KiB sent
Comments
This is what I get on debian OpenVZ. Any help please.
INFO: (wg0) 2019/08/02 15:29:46 Starting wireguard-go version v0.0.20190517-68-g1ff37e2-dirty
ERROR: (wg0) 2019/08/02 15:29:46 Failed to create TUN device: operation not permitted
Unable to access interface: Protocol not supported
[#] ip link delete dev wg0
Cannot find device "wg0"
This likely means that your VPS provider has not enabled TUN support for your VPS. You'll need to contact them and get them to enable it.
Can you suggest a provider which is inexpensive and reliable? As you mentioned in the other post $4/year that's a crazy attractive price.
If you don't need much RAM or disk space, MrVM has some plans starting at $4/year for 128 MB RAM and 3 GB disk space: https://mrvm.net/natvps/. I usually stick to 256 MB RAM as a minimum though. I'm using several of these 256 MB RAM MrVM VPSes for my site at https://dnstools.ws/, as it needs locations all around the world.
I got this failure while compiling on a new OpenVZ box, using Debian 9:
Makefile:20: recipe for target 'wireguard-go' failed
make[1]: *** [wireguard-go] Error 2
Makefile:11: recipe for target 'generate-version-and-build' failed
make: *** [generate-version-and-build] Error 2
boink@localhost:/usr/local/src/wireguard-go$ go version
go version go1.13.3 linux/amd64
Will it not compile on go1.13.1?
What's the full output you got from the build?
I made the mistake of trying to compile it on a OpenVZ VPS. I got memory errors *doh*
Instead, I compiled it on a VPS with enough memory. I will see how it goes. I used the git clone function.
I just uploaded a version that I compiled myself. Try that and see if it works for you?
https://d.ls/wireguard/wire...
This was compiled on a 64-bit machine running Debian 10.
Thanks for the pre-compiled version. I still could not get it to compile. heh.
And using go1.12.12, it did not compile as well:
go: golang.org/x/net@v0.0.0-201... git fetch -f origin refs/heads/*:refs/heads/* refs/tags/*:refs/tags/* in /root/go/pkg/mod/cache/vcs/4a22365141bc4eea5d5ac4a1395e653f2669485db75ef119e7bbec8e19b12a21: exit status 128:
fatal: early EOF
go: error loading module requirements
Makefile:20: recipe for target 'wireguard-go' failed
make[1]: *** [wireguard-go] Error 1
Makefile:11: recipe for target 'generate-version-and-build' failed
make: *** [generate-version-and-build] Error 2
root@localhost:/usr/local/src/wireguard-go# go version
go version go1.12.12 linux/amd64
And just for good measure, it would not compile with go1.12.6 either on Debian 9, OpenVZ.
Big thanks to Daniel who wrote guide on "WireGuard on OpenVZ/LXC" https://d.sb/2019/07/wiregu... . I have tried & tested Daniel's guide and its even working on Debian OpenVZ6 & 7 NAT VPS
OpenVZ6
Debian 8.11 x64 - 128MB NAT VPS Kernal: 2.6.32-042stab130.1
Debian 8.11 x64 - 256MB NAT VPS Kernal: 2.6.32-042stab140.1
Only one client is working, tried to add multiple clients but still only one client worked
IPv6 doesn't work
Speed is faster than Openvpn
low memory usage
OpenVZ7
Debian 9.11 x64 - 512MB NAT VPS - Kernal: 4.9.0
Multiple clients working
IPv6 working
Speed is good
low memory usage
KVM
Used installer of https://github.com/l-n-s/wi...
Automated installer for setup, adding clients & clients profile file.
IPv6 worked when added manually in wg0.conf
Speed is very good
low memory usage
Big Thanks to Daniel (https://d.sb/2019/07/wiregu.... If anyone try to play, here are the details and commands. I have used Daniel's guide, please follow all steps, I added few commands as i got errors i.e apt install make and wg-quick up wg0 and wg-quick down wg0
echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list && printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' > /etc/apt/preferences.d/limit-unstable && apt update
apt install wireguard-tools --no-install-recommends
cd /tmp && wget https://dl.google.com/go/go... && tar zvxf go1.13.4.linux-amd64.tar.gz && sudo mv go /opt/go1.13.4 && sudo ln -s /opt/go1.13.4/bin/go /usr/local/bin/go
go version
(have to install make, it wasn't install in my vps)
apt install make
cd /usr/local/src && wget https://git.zx2c4.com/wireg... && tar xvf wireguard-go-0.0.20191012.tar.xz && cd wireguard-go-0.0.20191012
(set these variables if you are using VPS less than 256MB)
nano device/queueconstants_default.go
MaxSegmentSize = 1700
PreallocatedBuffersPerPool = 1024
(Run make command)
make
sudo cp wireguard-go /usr/local/bin
wireguard-go --version
(Create public & private keys for Server)
wg genkey | tee private key | wg pubkey > publickey
nano /lib/systemd/system/wg-quick@.service
add this line directly below
Environment=WG_I_PREFER_BUGGY_USERSPACE_TO_POLISHED_KMOD=1
(Perform these commands or wg0-quick will give error and wg0 interface won't come UP)
wg-quick up wg0
wg-quick down wg0
Add following two lines in Server [Interface] /etc/wireguard/wg0.conf only if you using only IPv4
PostUp = iptables -t nat -A POSTROUTING -o venet0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o venet0 -j MASQUERADE)
For IPv6, add these in /etc/wireguard/wg0.conf
PostUp = iptables -t nat -A POSTROUTING -o venet0 -j MASQUERADE; ip6tables -t nat -A POSTROUTING -o venet0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o venet0 -j MASQUERADE; ip6tables -t nat -D POSTROUTING -o venet0 -j MASQUERADE
systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0
wg
(check wg running)
Install Wireguard Client. I have used android and windows 10 client. Generate public and private keys in client software/App and set client "public key" in server wg0.conf on SERVER & set server "public key" in CLIENT
thats it
===============
Following are my conf
OpenVZ6 VPS
Server Config /etc/wireguard/wg0.conf
[Interface]
Address = 10.66.66.1/24
PrivateKey = PRIVATE KEY OF SERVER
ListenPort = PORT
PostUp = iptables -t nat -A POSTROUTING -o venet0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o venet0 -j MASQUERADE
SaveConfig = false
[Peer]
PublicKey = PUBLIC KEY OF CLIENT
AllowedIPs = 10.66.66.3/24
Client Config
[Interface]
PrivateKey = PRIVATE KEY OF CLIENT
Address = 10.66.66.3/24
DNS = 8.8.8.8, 8.8.4.4
[Peer]
PublicKey = PUBLIC KEY OF SERVER
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = SERVER IP:PORT
PersistentKeepalive = 25
Frequently used commands
nano /etc/wireguard/wg0.conf
systemctl enable wg-quick@wg0
systemctl status wg-quick@wg0
systemctl start wg-quick@wg0
systemctl stop wg-quick@wg0
wg-quick up wg0
wg-quick down wg0
===============
OpenVZ7
Server Config /etc/wireguard/wg0.conf
[Interface]
Address = 10.123.0.1/24,fd42:42:42::1/80
PrivateKey = PRIVATE KEY OF SERVER
ListenPort = PORT
PostUp = iptables -t nat -A POSTROUTING -o venet0 -j MASQUERADE; ip6tables -t nat -A POSTROUTING -o venet0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o venet0 -j MASQUERADE; ip6tables -t nat -D POSTROUTING -o venet0 -j MASQUERADE
SaveConfig = false
[Peer]
PublicKey = PUBLIC KEY OF CLIENT1
AllowedIPs = 10.123.0.3/32,fd42:42:42::3/128
[Peer]
PublicKey = PUBLIC KEY OF CLIENT2
AllowedIPs = 10.123.0.4/32,fd42:42:42::4/128
Client1 Config
[Interface]
PrivateKey = PRIVATE KEY OF CLIENT1
Address = 10.123.0.3/24, fd42:42:42::3/80
DNS = 8.8.8.8, 8.8.4.4, 2001:4860:4860::8888
[Peer]
PublicKey = PUBLIC KEY OF SERVER
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = SERVER IP:PORT
PersistentKeepalive = 25
Client2 Config
[Interface]
PrivateKey = PRIVATE KEY OF CLIENT2
Address = 10.123.0.4/24, fd42:42:42::4/80
DNS = 8.8.8.8, 8.8.4.4, 2001:4860:4860::8888
[Peer]
PublicKey = PUBLIC KEY OF SERVER
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = SERVER IP:PORT
PersistentKeepalive = 25
Has anyone ever got this working on Debian 10 (OpenVZ) ?
I just tried it on Debian 10 and there was no routing (though, I could have done something very stupid).
I went back to Debian 9, and it worked right away. Though. for the routing I am using ufw instead.
I got it working fine on Debian 10. However, I don't route anything over the VPN tunnel other than traffic directly for the VPN IP addresses (I just use it for a point-to-point VPN). That configuration doesn't require any special routing config.
Hi Everyone! This is great documentation, as OpenVZ vps's have their limitations.
Though, this documentation is a little old. Would an update be possible for the newer versions of golang (18.3) and the latest wireguard-go (0.0.20220316).
Once I have it written, I'll pass on the link. There are just a few little adjustments needed.
If you let me know what changes are required, I'll update the post. Thanks!
Great guide! Managed to get it working on Ubuntu 22.04 OpenVZ VPS. Didn't have the `tun` device so just added two commands about it:
```bash
mkdir -p /dev/net
mknod /dev/net/tun c 10 200
```