How to set up a WireGuard Site to Site VPN Between 2 EdgeRouters
I’ve recently started college and I’m living in one of the dorms on campus. They provide 1 Ethernet jack per person per room. I have multiple wired devices, so at the very least I needed a switch, but I also wanted all the devices to be able to talk to everything back on my home network.
The best way to do this is with a site to site VPN. This lets devices on each end of the VPN tunnel communicate with each other as if they were directly on the same network.
My router of choice at home is an EdgeRouter Lite from Ubiquiti Networks. Originally I was going to use a Cisco Meraki MX64 firewall (get one for free here) at my dorm as my router, but the functionality is somewhat limited for my uses and I prefer the EdgeRouters, so I got a cheap EdgeRouter X off of eBay (college budget life) and went to work.
My original plan was to use OpenVPN because I’m familiar with it, but upon testing, I found the performance to be seriously lacking (up to about 7mbps). My dorm has 100/100 and home has 130/35, so that wasn’t going to cut it.
Plan B was IPSEC. Both EdgeRouters have hardware offloading for the encryption used in typical IPSEC configurations, so this seemed like a good high performance option. My next roadblock though was that I can’t port forward anything from my dorm, which made it difficult or impossible to establish an IPSEC tunnel. (may be possible but my Googling couldn’t find a way)
Finally, Plan C was to use WireGuard. I had made a post on Reddit with my IPSEC woes and it was suggested that I tried out WireGuard. WireGuard is a new type of VPN that aims to be fast, lightweight, and easy to set up (if you’re not me apparently), all while being highly secure. The details on how to set it up in on my hardware though were somewhat lacking, and it took quite a few hours to get it actually functional. My goal here today is to help someone else set up something similar without all the headache I went through, so without further delay, here’s how I did it.
Here’s a quick and basic diagram of my setup, made using Creately.
1. Install vyatta-wireguard on both routers. Find the download URL for your router and copy and paste it on line 3.
ssh <router ip> sudo apt-get install wget (alternatively, use curl) wget <download url, ex: https://github.com/Lochnair/vyatta-wireguard/releases/download/0.0.20180925-1/wireguard-e100-0.0.20180925-1.deb> sudo dpkg -i <file name, ex: wireguard-e100-0.0.20180925-1.deb>
2. Generate public and private keys on each router. Copy and paste the output into a text file for convenience. Top line of output is the private key, the bottom line is the public key.
wg genkey | tee /dev/tty | wg pubkey
3. Configure the home router. I used 10.100.100.1 for the wireguard tunnel IP so that I could set up the allowed IPs as 10.0.0.0/8. It wouldn’t allow me to use 0.0.0.0/0 like I wanted, so this works out too since both subnets are on 10.x.x.x and 10.0.0.0/8 allows everything in that range.
configure set interfaces wireguard wg0 address 10.100.100.1/24 set interfaces wireguard wg0 listen-port 51820 set interfaces wireguard wg0 route-allowed-ips true set interfaces wireguard wg0 private-key <private key from this router from before>
4. Configure the remote/dorm router. I used 10.100.100.2 for the wireguard tunnel IP on this one.
configure set interfaces wireguard wg0 address 10.100.100.2/24 set interfaces wireguard wg0 listen-port 51820 set interfaces wireguard wg0 route-allowed-ips true set interfaces wireguard wg0 private-key <private key from this router from before>
5. Set up the other router (peer) on each router. Skip line 2 on the side with port forwarding (only useful on the side that can reach out to the other side with port forwarding), or run it on both sides if there is. Must be run on at least one side. Line 3 keeps the connection active so it works without port forwarding and doesn’t disconnect after a short while of no traffic.
set interfaces wireguard wg0 peer <other router's public key> allowed-ips 10.0.0.0/8 set interfaces wireguard wg0 peer <other router's public key> endpoint <public IP or domain name:port> set interfaces wireguard wg0 peer <other router's public key> persistent-keepalive 15
6. Commit and save the changes on each router (otherwise they won’t take affect and be lost), then exit from configuration mode.
commit save exit
7. Go to the home router web UI, then Firewall/NAT -> Firewall Policies -> WAN_Local. Edit the ruleset configuration and add a new rule.
- Basic – Description: Allow WireGuard
- Basic – Action: Allow
- Basic – Protocol – UDP
- Source – Port: 51820
- Destination – Port: 51820
8. Theoretically, if everything worked, you should be able to see if there’s a connection.
Home Router: interface: wg0 public key: W6ap<home pubkey> private key: (hidden) listening port: 51820 peer: O8lz<dorm/remote pubkey> endpoint: 128.x.x.x:51820 allowed ips: 10.0.0.0/8 transfer: 453.80 MiB received, 116.24 MiB sent persistent keepalive: every 15 seconds
Dorm/Remote Router: interface: wg0 public key: O8lz<dorm/remote pubkey> private key: (hidden) listening port: 51820 peer: W6ap<home pubkey> endpoint: 69.x.x.x:51820 allowed ips: 10.0.0.0/8 latest handshake: 29 seconds ago transfer: 120.42 MiB received, 453.46 MiB sent persistent keepalive: every 15 seconds
9. You should also see a new wg0 interface in the dashboard, possibly with traffic going over it already.
10. As a helpful commenter pointed out, you may need to add static routes if it doesn’t happen automatically for you. This is so that your routers know about the networks on the other end and can direct traffic accordingly. This should do the trick, on each end type this with the relevant info:
ip route add <subnet address>/<CIDR> dev wg0 Ex: ip route add 10.20.32.0>/24 dev wg0
11. Try pinging a device on the other end, from either end. If it comes back with a response, you should be all done!
[email protected]:~$ ping 10.20.31.101 PING 10.20.31.101 (10.20.31.101) 56(84) bytes of data. 64 bytes from 10.20.31.101: icmp_seq=1 ttl=62 time=16.7 ms 64 bytes from 10.20.31.101: icmp_seq=2 ttl=62 time=16.3 ms 64 bytes from 10.20.31.101: icmp_seq=3 ttl=62 time=15.9 ms 64 bytes from 10.20.31.101: icmp_seq=4 ttl=62 time=20.3 ms ^C --- 10.20.31.101 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3004ms rtt min/avg/max/mdev = 15.960/17.343/20.318/1.746 ms
Assuming all went well, that should be it. Leave a comment below if anything is unclear, if you get stuck somewhere, or if something isn’t working right. Enjoy!