Wireguard is a wonderfully superior VPN. Its simple, fast, lightweight, modern, GPL licensed and very secure. Read more at Wireguard.com
Here is the setup:
10.11.13.0/24 is the home lan subnet with 10.11.13.1 as the OpenWRT gateway/router (v19.07.4).
172.21.13.0/24 is a public vlan that we will setup to route over the vpn.
10.11.14.0/24 is the wireguard subnet with 10.11.14.1 as the Wireguard interface (wg0).
Each wireguard client will be assigned an address between 10.11.13.2-254
Begin by installing the required packages on the OpenWRT gateway (Alternately, this can be done from Luci. System -> Software)
opkg install luci-app-wireguard wireguard wireguard-tools
Add a new interface for Wireguard. From the Luci interface go to “Network -> Interfaces -> Add New interface”. Call it wg0
Generate a public/private key for the server using the wg utility
wg genkey | tee [name].privatekey | wg pubkey > [name].publickey
wg genkey | tee mywgserver.privatekey | wg pubkey > mywgserver.publickey
cat mywgserver.publickey LOXb3qL66NfFMWim9tQP+RhWsEVpnlQpm1kpcpJsYHU=
cat mywgserver.privatekey QFLJ9p7MFz31DxTqNKCTu2ARhxLvN0lWhvoKarBT2Vg=
Create the Wireguard interface.
Add the private key from above
listen port 51820
keep alive of 25
Optionally, add the following to /etc/config/network
config interface 'wg0' option proto 'wireguard' option private_key 'QFLJ9p7MFz31DxTqNKCTu2ARhxLvN0lWhvoKarBT2Vg=' option listen_port '51820' list addresses '10.11.14.1/24'
Create a firewall zone for the wg0 interface and allow forwarding to and from the lan and public zones. As well as allow it to forward to the wan zone. This is needed when routing all traffic through the vpn. Network -> Firewall -> Add (zone)
Optionally, add the following to /etc/config/firewall
config zone option name 'wg' option input 'ACCEPT' option network 'wg0' option output 'ACCEPT' option forward 'REJECT' config forwarding option dest 'lan' option src 'wg' config forwarding option dest 'public_zone' option src 'wg' config forwarding option dest 'wg' option src 'lan' config forwarding option dest 'wg' option src 'public_zone' config forwarding option dest 'wan' option src 'wg'
We need to open up the Wireguard port in the firewall. You can use any port you like. I’m using the default (51820).
Network -> Firewall -> Traffic Rules -> Add
Change the following, leaving everything else default
Source zone: wan
Destination zone: Device
Destination port: 51820
Optionally, add a firewall rule to /etc/config/firewall
config rule option dest_port '51820' option src 'wan' option name 'wan-local-wg' option target 'ACCEPT' list proto 'udp'
Now lets setup a peer (client).
Generate a public private keypair
wg genkey | tee jason.privatekey | wg pubkey > jason.publickey
cat jason.privatekey OHs907NqGJD1NWY2yvrGjhYvNju48Q+E8/nnSy4jKmE=
cat jason.publickey N6bm45DTywv+dvTK5FRk47Agil+n+k5N0JyaOvfL7iw=
– Add a description: jason
– Paste the public key: N6bm45DTywv+dvTK5FRk47Agil+n+k5N0JyaOvfL7iw=
– Add a Preshared Key if you are worried about quantum computing compromising your keypair sometime in the future.
– Set “Allowed IPs” to an ip inside the wireguard subnet (10.11.14.0/24). For this peer we will use 10.11.14.10/32. If you add another peer this address will need to be unique. So the next peer can use .11/32.
Wireguard uses a ip to pubkey mechanism called cryptokey routing. In this case any traffic destined for 10.11.14.10 will be encrypted with this peers public key “…L7iw=” and sent to its most recent endpoint address.
– Change the “Persistent Keep Alive” to 25 seconds, which is recommended for traversing NAT. If your not behind NAT leave it blank.
Optionally, you can add a peer directly to /etc/config/network
config wireguard_wg0 option persistent_keepalive '25' option public_key 'N6bm45DTywv+dvTK5FRk47Agil+n+k5N0JyaOvfL7iw=' option description 'jason' list allowed_ips '10.11.14.10/32'
Now we are ready connect as a peer to this server. This can be done a number of ways. Wireguard has adopted a modular model like most GNU projects. They don’t concern themselves with the configuration or key distribution.
Here is a quote from the project “WireGuard securely encapsulates IP packets over UDP. You add a WireGuard interface, configure it with your private key and your peers’ public keys, and then you send packets across it. All issues of key distribution and pushed configurations are out of scope of WireGuard; these are issues much better left for other layers, lest we end up with the bloat of IKE or OpenVPN“
There are a few client connection options. You can do this manually (or scripted) using ip and wg or there is a helper script called wg-quick.
This is part of the wireguard-tools package on Debian.
I recommend wg-quick because its easy and slick. Create a config file called something like jasonvpn.conf either in your home directory someplace or in /etc/wireguard/
I prefer the vpn config in my home directory. I place mine in a directory called ~/wg/
Here is the client config with some options commented out (#) for reference. Save this to a file called whatever.conf and run
wq-quick up whatever.conf
[Interface] Address = 10.11.14.10/32 PrivateKey = OHs907NqGJD1NWY2yvrGjhYvNju48Q+E8/nnSy4jKmE= #DNS = 10.11.14.1 [Peer] PublicKey = LOXb3qL66NfFMWim9tQP+RhWsEVpnlQpm1kpcpJsYHU= Endpoint = [wireguard server IP or hostname]:51820 #AllowedIPs = 0.0.0.0/0, ::/0 AllowedIPs = 10.11.13.0/24, 172.21.13.0/24 # This is for if you're behind NAT PersistentKeepalive = 25
Take note that the [Peer] PublicKey is the servers (openwrt gateway) public key and the [Interface] PrivateKey is the private key we generated for Jason. The corresponding public key for Jason is what we added to the servers Peer section.
The above “AllowedIPs” will allow for split tunnel, where the client can connect to remote subnet 10.11.13.0/24 and 172.21.13.0/24 and any other traffic will route out of their default gateway. If you want to route all traffic through the vpn then set “AllowedIPs = 0.0.0.0/0, ::/0”
Wireguard uses some fancy routing features of iproute2. Containers, Namespaces, and using fwMark to solve deficiencies of the old routing methods.
Lets test the above whatever.conf connection. Instead of calling it whatever.conf I have called it vv.conf and saved it in ~/wg/
Now lets start the vpn
sudo wg-quick up wg/vv.conf Warning: `/home/jason/wg/vv.conf' is world accessible [#] ip link add vv type wireguard [#] wg setconf vv /dev/fd/63 [#] ip -4 address add 10.11.14.10/32 dev vv [#] ip link set mtu 1420 up dev vv [#] ip -4 route add 172.21.13.0/24 dev vv [#] ip -4 route add 10.11.13.0/24 dev vv
Can we ping the remote gateway?
ping 10.11.13.1 PING 10.11.13.1 (10.11.13.1) 56(84) bytes of data. ^C --- 10.11.13.1 ping statistics --- 9 packets transmitted, 0 received, 100% packet loss, time 8188ms
Nope. Lets check the status using wg show
sudo wg show interface: vv public key: N6bm45DTywv+dvTK5FRk47Agil+n+k5N0JyaOvfL7iw= private key: (hidden) listening port: 42233 peer: LOXb3qL66NfFMWim9tQP+RhWsEVpnlQpm1kpcpJsYHU= endpoint: [remote ip]:51820 allowed ips: 10.11.13.0/24, 172.21.13.0/24 transfer: 0 B received, 6.36 KiB sent persistent keepalive: every 25 seconds
Looks like its setup but not receiving any data. Aha! I forgot to restart the server interface after adding a peer.
Also, lets fix the error “Warning: `/home/jason/wg/vv.conf’ is world accessible”
chmod o-r /home/jason/wg/vv.conf
A convenient way to use wireguard is by adding the client to your network-manager.
Left click Network Manager -> VPN Connections -> “Configure VPN…”
nm-connection-editor from a terminal (I don’t know how to do this from Gnome’s network manager front end).
Lastly, you can automatically start wireguard using systemd
Place your client config (vv.conf) in /etc/wireguard/and run
systemctl enable wg-quick@vv