Wireguard VPN for OpenBSD/Linux
Jun 19, 2022
Wireguard is a simple VPN (Virtual Private Network) protocol known for its speed and security. It has been implemented in the Linux kernel as well as in OpenBSD. This is a guide on how to set up a Wireguard connection between two devices (an OpenBSD server and a Linux client) and a DNS resolver, in order to securely tunnel the traffic while using insecure public networks, or in any other case where it might be needed.
The official website of Wireguard includes a conceptual overview section and other links where the protocol is explained in more detail. What we need to do is generate keypairs for our server and our client (which are not taxonomically different in terms of how their configurations are handled), add the client as a peer on the server configuration, and add the server as a peer on the client configuration. Multiple peers may be added on the server to allow more client connections.
We begin by generating a base64 encoded 32-byte string that Wireguard can use as our private key.
[user@openbsd ~]$ openssl rand -base64 32 > wg0.key
The private key is now stored in the
wg0.key file. We change the file permissions for good measure.
[user@openbsd ~]$ chmod 600 wg0.key
Next, we create a network interface for Wireguard associating it with the private key we generated. We can also change the port for some obscurity, instead of using the default which is 51820. I chose 50101 in this case.
[user@openbsd ~]$ doas ifconfig wg0 create wgport 50101 wgkey `cat wg0.key`
We can now verify that the interface was created with
wg0 interface should appear in the output.
[user@openbsd ~]$ doas ifconfig wg0: ... ... wgpubkey: <server-public-key> ...
The output should contain the public key that is extracted from the private key, on the line starting with
wgpubkey. We note down this key.
We also need to assign an IP address to the server for the VPN tunnel. I'm using the 10.0.0.0/24 subnet since it is available and reserved for private networks. You can use another subnet if this one not available for your network.
[user@openbsd ~]$ doas ifconfig wg0 10.0.0.1 netmask 255.255.255.0
Now we move on to the Linux client to set up the interface.
Here, we install the
wireguard-tools package since it makes things easier. I am using Void Linux; you can use the package manager of your distribution, and
doas is not installed.
[user@void: ~]$ doas xbps-install -Su wireguard-tools
wireguard-toolson OpenBSD, but unnecessary in my opinion since the OpenBSD implementation is very simple.
We create a new Wireguard interface. This time we do not need to specify a wg port, as we do not need to handle incoming connections on the client for this setup.
[user@void: ~]$ doas ip link add dev wg0 type wireguard
We also assign a different IP address for this endpoint, again on the 10.0.0.0/24 subnet.
[user@void: ~]$ doas ip address add dev wg0 10.0.0.2/24
This time, we generate a key using the
wg command from
wireguard-tools and add it to the wg0 interface on our client. It is possible to use
openssl for this as well.
[user@void: ~]$ wg genkey > wg0.key [user@void: ~]$ chmod 600 wg0.key [user@void: ~]$ doas wg set wg0 private-key wg0.key
Next up, we need to connect the client and the server. For this step, we need the public keys in order to add peers. We can check the public key that was extracted from the private key for our client.
[user@void: ~]$ doas wg interface: wg0 public key: <client-public-key> private key: (hidden)
We note down the public key of the client.
First, we add our server as a peer on the client, using the server public key we obtained earlier.
[user@void: ~]$ doas wg set wg0 peer <server-public-key> allowed-ips 0.0.0.0/0 endpoint <server-public-IP>:50101
This specifies the peer public key, the allowed IP addresses and the server endpoint including the IP address and the port.
allowed-ipsis set to 0.0.0.0/0, which means all IP addresses. This tells Wireguard to send packages destined for any IP address over the tunnel. Therefore, all traffic while browsing the Internet goes through Wireguard.
Now we write all of this to a configuration file on the Linux client, in order to be able to quickly set up the interface and initiate the connection in the future.
[user@void: ~]$ doas mkdir -p /etc/wireguard [user@void: ~]$ doas vim /etc/wireguard/wg0.conf
Here is the configuration including all the information.
DNSline in the configuration file. We will be setting up a DNS resolver on our server with
unboundlater. This is recommended, since your queries will go over your ISP's default DNS servers otherwise, which defeats the purpose of using a VPN for privacy in most cases. If this is not what you want, you should omit this line so that you can keep using the default DNS settings.
Next, we add the client as a peer on our OpenBSD server, and make the configuration persistent across reboots by creating a
hostname file for the interface.
[user@openbsd ~]$ doas ifconfig wg0 wgpeer <client-public-key> wgaip 10.0.0.2/24 [user@openbsd ~]$ doas vi /etc/hostname.wg0
Here is what we should write in
We can use
unbound with a simple setup for now. We open the
unbound configuration file.
[user@openbsd ~]$ doas vi /var/unbound/etc/unbound.conf
Here is a basic configuration.
Now we enable and start
[user@openbsd ~]$ doas rcctl enable unbound [user@openbsd ~]$ doas rcctl start unbound
We also need to enable IP forwarding (and make it persistent across reboots) on our OpenBSD server so that the VPN can function for browsing the Web.
[user@openbsd ~]$ doas sysctl net.inet.ip.forwarding=1 [user@openbsd ~]$ doas sysctl net.inet6.ip6.forwarding=1 [user@openbsd ~]$ doas echo "net.inet.ip.forwarding=1" >> /etc/sysctl.conf [user@openbsd ~]$ doas echo "net.inet6.ip6.forwarding=1" >> /etc/sysctl.conf
Finally, we need to make the necessary changes in our
pf firewall configuration in order to allow traffic over Wireguard.
[user@openbsd ~]$ doas vi /etc/pf.conf
We add the following lines to
#allow NAT (network address translation) on outgoing traffic ) )
We load the firewall configuration.
[user@openbsd ~]$ doas pfctl -f /etc/pf.conf
That's is. We should now be able to initiate the VPN connection on our Linux client, and tunnel the traffic over Wireguard.
[user@void: ~]$ doas wg-quick up wg0