Skip to content

Instantly share code, notes, and snippets.

@morningreis
Created December 16, 2022 21:26
Show Gist options
  • Save morningreis/eeda36e8bb07dcb750d77e9a744776e8 to your computer and use it in GitHub Desktop.
Save morningreis/eeda36e8bb07dcb750d77e9a744776e8 to your computer and use it in GitHub Desktop.
OPNsense + ProtonVPN + Wireguard Configuration Guide

OPNsense + ProtonVPN + Wireguard

Published: 16 December 2022

Reference: https://docs.opnsense.org/manual/how-tos/wireguard-selective-routing.html

Goal: Set up one or more Wireguard connections from ProtonVPN on OPNsense, with policy based routing, and optional Killswitch.

I'm writing this guide first as a reference for my future self for when I inevitably forget how to do this, but also to help others out. I found there were not many guides on this specific configuration, particularly not with multiple concurrent connections, and these were some steps which were not at all obvious. I did begin with the guide in the official OPNsense documentation, but even that was missing info to make ProtonVPN work. If you are a pfSense user, it is very similar to OPNsense, and you should be able to follow along with some success, but I have not tested it myself.

Preparation: Get Proton Configuration

  1. Log into https://account.protonvpn.com/downloads
  2. Scroll down half way to the Wireguard Configuration section
  3. Type in a name for the certificate you will generate, select Router, and configure your VPN options (Malware/ad/tracker blocking, Moderate NAT, NAT-PMP, VPN Accelerator)
  4. You can hit the create button right under these settings and Proton will select the server closest to you, or you can manually select a server that you prefer.
  5. Hit create

For the purpose of this demo, this is the configuration I will be the following configuration and referring back to this:

[Interface]
# Key for OPNsense Demo
# Bouncing = 5
# NetShield = 1
# Moderate NAT = off
# NAT-PMP (Port Forwarding) = off
# VPN Accelerator = on
PrivateKey = yEwTFeoVRgB/6pU8sTzyLseLnv8U7ZO/jAyVd4Uiym8=
Address = 10.2.0.2/32
DNS = 10.2.0.1

[Peer]
# US-CA#33
PublicKey = 4v/dB/ha+PGL0jihNVlVj81NGAFh6VndO9s4giDZEUw=
AllowedIPs = 0.0.0.0/0
Endpoint = 185.230.126.18:51820

Before we get started, there is one more parameter we will need!

ProtonVPN provides the Public Key for the Peer, and the Private Key for the Interface, however you will also need the Public Key for the interface. We will have to generate this ourselves You will need access to a terminal with wireguard installed for this, and the simplest way is to SSH into your OPNsense machine with the Wireguard plugin already installed.

If you do not already have the Wireguard plugin installed:

  1. Log into OPNsense
  2. Navigate to System > Firmware > Plugins
  3. Search for os-wireguard
  4. Press the + to install

If SSH is not already enabled on your OPNsense server:

  1. Navigate to System > Settings > Administration
  2. Check Enable Secure Shell

NOTE

SSH is disabled by default, and unless you have a good reason to leave it enabled, you should disable it again when you are done

Now we need to generate the Interface Public Key:

  1. SSH into your OPNsense server ssh [email protected]

  2. Select option 8 to access the Shell

  3. Enter the following command: echo <PrivateKey> | wg pubkey

     eg. `echo yEwTFeoVRgB/6pU8sTzyLseLnv8U7ZO/jAyVd4Uiym8= | wg pubkey`
    
  4. Your Interface Public Key will be output on screen

     eg. Interface Public Key: `IQjcNrCTlbtVrlkdvvPaV0NZK9wK5VofoiZeHfYzuA4=`
    

You can disable SSH on your OPNsense server at this time. We are ready to continue with actually configuring the VPN connection(s).

OPNsense Configuration

Endpoint Configuration

  1. Navigate to VPN > WireGuard > Endpoints
  2. Select the + to add a new endpoint
  3. Fill it out the form as follows:
Name:                <Anything you want>
Public Key:          <Peer Public Key>
		       eg.   4v/dB/ha+PGL0jihNVlVj81NGAFh6VndO9s4giDZEUw=
Shared Secret:       <Blank>
Allowed IPs:         0.0.0.0/0
Endpoint Address:    <Peer Endpoint IP>
               eg.   185.230.126.18
Endpoint Port:       51820
Keepalive Interval:  25
  1. Save

Local Configuration

  1. Select the Local tab
  2. Select the + to add a new Local connection
  3. Select advanced mode
  4. Fill it out the form as follows:
Name:                <Anything you want>
Public Key:          <Leave Blank!!!>
Private Key:         <Leave Blank!!!>
Listen Port:         <Select a unique port for each tunnel>
MTU:                 1412
DNS Server:          <Leave Blank!!!>
Tunnel Address:      10.2.0.2/28
Peers:               <Select the Endpoint you just created>
Disable Routes:      Checked
Gateway:             <Select a unique IP for each tunnel>

NOTE

This step is very important!

When we activate the connection, Wireguard will initially populate the Public and Private Keys. Allow it to do this. We will go back and change it to the correct values later.

Not setting the MTU to 1412 or 1420 will not prevent a Wireguard connection, but will cause many lost packets and severe performance degradation.

Setting a DNS Server at this stage will override all of OPNsense's DNS configurations. We will continue to use OPNsense's DNS configs by leaving this blank, and we will take care of DNS leaks later on.

The Tunnel Address provided by ProtonVPN is a /32 subnet. /28 is used in this guide with success. With a single tunnel, /32 may work, however with multiple, you will need to use /28 or some other range.

  1. Start Wireguard from the General Tab, or if it is already started, then turn it off and then on again. You can also restart it from the dashboard.
  2. Go to the Status Tab and then the Handshakes Tab. You should see new entries corresponding to your tunnel.
  3. Go back to the Local Tab and edit your tunnel
  4. You will see entries in there for the Public and Private Key. Delete these and replace them with your own values. The Public Key will be the string you generated eg. IQjcNrCTlbtVrlkdvvPaV0NZK9wK5VofoiZeHfYzuA4= The Private Key will be the string provided by ProtonVPN eg. yEwTFeoVRgB/6pU8sTzyLseLnv8U7ZO/jAyVd4Uiym8=
  5. Save and restart the Wireguard

Interfaces, Firewall, and NAT

Create Interface
  1. Navigate to Interfaces > Assignments
  2. Add a new interface with your newly created tunnel
  3. Select that interface
  4. Check Enable Interface
  5. Change the name to your preference
  6. Leave everything else untouched
  7. Save and Apply Changes
Create Gateway
  1. Navigate to System > Gateways > Single
  2. Add a new Gateway
  3. Fill out the form as follows:
Name:                <Anything you want>
Description:         <Your preference>
Interface:           <Select the interface you created in the pervious section>
Address Family:      IPv4
IP Address:          <Enter the Peer Endpoint IP>
               eg.   185.230.126.18
Upstream Gateway:    Unchecked
Far Gateway:         Checked
Disable Gateway Monitoring: Unchecked
Monitor IP:          Blank
  1. Save and Apply Changes
Create Aliases

In this step we will create Aliases to essentially create labels for our various hosts and networks to base routing rules off of. While not strictly required, this is going to be significantly simpler than manually making Firewall rules directly with IPs.

  1. Navigate to Firewall > Aliases
  2. Add new Alias
  3. Fill out the form as follows:
Name:                <Something descriptive>
Type:                <Hosts for individual IPs or Networks for IP Ranges>
Categories:          <Blank>
Content:             <Enter your IPs or IP Ranges in CIDR Notation>
Description:         <Your preference>
  1. Save
  2. Create another Alias except with the following settings:
Name:                RFC1918_Networks
Type:                Networks
Categories:          <Blank>
Content:             192.168.0.0/16 10.0.0.0/8 172.16.0.0/12
Description:         All local (RFC1918) networks
  1. Save
NAT Configuration
  1. Navigate to Firewall > NAT > Outbound
  2. Select Hybrid outbound NAT rule generation
  3. Add a new rule
  4. Make the following changes:
Interface:                <Select your Wireguard Interface>
Source Address:           <Select the Alias you wish to route>
  1. Leave everything else default
  2. Save and Apply Changes
Firewall Rules
  1. Navigate to Firewall > Rules > LAN
  2. Add new rule
  3. Make the following changes:
Source:                <Select the Alias you wish to route>
Destination / Invert:  Checked
Destination:           RFC1918_Networks
Gateway:               <Select your Wireguard Gateway>

Click Advanced Options Show/Hide

Set local tag:         NO_WAN_EGRESS

NOTE

The NO_WAN_EGRESS local tag will be used for the killswitch to prevent traffic leaking out if a tunnel is down

  1. Move this rule above all other rules
  2. Save and Apply Changes
  3. Navigate to Firewall > Rules > Floating
  4. Add a new rule
  5. Make the following changes:
Action:                Block
Quick:                 Checked
Interface:             WAN
Direction:             out

Click Advanced Options Show/Hide

Match local tag:         NO_WAN_EGRESS
  1. Move this rule above all other rules
  2. Save and Apply Changes

NOTE

This block rule only needs to be made once, regardless of if you have multiple Wireguard tunnels. This is what is serving as the killswitch

Complete

You can repeat these steps to add additional tunnels, however I had issue getting more than 3 tunnels to work. I believe there may be a limit on Proton's end. On the WireGuard configuration page, delete any stored configurations that you are not using.

If you have more than one tunnel and want to disable one, go to Navigate to VPN > WireGuard > Endpoints and check the tunnel you want to disable. If you disable it from the Local tab, you will also remove the interface.

If for any reason a Wireguard tunnel drops out or fails to connect, the interface and gateway you created will still be in place, and the killswitch will prevent any traffic leaking out. However if your gateway is disabled for any reason, the default behavior will be to use your regular WAN gateway, meaning the VPN will not be used at all. There is no reason for your gateway to go down however even if the tunnel is down.

Lastly, for DNS Leak protection, you should ensure that your DNS resolver (most likely your OPNsense machine) is included under an Alias to be routed through one of your Wireguard connections. That will force DNS requests to go through the VPN, but past that you will need to configure DNS over TLS or DNS over HTTPS using Unbound DNS, which is outside the scope of this guide.

@ocedric
Copy link

ocedric commented Mar 14, 2023

I abandoned months ago, passed by here and read your post. Now it works flawlessly ! Thank you so much for your help !

@morningreis
Copy link
Author

I abandoned months ago, passed by here and read your post. Now it works flawlessly ! Thank you so much for your help !

Love to hear that!

@morningreis
Copy link
Author

Thanks for this tutorial it helped me!

Excellent!

@RedLanternTech
Copy link

This was a good writeup and got me going. Thank You

@hertg
Copy link

hertg commented Jul 8, 2023

It might be because it's 2am where I am right now, but I don't understand what IP I'm supposed to choose for the Gateway in the local wireguard configuration. Should this be just any IP? Where else do I have to use this IP?

Gateway:             <Select a unique IP for each tunnel>

@morningreis
Copy link
Author

It might be because it's 2am where I am right now, but I don't understand what IP I'm supposed to choose for the Gateway in the local wireguard configuration. Should this be just any IP? Where else do I have to use this IP?

Gateway:             <Select a unique IP for each tunnel>

@hertg If your tunnel subnet is 10.2.0.2/28 like in the example, then just pick a unique IP within that subnet for each gateway. So 10.2.0.4, 10.2.0.5, etc

@moshmast
Copy link

Great guide thank you. Worked seamlessly. You clearly have experience in these setups and have learned from many challenges in the past.

@Lynx-Express
Copy link

Megathanks for this guide. That's approximately 10^6 amount of gratitude.

@zz0rk
Copy link

zz0rk commented Nov 30, 2023

I have two questions. Would I simply disable the WG Proton VPN endpoint, if I want to temporarily revert to unencrypted traffic? Secondly, with the WG Proton VPN endpoint enabled for outbound traffic, would I still be able to remote into my LAN if I have a second WG endpoint set up for that purpose. Thank you

@morningreis
Copy link
Author

I have two questions. Would I simply disable the WG Proton VPN endpoint, if I want to temporarily revert to unencrypted traffic? Secondly, with the WG Proton VPN endpoint enabled for outbound traffic, would I still be able to remote into my LAN if I have a second WG endpoint set up for that purpose. Thank you

Easiest way to circumvent the VPN temporarily is to change the gateway in your firewall rules. You can set an IP range you want to exempt and set that to use your WAN gateway.

This won't affect any additional endpoints you've set up if you want to remote in.

@zz0rk
Copy link

zz0rk commented Nov 30, 2023

Easiest way to circumvent the VPN temporarily is to change the gateway in your firewall rules.

Ok, so this would be option a) change the gateway to temporarily route all traffic through the WAN

You can set an IP range you want to exempt and set that to use your WAN gateway.

... or alternatively, option b) set up an IP range so that only traffic from those IP addresses get routed through the WAN and all others through the WG Proton VPN as a more permanent setup, correct?

@morningreis
Copy link
Author

Easiest way to circumvent the VPN temporarily is to change the gateway in your firewall rules.

Ok, so this would be option a) change the gateway to temporarily route all traffic through the WAN

You can set an IP range you want to exempt and set that to use your WAN gateway.

... or alternatively, option b) set up an IP range so that only traffic from those IP addresses get routed through the WAN and all others through the WG Proton VPN as a more permanent setup, correct?

Yes. Any of the above work. You have a lot of control with firewall rules.

@zz0rk
Copy link

zz0rk commented Nov 30, 2023

Thank you so much. I've read other instructions on how to set up an OpenVPN client on OPNsense, but it seems far more involved, versus the more elegant WG approach. Thank you so much for your quick response. Cheers

@duck955
Copy link

duck955 commented Jan 2, 2024

Thank you for this thorough writeup, I was able to create a tunnel and route traffic with firewall rules.

My issues is the gateway is not monitoring even with the box unchecked and the default monitoring IP. I've attempted multiple monitoring IPs. I'm able to ping the ProtonVPN public IP gateway from my network, yet the interface will not show up. Any idea on why the interface will not ping the ProtonVPN server IP?
Screenshot 2024-01-01 191102

@zz0rk
Copy link

zz0rk commented Jan 12, 2024

@morningreis

Lastly, for DNS Leak protection, you should ensure that your DNS resolver (most likely your OPNsense machine) is included under an Alias to be routed through one of your Wireguard connections. That will force DNS requests to go through the VPN, but past that you will need to configure DNS over TLS or DNS over HTTPS using Unbound DNS, which is outside the scope of this guide.

I am running into a mental block here, lol. I have DOT and DNSSEC enabled in Unbound which runs on my OPNsense box. Would I still need to route traffic through my Wireguard connection to prevent DNS leaks? Also, if the answer is Yes and I create an alias for my OPNSense box etc., wouldn't this route ALL traffic through the Wireguard connection and defeat the purpose of creating aliases for individual nodes specifically?

Thanks muchly!

@martin-forum
Copy link

Thank you for your guide. It helped a lot and is working with the current version of opnsense with vlan and bridges.

One question about the vpn status in the dashboard: 'latency' (in organge). Any hint what I can do?

@morningreis
Copy link
Author

Thank you for your guide. It helped a lot and is working with the current version of opnsense with vlan and bridges.

One question about the vpn status in the dashboard: 'latency' (in organge). Any hint what I can do?

Set the monitor IP to your endpoint IP under System > Gateways > Single

@martin-forum
Copy link

Thank you for your guide. It helped a lot and is working with the current version of opnsense with vlan and bridges.
One question about the vpn status in the dashboard: 'latency' (in organge). Any hint what I can do?

Set the monitor IP to your endpoint IP under System > Gateways > Single

Thank you for your feedback. I have added the endpoint IP also in the monitor IP field (menu: system - gateways - configuration).
After a reboot, nothing changed. Other idea?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment