WireGuard
WireGuard is an easy to use VPN that provides a secure connection between two parties using public key authentication.
Installation
Installing WireGuard
On CentOS / RHEL / Rocky Linux 8, you will need to install the WireGuard repos and EPEL for DKMS dependencies.
# curl -Lo /etc/yum.repos.d/wireguard.repo https://copr.fedorainfracloud.org/coprs/jdoss/wireguard/repo/epel-8/jdoss-wireguard-epel-8.repo
# yum -y install epel-release
# yum install wireguard-dkms wireguard-tools
On OracleLinux 8, the EPEL repo is named differently. Instead of epel-release, you'll need to install Oracle's version and enable the repo.
# curl -Lo /etc/yum.repos.d/wireguard.repo https://copr.fedorainfracloud.org/coprs/jdoss/wireguard/repo/epel-8/jdoss-wireguard-epel-8.repo
# yum -y install oracle-epel-release-el8
# yum-config-manager --enable ol8_developer_EPEL
# yum install wireguard-dkms wireguard-tools
On Ubuntu, WireGuard is part of the official repos and you simply need to install the package:
# apt install wireguard
Quick Start
Configuration
WireGuard sets up a private network amongst one or more remote endpoints using UDP traffic. All traffic sent and received by WireGuard is encrypted using the endpoint's public key and decrypted using this instance's private key. Therefore, each WireGuard node must have its own set of public/private keys.
Each WireGuard instance will create a WireGuard interface (eg. wg0). The configuration file should be named after each WireGuard interface. To get started, create a new wg0.conf file with a new private key:
## Create the directory if it doesn't already exist
# mkdir /etc/wireguard
# cd /etc/wireguard
## Generate a new private / public key
# (umask 077 && printf "[Interface]\nPrivateKey = " | sudo tee /etc/wireguard/wg0.conf > /dev/null)
# wg genkey | sudo tee -a /etc/wireguard/wg0.conf | wg pubkey | sudo tee /etc/wireguard/publickey
Continue editing the wg0.conf and specify this endpoint's address. The VPN's subnet is determined based on the address and netmask specified here. What you should end up with should be something similar to this:
# cat /etc/wireguard/wg0.conf
[Interface]
PrivateKey = **secret**
ListenPort = 5555
Address = 10.44.118.100/24
Repeat the steps above on another remote endpoint.
Connecting two or more endpoints
After installing WireGuard and configuring wg0 on two or more endpoints, you should have something similar to this:
| Site A | Site B |
|---|---|
/etc/wireguard/wg0.conf:[Interface]
PrivateKey = SITE-A-KEY
ListenPort = 5555
SaveConfig = true
Address = 192.168.1.1/24
|
/etc/wireguard/wg0.conf:[Interface]
PrivateKey = SITE-B-KEY
ListenPort = 5555
SaveConfig = true
Address = 192.168.1.2/24
|
Start WireGuard on both sites. The wg0 network device should have the address that is specified in the configuration file.
# systemctl start wg-quick@wg0
# systemctl enable wg-quick@wg0
# ip a show wg0
6: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet 192.168.1.2/24 scope global wg0
valid_lft forever preferred_lft forever
Next, connect Site A to Site B and vice versa using the each other's public key.
| Site A | Site B |
|---|---|
Determine Site A's public key by reading /etc/wireguard/publickey or by running echo SITE-A-KEY | wg pubkeyAdd the following lines to /etc/wireguard/wg0.conf and restart WireGuard.[Peer]
PublicKey = SITE-B-PUBLIC-KEY
AllowedIPs = 192.168.1.2/32
Endpoint = SITE-B-EXTERNAL-IP:5555
# wg set wg0 peer SITE-B-PUBLIC-KEY \
endpoint SITE-B-IP:5555 \
allowed-ips 0.0.0.0/0
|
Determine Site B's public key by reading /etc/wireguard/publickey or by running echo SITE-B-KEY | wg pubkeyAdd the following lines to /etc/wireguard/wg0.conf and restart WireGuard.[Peer]
PublicKey = SITE-A-PUBLIC-KEY
AllowedIPs = 192.168.1.1/32
Endpoint = SITE-A-EXTERNAL-IP:5555
# wg set wg0 peer SITE-A-PUBLIC-KEY \
endpoint SITE-A-IP:5555 \
allowed-ips 0.0.0.0/0
|
If everything worked, you should be able to ping each other's private IP address. You should also be able to see each peer's status by running wg show.
# wg show
interface: wg0
public key: (public-key)
private key: (hidden)
listening port: 5555
peer: (peer-public-key)
endpoint: 10.1.1.1:5555
allowed ips: 192.168.1.1/32
latest handshake: 55 seconds ago
transfer: 68.72 KiB received, 218.09 KiB sent
persistent keepalive: every 30 seconds
Additional peers can be added by repeating the steps above.
Accessing other internal subnets
You may use WireGuard to access private or internal subnets. Suppose that Site A has access to a private network 192.168.1.1/24 that you wish to access remotely.
To reach 192.168.1.1/24 from Site B:
- Set up WireGuard on Site A using an unused subnet (eg. Using an endpoint address of 192.168.200.1 on a subnet 192.168.200.0/24).
- Set up WireGuard on Site B and connect it to Site A (eg. with 192.168.200.2).
- Site A's [Peer] configuration for Site B must have the VPN subnet as well as the private network's subnet in the AllowedIPs list. Otherwise, the traffic will get dropped.
- On Site A's /etc/wireguard/wg0.conf configuration, ensure AllowedIPs allow these two subnets through:
[Peer]
PublicKey = SITE-B-PUBLIC-KEY
Endpoint = SITE-B-EXTERNAL-IP:5555
AllowedIPs = 192.168.1.1/24,192.168.200.0/24
- On Site B, create an internal route for 192.168.1.1/24 via 192.168.200.1. This should route everything to the private network via WireGuard.
- Run on Site B:
ip route add 192.168.1.1/24 via 192.168.200.1
- Run on Site B:
- On Site A, traffic destined for 192.168.1.1/24 via WireGuard should be routed automatically. However, you will want to enable masquerading so that traffic via WireGuard appears to be from the endpoint's local network.
- Run on Site A:
iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -d 192.168.1.0/24 -j MASQUERADE
- Run on Site A:
Troubleshooting
Missing Kernel Module
If the kernel module isn't loading, ensure that you have the proper kernel development package installed for the running kernel. Reinstall the wireguard-dkms package to trigger a kernel module rebuild. Alternatively, trigger DKMS to rebuild the module with:
# dkms status
## Build and install the version that's available on your system.
# dkms build -m wireguard/1.0.20211208
# dkms install wireguard/1.0.20211208
Connection Timeout
If your WireGuard connections are dropping or becomes unresponsive, add a PersistentKeepalive under the Peer section. Eg:
[Peer]
PublicKey = private-key
AllowedIPs = 192.168.1.1/32
Endpoint = endpoint:5555
PersistentKeepalive = 30
See Also
- https://www.digitalocean.com/community/tutorials/how-to-create-a-point-to-point-vpn-with-wireguard-on-ubuntu-16-04
- https://blog.stigok.com/2018/10/08/wireguard-vpn-server-on-centos-7.html
- https://mikkel.hoegh.org/2019/11/01/home-vpn-server-wireguard/