Using Wireguard

recently I was visiting my family to celebrate easter, but wanted to be able to have access to my NAS server at home. I had heard about WireGuard before, but never actually looked into it, so I did.

to interface with wireguard interfaces, we use wg(8) and ip(8).

we start off by creating the interfaces;

INTERFACE=wgtest0
LISTEN_PORT=51820
PRIVKEY="`wg genkey`"
PUBKEY="`echo $PRIVKEY | wg pubkey`"
PRIVKEYPATH="$HOME/wgprivkey"

# we set the server ip to 10.10.10.1, and the client ip to 10.10.10.2
ADDRESS="10.10.10.1/24"
#ADDRESS="10.10.10.2/24"

# the wg tool requires the private key to be read from a file
echo "$PRIVKEY" >$PRIVKEYPATH

ip link add dev $INTERFACE type wireguard
ip addr add dev $INTERFACE $ADDRESS
wg set $INTERFACE listen-port $LISTEN_PORT private-key $PRIVKEYPATH

we do this on both the client-, and server-side.

then we set up the server to accept connections from the client.

wg set $INTERFACE peer "$CLIENT_PUBKEY" allowed-ips 10.10.10.0/24

and the reverse on the client side, with the additional endpoint argument.

wg set $INTERFACE peer "$SERVER_PUBKEY" allowed-ips 10.10.10.0/24 endpoint $SERVER_HOST:$LISTEN_PORT

then on both sides, we bring the interfaces up.

ip link set up dev $INTERFACE

now we can confirm that it works by having the server and client ping eachother.

# ping the server from the client side
ping -c4 10.10.10.1

# ping the client from the server side
ping -c4 10.10.10.2

in order to avoid using all of these flags for each client being connected, wg allows for the reading of config files via the setconf argument. in order to get the config of the already established interface we've set up, we do;

wg showconf $INTERFACE | tee WireGuard.conf
[Interface]
ListenPort = 51820
PrivateKey = ABase64RepresentationOfYourPrivateKeyThatShouldBeKeptSecret=

[Peer]
PublicKey = ABase64RepresentationOfYourPublicKeyThatYouCanShareFreely=
AllowedIPs = 10.10.10.2/24

now for the future we can load the config by running wg setconf $INTERFACE WireGuard.conf.

as you can see, wireguard doesn't have a clear distinction between server and client, and therefore you can have multiple "server" nodes connected together.


Extras

as we can see; the pubkey is a 44 character base64 string, which makes it visually unaesthetic. in order to counter this, we can use a vanity address generator such as warner/wireguard-vanity-address, axllent/wireguard-vanity-keygen, or even just running wg genkey and checking pubkey by pumping it into wg pubkey (though this will have significant overhead.)

if you're connecting with a device like a smartphone, we can generate a QR code with qrencode like so;

#OUTPUT_TYPE=png
#OUTPUT_TYPE=svg
#OUTPUT_TYPE=ascii
OUTPUT_TYPE=ansiutf8
qrencode -t $OUTPUT_TYPE <my_wireguard.conf

Caveats

you won't be able to use portscanners to check if your endpoint is up (see chapter 5.1 in the whitepaper).