How To set up WireGuard VPN on Debian 10 Buster

Introduction

WireGuard is the next generation VPN. It has good performance, it's very secure and easy to use.

Let's see how to configure it from a debian GNU/Linux server with Windows clients.

Network diagram

VPN WireGuard | Diagram network
  • WireGuard Server :
    • OS : debian gnu/linux 10 (buster)
    • Role : wireguard server + gateway
  • Windows Client :
    • OS : Windows 10

Debian Server (Part I)

Installing

  • Add non-stable packages :
root@host:~# echo 'deb http://deb.debian.org/debian/ unstable main' >> /etc/apt/sources.list.d/unstable.list
  • Use non-stable for packages that are not available in default release only :
root@host:~# printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' >> /etc/apt/preferences.d/limit-unstable
  • Install :
root@host:~# apt update
root@host:~# apt install wireguard
  • Create private and public keys :
root@host:~# umask 077
root@host:~# wg genkey > wg-private.key
root@host:~# wg pubkey < wg-private.key > wg-public.key

Configure

  • Copy wg-private.key :
root@host:~# cat wg-private.key 
2GIURzIDBgI1Y+1Ei+i2C5kEOR53mH172MaidaVpD3M=
  • Create the /etc/wireguard/wg0.conf file and replace PrivateKey value with yours :
# define the WireGuard service
[Interface]

# contents of file wg-private.key that was recently created
PrivateKey = 2GIURzIDBgI1Y+1Ei+i2C5kEOR53mH172MaidaVpD3M=

# UDP service port; 51820 is a common choice for WireGuard
ListenPort = 51820

Create wg0 interface

  • Create the /etc/network/interfaces.d/wg0 file :
# indicate that wg0 should be created when the system boots, and on ifup -a
auto wg0

# describe wg0 as an IPv4 interface with static address
iface wg0 inet static

        # static IP address 
        address 10.0.2.1/24

        # before ifup, create the device with this ip link command
        pre-up ip link add $IFACE type wireguard

        # before ifup, set the WireGuard config from earlier
        pre-up wg setconf $IFACE /etc/wireguard/$IFACE.conf

        # after ifdown, destroy the wg0 interface
        post-down ip link del $IFACE

Windows (Client)

Download the latest software on the official website https://wireguard.com/, and install.

  • Open WireGuard VPN Client :
VPN WireGuard | Windows start menu, wireguard icon
  • Add new profile :
VPN WireGuard | Windows client, add profile
  • From Debian get public key :
root@host:~# cat wg-public.key
hlKy6azGCB0uVbCdkW8Htx23k57iWzOFJRLAYHTx5wU=
  • Configure profile :
VPN WireGuard | Windows client, edit profile
[Interface]
PrivateKey = qPGa8vQc8lAxwyuaqXqUZwSEkFnLJI2LAglZ2aIFC0g=
Address = 10.0.2.2/24

[Peer]
PublicKey = hlKy6azGCB0uVbCdkW8Htx23k57iWzOFJRLAYHTx5wU=
AllowedIPs = 0.0.0.0/1, 128.0.0.0/1
Endpoint = 192.168.1.131:51820
  • Activate :
VPN WireGuard | Windows client, activate profile

Debian Server (Part II)

WireGuard

  • Enable wireguard :
root@host:~# ifup wg0
  • Copy Windows 10 client public key :
VPN WireGuard | Windows client, copy public key
  • From the debian server Allow client public key :
root@host:~# wg set wg0 peer CLIENT_PUBLIC_KEY allowed-ips 0.0.0.0/0
  • From Windows ping debian wg0 ip to see if it works :
VPN WireGuard | Windows client, ping wg0 interface
  • To make it persistent, edit /etc/network/interfaces.d/wg0 file and add :
 # indicate that wg0 should be created when the system boots, and on ifup -a
auto wg0

# describe wg0 as an IPv4 interface with static address
iface wg0 inet static

        # static IP address 
        address 10.0.2.1/24

        # before ifup, create the device with this ip link command
        pre-up ip link add $IFACE type wireguard

        # before ifup, set the WireGuard config from earlier
        pre-up wg setconf $IFACE /etc/wireguard/$IFACE.conf

        # after ifdown, destroy the wg0 interface
        post-down ip link del $IFACE
        # allowed clients
	up wg set wg0 peer CLIENT01_PUBLIC_KEY allowed-ips 0.0.0.0/0
	up wg set wg0 peer CLIENT02_PUBLIC_KEY allowed-ips 0.0.0.0/0

Gateway mode

Enable ip forwarding

  • Edit /etc/sysctl.conf :
net.ipv4.ip_forward = 1
  • Run :
root@host:~# sysctl -p /etc/sysctl.conf
  • Check ip_forward is enabled :
root@host:~# cat /proc/sys/net/ipv4/ip_forward
1

iptables NAT rule

  • Identify your internal interface name :
VPN WireGuard | Debian server, ip addr sh
  • Enter the masquerade rule to make your internal network reachable from Windows :
root@host:~# iptables -t nat -A POSTROUTING -s 10.0.2.0/24 -o ens224 -j MASQUERADE
  • We can also add filter rules :
root@host:~# iptables -I INPUT -p udp -m udp --dport 51820 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
root@host:~# iptables -I OUTPUT -p udp -m udp --sport 51820 -m state --state ESTABLISHED,RELATED -j ACCEPT

nftables NAT rules

  • Enter the masquerade rules to make your internal network reachable from Windows :
root@host:~# nft add table ip NAT
root@host:~# nft add chain ip NAT my_masquerade '{ type nat hook postrouting priority 100; }'
root@host:~# nft add rule NAT my_masquerade ip saddr { 10.0.2.0/24 } oifname ens224 masquerade
  • We can also add filter rules :
root@host:~# nft add rule ip filter INPUT udp dport 51820 ct state new,established counter accept
root@host:~# nft add rule ip filter OUTPUT udp sport 51820 ct state established counter accept

Test from Windows

  • Ping any internal host :
VPN WireGuard | Windows client, ping internal host

Troubleshooting

  • Enable WireGuard debug :
root@host:~# modprobe wireguard && echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control
  • Watch syslog :
root@host:~# tail -f /var/log/syslog
  • Disable WireGuard debug :
root@host:~# modprobe wireguard && echo module wireguard -p > /sys/kernel/debug/dynamic_debug/control

References

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Contact :