WireGuard VPN using an EdgeRouter X
The EdgeRouter X has the capability to run WireGuard, a fast VPN protocol that has matured enough in the last years to be ready for home use. My favorite VPN provider, AzireVPN (referral link), already has support for it as well and at the moment has even opened up the WireGuard connections for free to test the load and performance. That means that, for now, you should be able to get this all up and running for free.
To complete this example you will have to be familiar with the EdgeRouter SSH command line interface and know something about the configuration you already have up and running. You should also feel comfortable to install packages.
Installing WireGuard
First we need to get and install the WireGuard package, you can get it from https://github.com/Lochnair/vyatta-wireguard/releases
and for the EdgeRouter X you need the E50 package. Download the latest version
and then upload it using, for example, scp
to the /tmp
folder on your EdgeRouter X.
Next run sudo dpkg -i /tmp/wireguard-e50-.....
to install the package.
Getting WireGuard credentials from AzireVPN
To keep it simple, we let AzireVPN generate our private key and configuration.
After creating an account, log in and visit https://www.azirevpn.com/cfg/wireguard
Here you can download a zip file with configuration for the different VPN endpoints that they own.
Choose one location, like azirevpn-es1.conf
and take not of your private key,
the endpoint and public key of the endpoint.
Configuration
Now it's time to start configuring the interface and the routing.
Log into your EdgeRouter via SSH and start the configuration session with configure
.
We start with the WireGuard interface and credentials:
edit interfaces wireguard wg0
set address <the ipv4 address you got>
set route-allowed-ips false
set peer ZcFmXAL9JWCQoS//5w9WRDKTzTcOlhXXNOX/8d/cSF8= endpoint es1.wg.azirevpn.net:51820
set peer ZcFmXAL9JWCQoS//5w9WRDKTzTcOlhXXNOX/8d/cSF8= allowed-ips 0.0.0.0/0
set private-key <the private key from the configuration file>
exit
The route-allowed-ips false
will make sure that we have to set up routing by hand, which
we are going to use to manually route only insecure traffic we want over the VPN later.
For this we start a new routing table with the default route over the wg0
interface.
set protocols static table 22 interface-route 0.0.0.0/0 next-hop-interface wg0
Next up, we make sure that any traffic that is sent out of the wg0
interface is
masqueraded to the ip of the interface.
edit service nat rule 5222
set description "masquerade for wg0"
set outbound-interface wg0
set type masquerade
exit
For this example, we are going to only route some of the traffic over the VPN and leave the rest to run outside of the VPN. I consider traffic to SSH and HTTPS ports to be secure already, so let's create a group for these ports:
edit firewall group port-group secure_tcp
set port ssh
set port https
exit
Then we create a modify
firewall rule set that will change the routing behavior
of matched traffic to use the wg0
routing table we created earlier.
edit firewall modify lan_in_modify rule 20
set description wireguard
set protocol tcp
set destination group port-group !secure_tcp
set modify table 22
exit
This will match anything that is not considered a secure TCP port and apply the
routing table we defined earlier (22
) to that traffic.
To apply this rule to traffic on a given interface, we need to hook up the
firewall rule. I've bonded together the local ports into a switch0
configuration
so for me it's
set interfaces switch switch0 firewall in modify lan_in_modify
but you can choose any port you like to, for example, only have some local ports on VPN and the rest just directly connected to the internet.
That's it for the basic connection, use compare
to see what you add and use commit
to apply the current configuration. But we are not done yet, we need a firewall
on the wg0
interface. These probably fit in with your current wan
facing firewall
and therefore I'm just giving a bare-minimal example for completeness here
First the firewall rules (don't forget to enter configure mode again)
set firewall name wan_in default-action drop
set firewall name wan_in description 'WAN to internal'
set firewall name wan_in rule 10 action accept
set firewall name wan_in rule 10 description 'Allow established/related'
set firewall name wan_in rule 10 state established enable
set firewall name wan_in rule 10 state related enable
set firewall name wan_in rule 20 action drop
set firewall name wan_in rule 20 description 'Drop invalid state'
set firewall name wan_in rule 20 state invalid enable
and then to apply them to the interface
set interfaces wireguard wg0 firewall in name wan_in
Also the connections from outside to wg0
should be protected, but keep in mind
that the connection for WireGuard itself should still be allowed. Here we can use
the firewall mark that the WireGuard driver adds. An example is:
set firewall name wan_local default-action drop
set firewall name wan_local description 'WAN to router'
set firewall name wan_local rule 10 description 'Allow established/related'
set firewall name wan_local rule 10 state established enable
set firewall name wan_local rule 10 state related enable
set firewall name wan_local rule 10 action accept
set firewall name wan_local rule 15 description 'accept wireguard'
set firewall name wan_local rule 15 mark 222
set firewall name wan_local rule 15 action accept
set firewall name wan_local rule 20 description 'Drop invalid state'
set firewall name wan_local rule 20 state invalid enable
set firewall name wan_local rule 20 action drop
set interfaces wireguard wg0 firewall in name wan_local
After all the commits (and if everything is working possibly a "save") you should have a simple WireGuard VPN connection for all but HTTPS and SSH.
The VPN connection may still be leaky if the route goes down, so this is by far a complete solution. Also, I still have to figure out the IPv6 support.
Happy hacking!