#+TITLE: OpenBSD Wireguard VPN Gateway #+DATE: 2023-12-29T16:35:36-05:00 #+DRAFT: true #+DESCRIPTION: #+TAGS[]: openbsd wireguard vpn #+KEYWORDS[]: openbsd wireguard vpn #+SLUG: #+SUMMARY: A couple of years ago I published a (link) blog post about creating an OpenBSD VPN gateway using OpenVPN. I've recently switched from an OpenVPN-based VPN provider to one that uses Wireguard. As a result I've had to redo my VPN gateway. One advantage this iteration has over my previous setup is that it no longer requires third party software to be installed on the OpenBSD router. Everything required comes as part of the base install. The purpose of the VPN gateway is to allow any device on the network to send its traffic through a VPN without installing anything. Instead of installing one profile per device, the client just sets the VPN Gateway as its default route. Unlike the previous setup, in this version we're going to create a separate routing table for the VPN. This lets us set the VPN as the default route for the traffic we want to go through, while leaving the rest of the system unaffected. It also lets us selectively send traffic from the router through the VPN using the =route= command. #+begin_src route -T exec #+end_src Here's a diagram of what we're building. The first step in the process is getting the VPN profile from the VPN provider. It should look something like the following. #+CAPTION: wireguard.conf #+begin_src conf [Interface] PrivateKey = PRIVATEKEY Address = XX.XX.XX.XX/32,YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY/128 DNS = ZZ.ZZ.ZZ.ZZ [Peer] PublicKey = PUBLICKEY AllowedIPs = 0.0.0.0/0,::0/0 Endpoint = ENDPOINT:51820 #+end_src We then have to rewrite it into OpenBSD's =hostname.if(5)= format. #+begin_src conf inet XX.XX.XX.XX/32 inet6 YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY/128 wgkey PRIVATEKEY wgpeer PUBLICKEY wgaip 0.0.0.0/0 wgaip ::0/0 wgendpoint ENDPOINT 51820 #+end_src #+begin_src conf inet XX.XX.XX.XX/32 inet6 YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY/128 wgkey PRIVATEKEY wgpeer PUBLICKEY wgaip 0.0.0.0/0 wgaip ::0/0 wgendpoint ENDPOINT 51820 !route -T 1 add -inet default XX.XX.XX.XX !route -T 1 add -inet6 default YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY #+end_src #+begin_src conf ext_if = "vio0" vpn_if = "wg0" pass in on $ext_if pass in on $ext_if from $ext_if:network rtable 1 pass out on $ext_if from self # ($ext_if) match out on $vpn_if from $ext_if:network to any nat-to $vpn_if pass out on $vpn_if #+end_src sysctl thing