wireguard vpn setup
mouse 51 · person cloud · link
Last update
2025-02-14
2025
02-14
« — »

1. SETUP

1.1 Install

1
2
3
4
5
6
7
8
9
10
11
apt install wireguard

cd /etc/wireguard/
wg genkey | tee private.key | wg pubkey > public.key
touch wg-srv.conf
chmod 600 private.key wg-srv.conf

## turn on ip forward systemwide within /etc/sysctl.d
## OR do it later inside wg-srv.conf
#sysctl --write net.ipv4.ip_forward=1
#echo net.ipv4.ip_forward=1 >> /etc/sysctl.d/local.conf

1.2 Firewall

1
2
3
4
# open port and allow traffic from intranet
ufw allow 1053/udp           comment 'VPN server'
ufw allow from 10.1.1.0/24   comment 'intranet VPN'
ufw route allow in on wg-srv comment 'VPN forward'

1.3 Network interface up/down

NB: wg-name = interface name = config filename without the extension .conf.

1
2
3
4
5
6
7
wg-quick up   wg-name # start
wg                    # info
wg-quick down wg-name # stop

# enable service
systemctl start  wg-quick@wg-name
systemctl enable wg-quick@wg-name

2. SERVER

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# /etc/wireguard/wg-srv.conf
# server (with rules to allow routing all traffic)
[Interface]
PrivateKey = KFSjreufI8MJq5DD4c94EIuVOMBRGB0cL00uAmy9+2s=  # server private key
ListenPort = 1053
Address    = 10.1.1.1/24
PostUp     = sysctl --write net.ipv4.ip_forward=1
PostUp     =   iptables -A FORWARD -i %i -j ACCEPT
PostUp     =   iptables -A FORWARD -o %i -j ACCEPT
PostUp     =   iptables -t nat -A POSTROUTING -o eth0   -j MASQUERADE
#PostUp   =   iptables -t nat -A POSTROUTING -o wg-xxx -j MASQUERADE  # can add other interfaces
PostDown   = sysctl --write net.ipv4.ip_forward=0
PostDown   =   iptables -D FORWARD -i %i -j ACCEPT
PostDown   =   iptables -D FORWARD -o %i -j ACCEPT
PostDown   =   iptables -t nat -D POSTROUTING -o eth0   -j MASQUERADE
#PostDown  =  iptables -t nat -D POSTROUTING -o wg-xxx -j MASQUERADE

# client A
[Peer]
PublicKey    = SCkqASUWoNXzDW59pZglfbUHMBzBMJmoH5HH7zffY0c=  # client public key
PresharedKey = tbAdUxK2T0uLIBk5IfSXXUYihPJUyGeFI0vP4MUPrUM=  # wg genpsk
AllowedIPs   = 10.1.1.2/32
PersistentKeepalive = 23

3. CLIENT

3.1 Standard client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# /etc/wireguard/wg-cli.conf
# client A
[Interface]
PrivateKey = oP6Zfi5ud9i4OL/COrL4FK0luSYpxvf3H7XRk8xfN0w=  # client private key
ListenPort = 2053
Address    = 10.1.1.2/24
DNS        = 10.0.0.1,1.1.1.1

# server
[Peer]
PublicKey    = ECxm9+6EAt/PPgIiVQEjzl0E8VZ7JBphZjWADUv/mVs=  # server public key
PresharedKey = tbAdUxK2T0uLIBk5IfSXXUYihPJUyGeFI0vP4MUPrUM=  # wg genpsk
AllowedIPs   = 0.0.0.0/0     # route all traffic through the server
#AllowedIPs = 10.1.1.0/24   # OR route VPN subnet only
Endpoint     = 185.193.254.157:1053
PersistentKeepalive = 5

3.2. NordVPN client (gist)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# create a linux access token
# => https://my.nordaccount.com/dashboard/nordvpn/manual-configuration/

# get my wg private key
curl -s -u token:XXXX https://api.nordvpn.com/v1/users/services/credentials | \
  jq -r .nordlynx_private_key

# get servers params
wget -qO - https://api.nordvpn.com/v1/servers?limit=15000 | gzip -9 > servers.json.gz

# get servers params (recommended)
curl -s "https://api.nordvpn.com/v1/servers/recommendations?&filters\[servers_technologies\]\[identifier\]=wireguard_udp&limit=1" | \
  jq -r '.[]|.hostname, .station, (.locations|.[]|.country|.city.name), (.locations|.[]|.country|.name), (.technologies|.[].metadata|.[].value), .load'

# create conf
[Interface]
PrivateKey = <PRIVATE_KEY>    # my private key
Address    = 10.5.0.2/32      # IP is always the same
DNS        = 127.0.0.1, 10.5.0.2, 1.1.1.1
# local ip/subnet/gateway rules to allow access to eth0 from outside
#PostUp    = ip rule  add from        192.168.1.110  table 1000         ; ip route add to 192.168.1.0/24 table 1000 dev eth0; ip route add default via 192.168.1.1    table 1000 dev eth0
#PreDown   = ip route del default via 192.168.1.1    table 1000 dev eth0; ip route del to 192.168.1.0/24 table 1000 dev eth0; ip rule  del from        192.168.1.110  table 1000

[Peer]
PublicKey  = <SRV_PUB_KEY>
AllowedIPs = 0.0.0.0/0, 192.168.1.110 # route everything, and allow binding to eth0 
Endpoint   = <SRV_IP>:51820   # port is always the same

Source Linux: Debian wiki 1 and 2, davidshomelab, deb10 wg server, dynamic IP reddit & script

Source NordVPN: myshittycode, gist, NordVPN-WireGuard-Config-Generator, NordVPN api