VPN using Wireguard

From OpenVZ Virtuozzo Containers Wiki
Revision as of 09:07, 11 July 2019 by Finist (talk | contribs) (Warning about WireGuard update procedure.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

This article describes how to use VPN via WireGuard inside a Virtuozzo 7 / OpenVZ 7 Container.

Warning.svg Warning:

This article describes the WireGuard configuration in an OpenVZ Container which does not survive WireGuard package update.
After WireGuard package update you have to repeat the described steps to make WireGuard working again.
If you wish to have a persistent configuration which survives WireGuard updates, please contact Virtuozzo Professional Services

Install WireGuard on the Host Node[edit]

Install vzkernel-devel package[edit]

Install vzkernel-devel package for the running kernel on the Host Node.
It's required for building third-party kernel modules.

# yum install -y vzkernel-devel

Install WireGuard packages[edit]

Virtuozzo 7 is a derivative of RHEL7/CentOS7, so use corresponding part of WireGuard installation.

# curl -Lo /etc/yum.repos.d/wireguard.repo https://copr.fedorainfracloud.org/coprs/jdoss/wireguard/repo/epel-7/jdoss-wireguard-epel-7.repo
# yum install epel-release
# yum install wireguard-dkms wireguard-tools

Allow WireGuard network interfaces inside a Container[edit]

Next, we need to patch wireguard kernel module to allow wireguard network interface to be created in Containers:
(change the path to wireguard sources if needed)

# patch /usr/src/wireguard-0.0.20190601/device.c diff-wireguard-allow-to-run-in-Containers
--- ./device.c.orig     2019-07-02 16:05:42.162373405 +0300
+++ ./device.c  2019-06-10 17:21:27.956413409 +0300
@@ -281,7 +281,7 @@ static void wg_setup(struct net_device *
 #else
        dev->tx_queue_len = 0;
 #endif
-       dev->features |= NETIF_F_LLTX;
+       dev->features |= NETIF_F_LLTX | NETIF_F_VIRTUAL;
        dev->features |= WG_NETDEV_FEATURES;
        dev->hw_features |= WG_NETDEV_FEATURES;
        dev->hw_enc_features |= WG_NETDEV_FEATURES;
Yellowpin.svg Note: Why it's required?

As Virtuozzo is very keen on security and stability, we don't allow creation of any unverified network interface inside Containers.
Only those which are safe (verified and considered properly virtualized) are allowed.

Rebuild patched wireguard kernel module[edit]

Now need to rebuild patched wireguard kernel module.
dkms does not have a command to rebuild a module, so have to remove/add the module.

# dkms remove -m wireguard -v 0.0.20190601 --all
# dkms add -m wireguard -v 0.0.20190601
# dkms build -m wireguard -v 0.0.20190601
# dkms install -m wireguard -v 0.0.20190601

Load the wireguard kernel module[edit]

Now load the wireguard kernel module on the Host Node,
it won't be automatically loaded upon request from inside a Container.

# modprobe wireguard

Create a Container[edit]

Create a Container with veth network (venet won't work here).

# vzctl create 200 --ostemplate centos7-x86_64
# prlctl set 200 --device-add net --network Bridged --dhcp yes
# vzctl start 200
# vzctl enter 200
// The Container should have an IP assigned now

Install WireGuard inside the Container[edit]

Same procedure like wireguard is installed on the Host:

[CT]# curl -Lo /etc/yum.repos.d/wireguard.repo https://copr.fedorainfracloud.org/coprs/jdoss/wireguard/repo/epel-7/jdoss-wireguard-epel-7.repo
[CT]# yum install epel-release
[CT]# yum install wireguard-dkms wireguard-tools
// may be its enough to install "wireguard-tools" package only, did not check

Now configure wireguard inside the Container using instructions from WireGuard quickstart

Allow WireGuard port(s) in firewall[edit]

Don't forget to open UDP port for wireguard on each end Node/Container.
Wireguard supports UDP only at the moment.
The port number can be checked via:

[CT]# wg | grep listening
  listening port: 35849
[CT]# firewall-cmd --permanent --zone=public --add-port=35849/udp     
success
[CT]# firewall-cmd --reload

Do the same on another Node/Container and voila!