Oct 262021
 
 October 26, 2021  Posted by at 1:20 pm Tutorial, vpn  Add comments

Wireguard is a wonderfully superior VPN. Its simple, fast, lightweight, modern, GPL licensed and very secure. Read more at wikipedia

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)
ssh root@10.11.13.1
opkg update
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
For example:
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
ip 10.11.14.1/24
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
Name: wan-local-wg
Protocol: UDP
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=

From Network -> Interfaces. “Edit” wg0 -> Peers -> Add Peers

– 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'

After adding a peer the wg0 interface needs to be restarted!

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.

If you want to route all traffic through the vpn (equivalent of split tunnel) 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 split tunnel 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…”

or run 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

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)