Wireguard

Installation

# pacman -S wireguard-tools
Enable backports for buster and older
# apt install wireguard

Configuration

This command creates a private key and also a matching public key
$ wg genkey | tee (name).key | wg pubkey > (name).pub

The network we will be using for wireguard will be 172.16.1.0/24

To activate a wireguard tunnel on boot use the following command
# systemctl enable --now wg-quick@wg0.service

VPN "Server" configuration

Illustration only, don't share your private keys
Private key: oFlgQ3uq4tjgRILDV3Lbqdx0mVZv2VCWWRkhJA3gcX4=
Public key: /0LMRaQCx1oMIh+eU/v4T3YQ8gAb/Qf7ulYl0zzFAkQ=

This server needs to have a public IP.
All traffic between the different nodes will be routed through here.

Kernel forwarding has to be enabled
SystemD only loads settings specified in the /etc/sysctl.d/ directory
# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.d/80-forwarding.conf
# sysctl -p /etc/sysctl.d/80-forwarding.conf

Note how the first peer has two allowed IPs.
/etc/wireguard/wg0.conf

[Interface]
Address = 172.16.1.10/24
ListenPort = 51900
PrivateKey = oFlgQ3uq4tjgRILDV3Lbqdx0mVZv2VCWWRkhJA3gcX4=
MTU = 1420
PostUp = /etc/wireguard/wg0-postup.sh
PostDown = /etc/wireguard/wg0-postdown.sh

[Peer]
PublicKey = r+TAbAN1hGh4MaIk/J5I5L3ZSAn+kCo1MJJq5YxHrl0=
AllowedIPs = 172.16.1.100/32, 172.16.1.69/32

[Peer]
PublicKey = RYXavpsPkJ8jwiBI39kz1csqgMDtVK14Lo2u8pDL0UY=
AllowedIPs = 172.16.1.101/32

[Peer]
PublicKey = 0jDtfR5GlZAHWtwxVEpukjneVj/Ace40VVdHh/eZnwU=
AllowedIPs = 172.16.1.200/32

/etc/wireguard/wg0-postup.sh

WIREGUARD_INTERFACE=wg0
WIREGUARD_LAN=172.16.1.0/24
MASQUERADE_INTERFACE=ens33

iptables -t nat -I POSTROUTING -o $MASQUERADE_INTERFACE -j MASQUERADE -s $WIREGUARD_LAN

# Add a WIREGUARD_wg0 chain to the FORWARD chain
CHAIN_NAME="WIREGUARD_$WIREGUARD_INTERFACE"
iptables -N $CHAIN_NAME
iptables -A FORWARD -j $CHAIN_NAME

# Accept related or established traffic
iptables -A $CHAIN_NAME -o $WIREGUARD_INTERFACE -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Accept traffic from (source) to (destination)
#iptables -A $CHAIN_NAME -s 172.16.1.100 -i $WIREGUARD_INTERFACE -d 172.16.1.10 -j ACCEPT
#iptables -A $CHAIN_NAME -s 172.16.1.101 -i $WIREGUARD_INTERFACE -d 172.16.1.10 -j ACCEPT
#iptables -A $CHAIN_NAME -s 172.16.1.200 -i $WIREGUARD_INTERFACE -d 172.16.1.10 -j ACCEPT
#iptables -A $CHAIN_NAME -s 172.16.1.200 -i $WIREGUARD_INTERFACE -d 172.16.1.100 -j ACCEPT

# Accept all traffic on the wireguard network
iptables -A $CHAIN_NAME -s 172.16.1.0/24 -i $WIREGUARD_INTERFACE -j ACCEPT

# Drop everything else coming through the Wireguard interface
iptables -A $CHAIN_NAME -i $WIREGUARD_INTERFACE -j DROP

# Return to FORWARD chain
iptables -A $CHAIN_NAME -j RETURN

/etc/wireguard/wg0-postdown.sh

WIREGUARD_INTERFACE=wg0
WIREGUARD_LAN=172.16.1.0/24
MASQUERADE_INTERFACE=ens33

CHAIN_NAME="WIREGUARD_$WIREGUARD_INTERFACE"

iptables -t nat -D POSTROUTING -o $MASQUERADE_INTERFACE -j MASQUERADE -s 172.16.1.0/24

# Remove and delete the WIREGUARD_wg0 chain
iptables -D FORWARD -j $CHAIN_NAME
iptables -F $CHAIN_NAME
iptables -X $CHAIN_NAME

VPN "Client" configuration

Illustration only, don't share your private keys
Private key: kAgCeU6l+RWlFxfpnGj19tzEDyYz3I4HuqHkaUmHX1Q=
Public key: r+TAbAN1hGh4MaIk/J5I5L3ZSAn+kCo1MJJq5YxHrl0=

Here we have two different interfaces configured under the same wireguard config
/etc/wireguard/wg0.conf

[Interface]
Address = 172.16.1.100/24
ListenPort = 51900
PrivateKey = kAgCeU6l+RWlFxfpnGj19tzEDyYz3I4HuqHkaUmHX1Q=
MTU = 1420

[Interface]
Address = 172.16.1.69/24
ListenPort = 51900
PrivateKey = kAgCeU6l+RWlFxfpnGj19tzEDyYz3I4HuqHkaUmHX1Q=
MTU = 1420

[Peer]
PublicKey = /0LMRaQCx1oMIh+eU/v4T3YQ8gAb/Qf7ulYl0zzFAkQ=
AllowedIPs = 172.16.1.0/24
Endpoint = 10.80.4.124:51900 #IPv4
#Endpoint = 864f:909a:4779::b:5e1b:51900 #IPv6
PersistentKeepalive = 5

Iptables no local access ssh user

Block outgoing network access for single user
Restrict internet access for user