WireGuard Road Warrior Setup

Introduction

WireGuard is a simple, fast VPN protocol using modern cryptography. It aims to be faster and less complex than IPsec whilst also being a considerably more performant alternative to OpenVPN. Initially released for the Linux kernel, it is now cross-platform and widely deployable.

This article describes setting up a central WireGuard server, running on OPNsense and configuring a client.

Step 1 - Installation

Install the plugin via System ‣ Firmware ‣ Plugins and selecting the package os-WireGuard.

Once the plugin is installed, refresh the page and you will find the WireGuard configuration menu via VPN ‣ WireGuard.

Step 2a - Setup WireGuard Server

First, create a WireGuard VPN server via VPN ‣ WireGuard under the Local tab. Create a new instance using the + button and customizing the following values as neccessary:

Enabled

Checked

Check to enable the server

Name

WireGuard

The name of the server instance

Instance

(auto populated)

Automatically generated server instance number

Public Key

(empty)

Leave empty, keys will be automatically generated

Private key

(empty)

Leave empty, keys will be automatically generated

Listen Port

51820

Server listen port. If multiple servers exist, this port must be unique

DNS Server

192.168.1.254

Populate as required with DNS server

Tunnel Address

10.10.10.1/24

Use CIDR notation and avoid subnet overlap with regularly used networks

Peers

(empty)

List of peers for this server, leave blank on initial configuration

Disable Routes

Unchecked

This will prevent installing routes

Warning

Ensure that Tunnel Address is a /24 or the desired CIDR notated subnet mask, do not use /32.

Once the tunnel is created after clicking Save, reopen the newly created instance and take note of the public key that was just generated. This key will be required when setting up any client that wishes to connect to this server. Make sure to protect it and use secure transmission methods to clients (e.g. PGP encrypted or via SMS).

Use the Endpoints tab to add the first client. Use the + button and configure the following:

Enabled

Checked

Check to enable the server

Name

client1

The name of the client

Public Key

PubKey

Provide public key from client

Shared Secret

(empty)

optional - shared secret (PSK) for this peer

AllowedIPs

10.10.10.2/32

IP address of client (peer) - ensure to use /32 with multiple clients

Endpoint Address

(empty)

Not required for inbound connections - dynamic

Endpoint Port

(empty)

Not required for inbound connections - dynamic

Keepalive

(empty)

optional - sets persistent keepalive interval

Click Save and return to the Local tab. Now select the newly created peer under Peers. Click Save.

Next, enable WireGuard under the General tab and continue with the setup. Add further clients under Endpoints and allow them to access the Wireguard server by selecting them under Peers.

Hint

Pressing Save effectively executes wg-quick down wg0 followed by wg-quick up wg0 (with 0 being the Instance ID of the server). Though not often required, sometimes it is useful to debug a tunnel not starting via the CLI using wg show. Configuration files are stored at /usr/local/etc/wireguard/wgX.conf.

Step 2b - Setup Firewall rules

For external clients to connect to the WireGuard server firewall rules must be created to permit that traffic to flow from WAN to LAN. Select Firewall ‣ NAT ‣ Port Forward and click +Add creating a rule with the following information:

Interface

WAN

The interface this rule applies to

TCP/IP Version

IPv4

Select the Internet Protocol version this rule applies to

Protocol

UDP

WireGuard works over UDP

Source

Accept traffic from any source

Source Port

Accept traffic on any port

Destination

WAN address

Traffic destination

Destination Port

51820

Specify the port or port range required

Redirect target IP

192.168.1.254

The LAN IP of the firewall

Redirect target port

51820

The listen port for WireGuard server

Description

WG WAN to LAN

Optional - provide a description

If more granular rules are required note there is a new interface wg0 where these may be configured.

The final piece is to allow traffic from the WireGuard network. First define an alias (e.g. VPN_clients) and include in it the IP addresses (e.g. 10.10.10.2 and 10.10.10.3) or subnet (e.g. 10.10.10.0/24) of the WireGuard clients from which traffic is to be allowed. Do this via Firewall ‣ Aliases (click + in the bottom right).

Then create a firewall rule via Firewall ‣ Rules ‣ WireGuard (click +Add in the top right), with the following information (if an item is not specified, leave it set to the default value):

Interface

WireGuard

The interface this rule applies to

Source

VPN_clients

Source subnet - use the alias defined as above

Destination

any

Traffic destination

Description

WG WAN to LAN

Optional - provide a description

Tip

If you have only one local WireGuard instance and only one WireGuard endpoint configured, you can use the default WireGuard net as the source rather than defining and using a new alias.

Hint

Rules defined under Firewall ‣ Rules ‣ WireGuard take precedence over rules individually configured for each tunnel.

Connect to the tunnel from a client and verify connection via VPN ‣ WireGuard using the List Configuration and Handshakes tabs where peers are identified by their public keys. At this point the tunnel should be up and running but the client will have limited access.

Step 2c - Assignments and Routing

Thus far, the setup documented here permits your clients to reach the internal networks configured via Allowed IPs. However, a common use case is that users wish to push all traffic through a VPN tunnel. To do this assign WireGuard an interface via Interfaces ‣ Assignments and select the wgX instance from the New interface dropdown menu. Click + to assign the interface. Once assigned, click Save.

Rename the interface as required and select Prevent Interface Removal by selecting the interface from the Interfaces -> [wgX] list. Do not assign the interface an IP address.

The next step is to configure Outbound NAT. Go to Firewall ‣ NAT ‣ Outbound and add a rule. First, ensure that rule generation is set to manual or hybrid (if unsure, select hybrid). Add a rule (via +Add in the top right) with the following values (unless explictly mentioned below, leave as default):

Interface

WAN

The interface the rule applies to

Source address

wg0 net

Tunnel Network configured previously

Translation / target

WAN address

Packets matching this rule will be mapped to the IP address given here

To reach the Internet from a client via the VPN configure configure AllowedIPs to 0.0.0.0/0.

When assigning interfaces, gateways can be added to them. This is useful if balancing traffic across multiple VPNs is required or in more complex routing scenarios.

To do this, go to System ‣ Gateways ‣ Single and add a new gateway. Choose the relevant WireGuard interface and set the Gateway to dynamic.

Step 3 - Setup WireGuard Client

Tip

Key generation can be performed on any device with WireGuard client tools installed. A one-liner for generating a matching private and public keypair is wg genkey | tee private.key | wg pubkey > public.key.

Client configuration is largely beyond the scope of this article since there is such a wide array of possible targets. However, the key pieces of information required to configure a client are:

  • Address - Server side this is referred to as **Tunnel Address**

  • DNS - DNS server

  • Endpoint - DNS entry or IP supported, include the port here

  • Public Key - Refers to Public Key of the WireGuard server

  • AllowedIPs - Configure which traffic (by subnet) is sent via the tunnel

Appendix A - Example configurations

Warning

Note that WireGuard is still under heavy development and these configurations may change without warning. They are provided for guidance only.

Do not reuse these example keys!

An example Client configuration file:

[Interface]
PrivateKey = 8GboYh0YF3q/hJhoPFoL3HM/ObgOuC8YI6UXWsgWL2M=
Address = 10.10.10.2/32
DNS = 192.168.1.254

[Peer]
PublicKey = OwdegSTyhlpw7Dbpg8VSUBKXF9CxoQp2gAOdwgqtPVI=
AllowedIPs = 0.0.0.0/0
Endpoint = vpn.example.com:51820

An example Server configuration file:

[Interface]
Address = 10.10.10.1/24
DNS = 192.168.1.254
ListenPort = 51820
PrivateKey = YNqHwpcAmVj0lVzPSt3oUnL7cRPKB/geVxccs0C0kk0=
[Peer]
PublicKey = CLnGaiAfyf6kTBJKh0M529MnlqfFqoWJ5K4IAJ2+X08=
AllowedIPs = 10.10.10.2/32