WireGuard: Difference between revisions

From Leo's Notes
This page was last edited on 2 February 2022, at 22:06.
No edit summary
Line 84: Line 84:
!Site B
!Site B
|-
|-
|Determine Site A's public key by reading <code>/etc/wireguard/publickey</code> or by running <code><nowiki>echo SITE-A-KEY | wg pubkey</nowiki></code>
|Determine Site A's public key by reading <code>/etc/wireguard/publickey</code> or by running <code><nowiki>echo SITE-A-KEY | wg pubkey</nowiki></code>Add the following lines to <code>/etc/wireguard/wg0.conf</code> and restart WireGuard.{{highlight|lang=text|code=
 
Add the following lines to <code>/etc/wireguard/wg0.conf</code> and restart WireGuard.{{highlight|lang=text|code=
[Peer]
[Peer]
PublicKey = SITE-B-PUBLIC-KEY
PublicKey = SITE-B-PUBLIC-KEY
Line 97: Line 95:
| lang = terminal
| lang = terminal
}}
}}
|Determine Site B's public key by reading <code>/etc/wireguard/publickey</code> or by running <code><nowiki>echo SITE-B-KEY | wg pubkey</nowiki></code>
|Determine Site B's public key by reading <code>/etc/wireguard/publickey</code> or by running <code><nowiki>echo SITE-B-KEY | wg pubkey</nowiki></code>Add the following lines to <code>/etc/wireguard/wg0.conf</code> and restart WireGuard.{{highlight|lang=text|code=
Add the following lines to <code>/etc/wireguard/wg0.conf</code> and restart WireGuard.{{highlight|lang=text|code=
[Peer]
[Peer]
PublicKey = SITE-A-PUBLIC-KEY
PublicKey = SITE-A-PUBLIC-KEY
Line 135: Line 132:


# 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 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)
# Set up WireGuard on Site B and connect it to Site A (eg. with 192.168.200.2).
# 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.  Do this by running on Site B: <code>ip route add 192.168.1.1/24 via 192.168.200.1</code>
#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, 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..  Do this by running on Site A: <code>iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -d 192.168.1.0/24 -j MASQUERADE</code>
#*On Site A's /etc/wireguard/wg0.conf configuration, ensure AllowedIPs allow these two subnets through:
{{Highlight
| code = [Peer]
PublicKey = SITE-B-PUBLIC-KEY
Endpoint = SITE-B-EXTERNAL-IP:5555
AllowedIPs = 192.168.1.1/24,192.168.200.0/24
| lang = terminal
}}
# 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: <code>ip route add 192.168.1.1/24 via 192.168.200.1</code>
# 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: <code>iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -d 192.168.1.0/24 -j MASQUERADE</code>


== Troubleshooting ==
== Troubleshooting ==

Revision as of 22:06, 2 February 2022

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
or run:
# 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
or run:
# 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:

  1. 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).
  2. Set up WireGuard on Site B and connect it to Site A (eg. with 192.168.200.2).
  3. 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
  1. 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
  2. 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

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