diff options
Diffstat (limited to 'content/posts')
-rw-r--r-- | content/posts/openbsd-wireguard-vpn-gateway/index.org | 74 |
1 files changed, 68 insertions, 6 deletions
diff --git a/content/posts/openbsd-wireguard-vpn-gateway/index.org b/content/posts/openbsd-wireguard-vpn-gateway/index.org index 3e064fb..3f27707 100644 --- a/content/posts/openbsd-wireguard-vpn-gateway/index.org +++ b/content/posts/openbsd-wireguard-vpn-gateway/index.org @@ -26,7 +26,7 @@ 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. +traffic from the router through the VPN using the =route(8)= command. #+begin_src route -T <rtable> exec <program> @@ -34,10 +34,12 @@ route -T <rtable> exec <program> Here's a diagram of what we're building. +(diagram of the network configuration) + 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 +#+CAPTION: profile.conf #+begin_src conf [Interface] PrivateKey = PRIVATEKEY @@ -51,7 +53,10 @@ Endpoint = ENDPOINT:51820 #+end_src We then have to rewrite it into OpenBSD's =hostname.if(5)= format. +We'll call it =/etc/hostname.wg0= to create a Wireguard interface and +execute the following commands when it's created. +#+CAPTION: /etc/hostname.wg0 #+begin_src conf inet XX.XX.XX.XX/32 inet6 YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY/128 @@ -59,8 +64,14 @@ wgkey PRIVATEKEY wgpeer PUBLICKEY wgaip 0.0.0.0/0 wgaip ::0/0 wgendpoint ENDPOINT 51820 #+end_src +In our setup, since we want to setup a routing table where the VPN is +the default route, we need to create it and set the routes +accordingly. We can do this by adding commands to the end of our +config file. Lines beginning with =!= are commands that are run as +root when the interface is being created. In this case our new routing +table (rtable) will be number 1. The default routing table is number 0. - +#+CAPTION: /etc/hostname.wg0 #+begin_src conf inet XX.XX.XX.XX/32 inet6 YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY/128 @@ -71,16 +82,67 @@ wgpeer PUBLICKEY wgaip 0.0.0.0/0 wgaip ::0/0 wgendpoint ENDPOINT 51820 !route -T 1 add -inet6 default YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY #+end_src +Now that our interfaces are setup, we need to create the firewall +rules that will take care of the routing and NAT. We use a couple +macros here (=$ext_if= and =$vpn_if=) to make it easy to change the +interface names if we ever have to. + +We can bring up the interface using the command =sh /etc/netstart wg0=. + +#+CAPTION: /etc/pf.conf #+begin_src conf +set skip on lo + +block return # block stateless traffic +# pass # establish keep-state + ext_if = "vio0" vpn_if = "wg0" -pass in on $ext_if +# Don't send traffic for us (ssh) through the VPN +pass in quick on $ext_if proto tcp from $ext_if:network to self port 22 + pass in on $ext_if from $ext_if:network rtable 1 -pass out on $ext_if from self # ($ext_if) +pass out on $ext_if from self match out on $vpn_if from $ext_if:network to any nat-to $vpn_if pass out on $vpn_if #+end_src -sysctl thing +Let's break down this file line by line. + +- =set skip on lo= This is part of the default =pf.conf(5)= file. It + stops =pf= from evaluating traffic on the loopback interfaces. This + is fine. +- =block return= Block all traffic by default +- =# pass= We comment out the =pass= rule. This is part of the default + configuration to allow all traffic to pass in and out. We want to + only allow traffic we explicitly specify through so we remove it. +- =ext_if = "vio0"= Create a macro for the main egress interface. This + interface will be connected to our network and also have access to + the internet. +- =vpn_if = "wg0"= Create a macro for the VPN interface. +- =pass in quick on $ext_if proto tcp from $ext_if:network to self + port 22= Here we allow any traffic directly addressing our server on + TDP port 22 to pass in without any further rule evaluations. This + lets us SSH into our server without the packets being put into the + VPN routing table. +- =pass out on $ext_if from self= This lets us connect to the internet + from the VPN server. +- =match out on $vpn_if from $ext_if:network to any nat-to $vpn_if= + This rule will take any traffic coming in from out network and NAT + it to our VPN interface. +- =pass out on $vpn_if= This lets the traffic out through the VPN + interface. + +We can apply the file without rebooting with the command =pfctl -f /etc/pf.conf= + +Finally we need to make sure our machine will forward traffic. We can +do this by adding a line to our =sysctl.conf(5)= file. + +#+CAPTION: /etc/sysctl.conf +#+begin_src conf +net.inet.ip.forwarding=1 +#+end_src + +We can change the variable without rebooting with the command =sysctl net.inet.ip.forwarding=1= |