This example shows how to setup a WireGuard VPN network with a Linux server that is publicly accessible and serveral OpenWRT nodes that are not. One of these client nodes is used as network wide 'exit node'. This makes it possible to easily configure network with an exit node which is a network that is not under your control or cannot be (easily) configured to setup port forwarding.
Generate private keys for all clients and a pre-shared key (PSK) for every connection pair.
(umask 0377; wg genkey > peerA.key)
wg pubkey < peerA.key > peerA.pub
(umask 0377; wg genpsk > peerA-peerB.psk)
(umask 0377; wg genpsk > peerA-peerC.psk)
To be able to more easily recognize keys in status overviews it might be benificial to use a vanity address.
wireguard-vanity-address --in 3 bob
Decide the RFC1918 IPv4 subnet you are going to use. For this a generator can be used. This example only implements IPv4 on the WireGuard layer. The underlying carrier network can, but does not need to, be IPv6.
The examples below uses 192.0.2.0/24
(RFC 5737).
Consult your distributions documentation on how to install wireguard
on your Linux server.
Create the configuration file /etc/wireguard/wg0.conf
[Interface]
Address = 192.0.2.1/24
ListenPort = 443
PrivateKey = PrivateKeyOfPeerA
# Disable automatic routing
Table = off
# Insert manual routing and rule after device creation
PostUp = ip route add 192.0.2.0/24 dev wg0 scope link table 51820
PostUp = ip route add default via 192.0.2.2 dev wg0 table 51820
PostUp = ip rule add from 192.0.2.0/24 priority 30000 lookup 51820
PostUp = ip route flush cache
# Delete manual routes and rule on device removal
PreDown = ip rule del from 192.0.2.0/24 priority 30000 lookup 51820
PreDown = ip route del default via 192.0.2.2 dev wg0 table 51820
PreDown = ip route del 192.0.2.0/24 dev wg0 scope link table 51820
PreDown = ip route flush cache
[Peer]
PublicKey = PublicKeyOfPeerB
PresharedKey = PSKpeerApeerB
AllowedIPs = 192.0.2.2/32, 0.0.0.0/0
[Peer]
PublicKey = PublicKeyOfPeerC
PresharedKey = PSKpeerApeerC
AllowedIPs = 192.0.2.3/32
[Peer]
PublicKey = PublicKeyOfPeerD
PresharedKey = PSKpeerApeerD
AllowedIPs = 192.0.2.4/32
[Peer]
PublicKey = PublicKeyOfPeerE
PresharedKey = PSKpeerApeerE
AllowedIPs = 192.0.2.5/32
# Configure more peers as required
This configuration file setups WireGuard with an isolated routing table, separate from the rest of the default and possible other routes (eg. docker).
Start and enable the WireGuard service
systemctl start [email protected]
systemctl enable [email protected]
Configure your firewall to allow incomming traffic to the WireGuard service.
# When using iptables: (make sure to store permanently in eg /etc/iptables/rules.v4; consult your distros docs)
iptables -I INPUT -p udp –dport 443 -j ACCEPT
iptables -I FORWARD -i wg0 -j ACCEPT
# When using UFW:
ufw allow 443/udp
ufw route allow in on wg0
Configure your kernel to allow forwarding.
echo net.ipv4.ip_forward=1 >> /etc/sysctl.d/99-forward.conf
sysctl --system
Setup interface
uci set network.wg=interface
uci set network.wg.proto='wireguard'
uci set network.wg.private_key='PrivateKeyOfPeerB'
uci set network.wg.listen_port='51820'
uci set network.wg.addresses='192.0.2.2/24'
uci set network.wg.nohostroute='1'
uci set network.wg.defaultroute='0'
uci set network.wg.fwmark='0xca6c'
uci set network.wg.ip4table='51820'
Add peer
uci add network wireguard_wg
uci set network.@wireguard_wg[-1].description='Middleman'
uci set network.@wireguard_wg[-1].public_key='PublicKeyOfPeerA'
uci set network.@wireguard_wg[-1].preshared_key='PSKpeerApeerB'
uci set network.@wireguard_wg[-1].allowed_ips='192.0.2.0/24'
uci set network.@wireguard_wg[-1].endpoint_host='fqdn.example.org'
uci set network.@wireguard_wg[-1].endpoint_port='443'
uci set network.@wireguard_wg[-1].persistent_keepalive='25'
Add WireGuard to the "LAN" zone (usualy this is zone 0
)
ZONE=$(uci show firewall | grep ".name='lan'" | grep -oE '[0-9]+')
uci add_list firewall.@zone[$ZONE].network='wg'
Commit
uci commit firewall
uci commit network
Setup interface
uci set network.wg=interface
uci set network.wg.proto='wireguard'
uci set network.wg.private_key='PrivateKeyOfPeerC'
uci set network.wg.listen_port='51820'
uci set network.wg.addresses='192.0.2.3/24'
uci set network.wg.nohostroute='1'
uci set network.wg.defaultroute='0'
uci set network.wg.fwmark='0xca6c'
uci set network.wg.ip4table='51820'
Add peer
uci add network wireguard_wg
uci set network.@wireguard_wg[-1].description='Middleman'
uci set network.@wireguard_wg[-1].public_key='PublicKeyOfPeerA'
uci set network.@wireguard_wg[-1].preshared_key='PSKpeerApeerC'
uci set network.@wireguard_wg[-1].allowed_ips='0.0.0.0/0'
uci set network.@wireguard_wg[-1].endpoint_host='fqdn.example.org'
uci set network.@wireguard_wg[-1].endpoint_port='443'
uci set network.@wireguard_wg[-1].persistent_keepalive='25'
Route traffic through wireguard
uci add network rule
uci set network.@rule[-1].priority='30000'
uci set network.@rule[-1].lookup='main'
uci set network.@rule[-1].suppress_prefixlength='0'
uci add network rule
uci set network.@rule[-1].priority='30001'
uci set network.@rule[-1].lookup='51820'
uci set network.@rule[-1].mark='0xca6c'
uci set network.@rule[-1].invert='1'
uci add network route
uci set network.@route[-1].interface='wg'
uci set network.@route[-1].target='0.0.0.0/0'
uci set network.@route[-1].table='51820'
uci set network.@route[-1].gateway='192.0.2.2'
Add WireGuard to the "WAN" zone (usualy this is zone 1
)
ZONE=$(uci show firewall | grep ".name='wan'" | grep -oE '[0-9]+')
uci add_list firewall.@zone[$ZONE].network='wg'
Allow management via WireGuard
uci add firewall rule
uci set firewall.@rule[-1].name='Allow SSH via wg'
uci set firewall.@rule[-1].family='ipv4'
uci set firewall.@rule[-1].src='wan'
uci set firewall.@rule[-1].src_ip='192.0.2.0/24'
uci set firewall.@rule[-1].target='ACCEPT'
uci set firewall.@rule[-1].dest_port='22'
Commit
uci commit firewall
uci commit network