WireGuard
WireGuard is a tunneling protocol that can be used to implement a VPN.
Establish Server/Client Connection
Initial key generation and exchange
sudo pacman -S wireguard-tools # install userspace utilities # generate key pair on server wg genkey | tee wg0-server.priv | wg pubkey > wg0-server.pub # generate key pair on client wg genkey | tee wg0-client.priv | wg pubkey > wg0-client.pub # exchange public keys scp user@client:/path/to/wg0-client.pub admin@server: scp admin@server:/path/to/wg0-server.pub user@client:
On wireguard server (e.g. a VPS)
# add interface and set ip address ip link add dev wg0 type wireguard ip addr add 10.0.0.1/24 dev wg0 # set listening port and add private key wg set wg0 listen-port 12345 private-key /path/to/wg0-server.priv # set peer (client) via their public key wg set wg0 peer $(cat wg0-client.pub) allowed-ips 10.0.0.2/32 ip link set wg0 up
On wireguard client (e.g. a home server behind NAT)
ip link add dev wg0 type wireguard ip addr add 10.0.0.2/24 dev wg0 # must match allowed-ips above wg set wg0 listen-port 12345 private-key /path/to/wg0-client.priv # set peer (server) via their public key and specify an endpoint # plus set keep alive so that connection doesnt die (e.g. when client switches ip) wg set wg0 peer $(cat wg0-server.pub) allowed-ips 10.0.0.1/32 endpoint 12.34.678.9:12345 persistent-keepalive 25 ip link set wg0 up
Test connection
# first ping 10.0.0.1 from client to establish connection ping 10.0.0.1 # now try pinging 10.0.0.2 from server ping 10.0.0.2 # server should be able to ping client, even though no client endpoint was # defined thanks to the pre-established connection # check connections, allowed ips, etc. on server or client wg
Make Client's LAN accessible over WireGuard
To be able to access other machines in the client's LAN
# on server & client, add the LAN subnetwork as allowed ips wg set wg0 peer $(cat wg0-client.pub) allowed-ips 10.0.0.2/32,192.168.178.0/24 wg set wg0 peer $(cat wg0-server.pub) allowed-ips 10.0.0.1/32,192.168.178.0/24 # add route to the home server's LAN on server ip route add 192.168.35.0/24 dev wg0 # check if ipv4 forwarding is enabled on client sysctl -a | grep ip_forward # if net.ipv4.ip_forward = 0, enable it sysctl -w net.ipv4.ip_forward=1 # enable ip masquerading according to https://unix.stackexchange.com/questions/638889/make-local-resources-available-when-connected-to-wireguard-vpn iptables -t mangle -A PREROUTING -i wg0 -j MARK --set-mark 0x30 iptables -t nat -A POSTROUTING ! -o wg0 -m mark --mark 0x30 -j MASQUERADE # test by pinging a machine in the client's LAN on the server ping 192.168.178.30
Using wg.conf files with wg-quick
# WireGuard config files live in /etc/wireguard/ # Manual setup from above can be saved with wg showconf wg0 > /etc/wireguard/wg0.conf # add Address = ... field in wg0.conf (used by wg-quick) [Interface] Address = 10.0.0.x/24 # for more config options that only wg-quick uses, see # https://man.archlinux.org/man/wg-quick.8#CONFIGURATION # Start wireguard using wg0 config with wg-quick up wg0 # Or systemctl start wg-quick@wg0.service # To persist across reboots systemctl enable wg-quick@wg0.service