Configure WireGuard
wg(4) allows us to create a WireGuard pseudo-device interface for VPNs. Packets sent over WireGuard are securely encrypted and transported over UDP.
In this setup, we will configure two OpenBSD machines, wg1
and wg2
, to
connect together using wg(4). In our examples,
these two machines will have IP addresses 192.168.5.2 and 192.168.5.3,
respectively. These two addresses must be replaced with publicly routable IP
addresses.
Configuring wg(4) interfaces
On the first machine, we generate a private key. We then use ifconfig(8) to create a wg(4) interface, which we use to obtain the public key:
wg1# openssl rand -base64 32 LizlMGTl5tM8EgGl6btVbT++PrtYdtgrvGQ2lO6yfrU= wg1# ifconfig wg0 create wgport 7111 wgkey LizlMGTl5tM8EgGl6btVbT++PrtYdtgrvGQ2lO6yfrU= wg1# ifconfig wg0 | grep 'wgpubkey' | cut -d ' ' -f 2 1XuhX5G1c3VeEkXiqkfC9vC/75HPWgy28bnRtRMkxk8=
Repeat this process with the second machine:
wg2# openssl rand -base64 32 dBV9BYAAnIVU2Aw+Um6Z8CWGsZE8Vgb03sZkFrJm2MU= wg2# ifconfig wg0 create wgport 7222 wgkey dBV9BYAAnIVU2Aw+Um6Z8CWGsZE8Vgb03sZkFrJm2MU= wg2# ifconfig wg0 | grep 'wgpubkey' | cut -d ' ' -f 2 Mqud/KzSVrKRaKzxLz9aU8/1lRChbBwkmOz0hQq1RxM=
We now use this information to create the interface file /etc/hostname.wg0. On machine wg1:
wg1# cat /etc/hostname.wg0 wgport 7111 wgkey LizlMGTl5tM8EgGl6btVbT++PrtYdtgrvGQ2lO6yfrU= wgpeer Mqud/KzSVrKRaKzxLz9aU8/1lRChbBwkmOz0hQq1RxM= wgendpoint 192.168.5.3 7222 wgaip 10.0.5.2/32 wgpka 20 inet 10.0.5.1 0xffffff00 wg1# sh /etc/netstart wg0
On machine wg2:
wg2# cat /etc/hostname.wg0 wgport 7222 wgkey dBV9BYAAnIVU2Aw+Um6Z8CWGsZE8Vgb03sZkFrJm2MU= wgpeer 1XuhX5G1c3VeEkXiqkfC9vC/75HPWgy28bnRtRMkxk8= wgendpoint 192.168.5.2 7111 wgaip 10.0.5.1/32 wgpka 20 inet 10.0.5.2 0xffffff00 wg2# sh /etc/netstart wg0
Replace the public key and private key with your own uniquely generated
strings. Replace @192.168.5.2@ and @192.168.5.3@ with the publicly routable IP
addresses of the two machines. Replace 10.0.5.1
and 10.0.5.2
with the
IP addresses of the WireGuard interfaces (these IP addresses will not be
publicly routable).
Verify that wireguard is working:
wg2# ping 10.0.5.1 PING 10.0.5.1 (10.0.5.1): 56 data bytes 64 bytes from 10.0.5.1: icmp_seq=0 ttl=255 time=2.378 ms 64 bytes from 10.0.5.1: icmp_seq=1 ttl=255 time=0.775 ms wg1# tcpdump -ne -i wg0 'icmp' tcpdump: listening on wg0, link-type LOOP 01:10:08.043339 10.0.5.2 > 10.0.5.1:icmp: echo request 01:10:08.043353 10.0.5.1 > 10.0.5.2:icmp: echo reply 01:10:09.060209 10.0.5.2 > 10.0.5.1:icmp: echo request 01:10:09.060220 10.0.5.1 > 10.0.5.2:icmp: echo reply
Client-server
Typically, one machine will act as the server, and the other as the client.
Beyond the basic configuration, we will configure wg1
to act as server, and
wg2
as client. All traffic from wg2
will be tunneled to wg1
and
forwarded to the broader Internet.
First, what we must do is set wg2
's default interface to use a different
rdomain(4). For example, if wg2
normally uses static networking, we would have:
# cat /etc/hostname.if0 rdomain 1 inet 192.168.5.3 0xffff0000 !route -T1 add default 192.168.5.1
Replace 192.168.5.3
with your device's actual IP address, replace
192.168.5.1
with the actual default gateway, and replace if0
with the
actual interface name.
If WiFi and DHCP are used instead, the configuration might be:
# cat /etc/hostname.if0 join NWID wpakey PRIVKEY rdomain 1 inet autoconf up
We update machine wg2
's /etc/hostname.wg0 to make 10.0.5.1 the default
route. We use the rtable 1 to connect to our WireGuard peer and we loosen the
wgaip restrictions on wg1
's wg(4) interface (since replies will come from
source IPs all over the Internet):
wg2# cat /etc/hostname.wg0 wgport 7222 wgkey 'dBV9BYAAnIVU2Aw+Um6Z8CWGsZE8Vgb03sZkFrJm2MU=' wgpeer 1XuhX5G1c3VeEkXiqkfC9vC/75HPWgy28bnRtRMkxk8= wgendpoint 192.168.5.2 7111 wgaip 0.0.0.0/0 wgpka 20 wgrtable 1 inet 10.0.5.2 0xffffff00 !route add -inet default 10.0.5.1
Now traffic from machine wg2
is routed through wg1
.
In order for DNS to work, wg2
can either use an external IP address in resolv.conf, or use a local resolver such as unwind.
Note: You may have errors using 127.0.0.1 (localhost) for your caching nameserver because of another routing table.
Next, we configure NAT. NAT is one method to allow packets
coming from wg2
get routed properly to the public Internet. On
machine wg1
, we add this line to /etc/pf.conf?:
match out on egress from (wg0:network) to any nat-to (egress:0)
# pfctl -f /etc/pf.conf
Finally, make sure to update the sysctls:
wg1# sysctl net.inet.ip.forwarding=1 net.inet.ip.forwarding: 0 -> 1 wg1# cat /etc/sysctl.conf net.inet.ip.forwarding=1