Wireguard Configuration

Standard configuration for Wireguard VPN. Assumes wireguard server is running on a Debian host.

Ports

Key Generation

Public/Private keys need to be generated for each machine using wireguard. A barebones utility is provided, generated keys are not OS specific.

0755 user user wggen
#!/bin/bash
# Generate wireguard keys.
WG=/usr/bin/wg
TEE=/usr/bin/tee

if [ -z "$1" ]; then
    echo "Requires name for output files."
    exit 1
else
    name=$1
fi

${WG} genkey | ${TEE} ${1}.key | ${WG} pubkey > ${1}.pub
chmod 0400 ${1}.{key,pub}

Note

Standard precautions should be used for private key material. The private key will enable anyone to impersonate that client on the VPN.

Point To Point Private Network

This setup enables a private network connection to the server, preventing other clients on that network from communicating to other clients. DNS and any network access not directly addressed to the private network will egress through the client’s standard network stack.

This creates a /24 network that all machines use, while only allowing point to point communications from each client to the server.

Server

0600 root root /etc/wireguard/server.conf
[Interface]
Address = 172.31.255.254/24
SaveConfig = False
ListenPort = 51820
PrivateKey = {SERVER PRIVATE KEY}

# Client #1
[Peer]
PublicKey = {CLIENT PUBLIC KEY}
AllowedIPs = 172.31.255.250/32

...
Bring up the tunnel for testing.
systemctl enable wg-quick@server

Clients

0600 root root /etc/wireguard/client.conf
[Interface]
Address = 172.31.255.250/24
PrivateKey = {CLIENT PRIVATE KEY}
SaveConfig = False

# Wireguard server
[Peer]
PublicKey = {SERVER PUBLIC KEY}
EndPoint = {SERVER PUBLIC IP}:51820
AllowedIPs = 172.31.255.254/32

Warning

Windows clients do not use the SaveConfig option. Remove this line if configuring a Windows client.

Bring up the tunnel for testing.
systemctl enable wg-quick@client

Testing

Show server network status and ping a client.
wg
ping 172.31.255.250
Show client network status and ping server. Pinging other clients should fail.
wg
ping 172.31.255.254
ping 172.31.255.100

VPN Network

Behaves like a traditional VPN network. All traffic and DNS lookups are routed through the connection to be resolved in the VPN server location.

Server

Enabled IP traffic forwarding on iptables.
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv6/ip_forward
0644 root root /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
Automatically adjust iptables rules to allow forwarded traffic when VPN is up.
[Interface]
Address = 172.31.255.254/24
SaveConfig = False
ListenPort = 51820
PrivateKey = {SERVER PRIVATE KEY}
PostUp = iptables -A FORWARD -i {WIREGUARD TUNNEL} -j ACCEPT; iptables -t nat -A POSTROUTING -o {INTERFACE} -j MASQUERADE; ip6tables -A FORWARD -i {WIREGUARD TUNNEL} -j ACCEPT; ip6tables -t nat -A POSTROUTING -o {INTERFACE} -j MASQUERADE
PostDown = iptables -D FORWARD -i {WIREGUARD TUNNEL} -j ACCEPT; iptables -t nat -D POSTROUTING -o {INTERFACE} -j MASQUERADE; ip6tables -D FORWARD -i {WIREGUARD TUNNEL} -j ACCEPT; ip6tables -t nat -D POSTROUTING -o {INTERFACE} -j MASQUERADE

# Client #1
[Peer]
PublicKey = {CLIENT PUBLIC KEY}
AllowedIPs = 172.31.255.250/32

...
Bring up the tunnel for testing.
systemctl enable wg-quick@server

Client

Route all traffic through VPN connection.
[Interface]
Address = 172.31.255.250/24
PrivateKey = {CLIENT PRIVATE KEY}
DNS = 1.1.1.1,1.1.2.2
SaveConfig = False

# Wireguard server
[Peer]
PublicKey = {SERVER PUBLIC KEY}
EndPoint = {SERVER PUBLIC IP}:51820
AllowedIPs = 0.0.0.0/0

Important

Set a custom DNS server if needed. DNS is resolved at the VPN server.

Bring up the tunnel for testing.
systemctl enable wg-quick@vpn-client

Testing

From the client access the Internet and verify that your data is routed through the VPN server.

A quick test can be verifying different IP’s from https://www.whatismyip.com.

Debugging

Issues with wireguard connections can be debugged by enabling dynamic debug in the kernel. Requires Kernel 5.6.

Enable wireguard dynamic kernel debugging and show log.
echo 'module wireguard +p' | sudo tee /sys/kernel/debug/dynamic_debug/control
dmesg -wH
Disable wireguard dynamic kernel debugging.
echo 'module wireguard -p' | sudo tee /sys/kernel/debug/dynamic_debug/control

Troubleshooting

SSH not working, UFW allowing SSH, No NAT

Expresses as pings between clients through the wireguard server work correctly, but SSH’ing fails. UFW on the wireguard server is enabled and allowing SSH traffic. Disabling UFW allows SSH connections to happen.

Solution: Traffic needs to be tagged in IP tables to allow wireguard to wireguard traffic to be forwarded; otherwise this is not tagged as inbound traffic to the wireguard server in UFW and subsequently blocked.

0600 root root /etc/wireguard/server.conf
iptables -A FORWARD -i {INTERFACE} -o {INTERFACE} -m conntrack --ctstate NEW -j ACCEPT

References

  1. Wireguard VPN setup

  2. SSH blocked between wireguard clients