Home / Articles

WireGuard on OpenBSD with wg(4)

2020-10-25T13:49:12.850Z.

Changelog:

This article describes the WireGuard server configuration on OpenBSD 7.3, WireGuard client configuration on iOS 16 and OpenBSD 7.3. Once the configuration is complete, all traffic from the clients will go through the server before reaching the Internet. This is also known as "road warrior" setup.

The network setup:

Network diagram.

Enable IP forwarding

Enable IP forwarding on the server:


sysctl net.inet.ip.forwarding=1
sysctl net.inet6.ip6.forwarding=1

To make the settings permanent, save the configuration in /etc/sysctl.conf:


net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1

Prepare keys

The server private key and pre-shared key will be placed in the /etc/wireguard directory:


mkdir -p /etc/wireguard/

Generate the server private key, as root:


openssl rand -base64 32 > /etc/wireguard/server.key
chmod 600 /etc/wireguard/server.key

Generate the pre-shared key:


openssl rand -base64 32 > /etc/wireguard/client-ios.psk
chmod 600 /etc/wireguard/client-ios.psk
openssl rand -base64 32 > /etc/wireguard/client-openbsd.psk
chmod 600 /etc/wireguard/client-openbsd.psk

Each pre-shared key is shared between the server and client.

Configure network interface

Configure the wg0 interface on the server by adding a file /etc/hostname.wg0:


inet 10.0.7.1 255.255.255.0
inet6 fd00:0:0:7::1 64

wgkey SERVER_PRIVATE_KEY
wgport 50000

# Client (iOS).
wgpeer PEER_PUBLIC_KEY wgpsk PRE_SHARED_KEY wgaip 10.0.7.2/32 wgaip fd00:0:0:7:2716::1/80

# Client (OpenBSD).
wgpeer PEER_PUBLIC_KEY wgpsk PRE_SHARED_KEY wgaip 10.0.7.3/32 wgaip fd00:0:0:7:2719::1/80

up

Note:

Start the interface:


sh /etc/netstart wg0

Check the public key of the server:


ifconfig wg0 | grep wgpubkey

The string after wgpubkey shown on screen is the server public key.

Configure Packet Filter

On the server, add the following rules in /etc/pf.conf:


pass in on egress proto udp from any to egress port 50000
pass out on egress from wg0:network to any nat-to (egress)

Validate and reload the rules:


pfctl -n -f /etc/pf.conf
pfctl -f /etc/pf.conf

Configure WireGuard on client (iOS)

Install WireGuard for iOS, then create a new WireGuard tunnel.

WireGuard for iOS, interface configuration.

In the interface section:

WireGuard for iOS, peer configuration.

In the peer section:

Configure WireGuard on client (OpenBSD)

Generate the client private key, as root:


openssl rand -base64 32 > /etc/wireguard/client.key
chmod 600 /etc/wireguard/client.key

Configure the wg0 interface on the client by adding a file /etc/hostname.wg0:


inet 10.0.7.3 255.255.255.0
inet6 fd00::7:2719:0:0:1 64

wgkey CLIENT_PRIVATE_KEY

wgpeer SERVER_PUBLIC_KEY wgendpoint SERVER_PUBLIC_IP_OR_DOMAIN 50000 wgpsk PRE_SHARED_KEY wgaip 0.0.0.0/0 wgaip ::/0

up

Note:

Start the interface:


sh /etc/netstart wg0

Check the public key of the client:


ifconfig wg0 | grep wgpubkey

The string after wgpubkey shown on screen is the client's public key.

Set client public keys on server

Going back to the server, update /etc/hostname.wg0 and replace the PEER_PUBLIC_KEY placeholders with the public keys generated on the clients.

Activate WireGuard tunnel (iOS)

Tap on the toggle switch to activate the tunnel. The data sent and received through the tunnel is shown in the tunnel details screen.

Activate and route traffic through the WireGuard tunnel (OpenBSD)

When the wg0 interface is up, the tunnel is activated. You can verify by using ping(8), for example:


ping -c 3 10.0.7.1
ping6 -c 3 fd00:0:0:7::1

Packets should be sent and received successfully.

To route all traffic through the WireGuard tunnel, run the following to add several routes to the routing table:


# IPv4.
route add -priority 2 SERVER_PUBLIC_IP DEFAULT_GATEWAY
route add -priority 7 default SERVER_WG_IP
# IPv6.
route add -priority 7 -inet6 default CLIENT_WG_IP

Note:

Verifications

On the client, visit websites like https://ifconfig.co/ to verify the IP address is the server's public IP address, instead of the client's public IP address. On OpenBSD, you can also use ftp(1) to check the IP addresses. For example:


# IPv4.
ftp -o - -4 https://ifconfig.co/json
# IPv6.
ftp -o - -6 https://ifconfig.co/json

Websites like https://test-ipv6.com/ can be used to verify that the client has a working IPv6 connection.

IPv6 connection test.

Deactivate the tunnel (iOS)

Tap on the toggle switch to deactivate the tunnel.

Deactivate the tunnel and restore traffic routing (OpenBSD)

Delete the routes added to the routing table:


# IPv4.
route delete default -priority 7 SERVER_WG_IP
route delete SERVER_PUBLIC_IP -priority 2 DEFAULT_GATEWAY
# IPv6.
route delete -inet6 default -priority 7 CLIENT_WG_IP

Note:

Mark the wg0 as down on the client:


ifconfig wg0 down

References