jason schaefer . com

"arguing that you don’t care about the right to privacy because you have nothing to hide is no different than saying you don’t care about free speech because you have nothing to say."

Wireguard VPN server on OpenWRT

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)
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.

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…”

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

Comments

12 responses to “Wireguard VPN server on OpenWRT”

  1. CHIVOT Laurent Avatar
    CHIVOT Laurent

    Hello, and first of all thank you for taking the time to explain.
    Unfortunately my TPlink with open wrt 2102 refuses to launch the vpn…any help or hint would be greatly appreciated

  2. jason Avatar

    Hi Laurent
    Can you ssh into the router and run “wg show” from the terminal? It should output something like this:
    interface: wg0
    public key: QWJ+0UqO0PH84EarZ75mAKoXG8sdfasDfwdSNRhiTpiw=
    private key: (hidden)
    listening port: 51820

  3. Vincent Avatar
    Vincent

    Hello, thanks a lot for our well illustrated and very clear setup of a wireguard server under openwrt.
    I set it up on a GL.iNet GL-AR750S router running OpenWrt 19.07.8 with LuCI, configured as an Access Point (router is connected to main internet router with cable).
    My client laptop connects to the wireguard fine, but no traffic is being routed to the wan… I guess this has to do with he firewall rules ?
    Any help or hint would be much appreciated thank you.

    OpenWrt 19.07.8, r11364-ef56c85848
    —————————————————–
    root@GL-AR750S:~# wg show
    interface: wg0
    public key: 5CLs1RN5jKpkxyc…
    private key: (hidden)
    listening port: 51050

    peer: 1kRksDYDNk5IY7bVlmaH+…
    endpoint: x.x.x.x:59620
    allowed ips: 10.11.14.10/32
    latest handshake: 1 minute, 24 seconds ago
    transfer: 45.78 KiB received, 3.90 MiB sent
    persistent keepalive: every 25 seconds

  4. L Fox Avatar
    L Fox

    I just bought a gl-inet GL-AX1800. Added luci. When I try to add a new interface, it does not list Wireguard Server as an option. The dropdown only lists:
    Static address, DHCP client, Unmanaged, DHCPv6 client, PPP, PPPOE, and UMTS/GRPS/EV-DO
    Can I use any of those?

  5. jason Avatar

    Hi Vincent

    I would recommend you setup the vpn server on the gateway. It will make for a simpler routing setup.
    If you want to try and make it work as you described, you can route all traffic through the access-point-vpn with AllowedIPs 0.0.0.0/0 and NAT your vpn traffic into the upstream subnet OR you can add a route on the gateway for your vpn subnet to go back to the AP that hosts your vpn.
    Something like “[vpn-subnet]/24 via [access-point-ip] dev br-lan proto static”.
    Also, your access-point-vpn needs a default gateway that points to your gateway router for any of this to work.

  6. jason Avatar

    L Fox
    Did you install wireguard as described in the tutorial?
    You may want to install stock OpenWRT as well. I’ve seen hardware vendors make changes to openWRT that break functionality or are terribly done.

  7. Diego Avatar
    Diego

    Dear Jason,
    Thanks for this tutorial!

    I have a question: Why the traffic rule is needed if you create a firewall zone? Also, could you please explain how this firewall zone works? Because in the OpenWRT docs they suggest to use the LAN zone with the WireGuard interface.

    Thanks in advance :D

  8. jason Avatar

    Hi Diego
    The traffic rule is needed because of NAT. It forwards (DNAT) traffic from the wan to the local device where wg is installed.
    You can add the vpn to the lan zone but I create a separate zone so I have more control. For example, if I want the vpn to access my public vlan and I don’t want the lan to have access to public I need to have a separate zone for vpn and lan.

  9. Diego Avatar
    Diego

    Thanks Jason! I was going crazy trying to understand the firewall configuration for WireGuard, and you made it simple :D

  10. Julian Hughes Avatar
    Julian Hughes

    I found this blog very useful, thank you. I do think that not placing the wireguard device in the lan zone and instead assigning it to its own firewall zone confuses things for many people though. It’s something specific to your own situation will introduce unexpected issues for most people. I tried it your way and it didn’t work until I also added a port forward/redirect redirecting wan 51820 to the DNAT target openwrt device, which is quite a convoluted way of doing things. I then decided to change to a more vanilla config, so moved the wireguard device into the lan zone, removed the extra port forward and then a simple rule like your wan-local-wg rule worked fine. I think if I’d been new to using wireguard I’d not have succeeded using your guide. As it was, I was moving my wireguard service off a Linux server on my LAN and onto my OpenWrt router and so could have a look at a known working config and consider the differences and adjust as necessary. Anyway, I did find it useful as OpenWrt’s wiki pages are so terse and I really like to see description and examples before making changes, so thanks again.

  11. jason Avatar

    Julian, I don’t understand what you mean by the “extra port forward”. No matter how you set it up (in lan or its own zone), you would need dnat unless you weren’t using nat at all. I wonder if you actually got hung up with the firewall zone forwarding rules between wg and lan? I hope you are able to help clarify this because it does seem to be a place of confusion and it would be cool if we could make this even more clear and precise. Thank you for your help!

Leave a Reply

Your email address will not be published. Required fields are marked *