Wheelhouse docs

A WireGuard tunnel for a laptop#

You will end up with a WireGuard interface on the router, one peer entry per device, and a laptop that can reach the LAN from anywhere. This is the answer to "I want to reach my network from outside" that does not involve publishing a service to the internet.

Before you start#

  • The operator role and a licence.
  • The WireGuard feature module installed — Services → Apps → WireGuard. It gates the page, not the kernel: the implementation is always present, and the page appears once the module is installed or once interfaces wireguard exists in the configuration.
  • A UDP port you can open, and a way for the laptop to reach the router's public address.
  • Key pairs. Generate them on the router:

    bash
    generate pki wireguard key-pair

    and on the laptop with wg genkey | tee private.key | wg pubkey.

Step 1 — Create the tunnel#

Security → WireGuard → + Add tunnel.

set interfaces wireguard wg0 port 51820
set interfaces wireguard wg0 address 10.10.0.1/24
set interfaces wireguard wg0 private-key <the router's private key>

The panel's private-key field hints at the command that generates one. Give the tunnel its own subnet — 10.10.0.0/24 here — that is not in use anywhere else on your network.

Step 2 — Add the laptop as a peer#

+ Add peer on the tunnel.

set interfaces wireguard wg0 peer laptop public-key <the laptop's public key>
set interfaces wireguard wg0 peer laptop allowed-ips 10.10.0.2/32

allowed-ips on the router's side is the address the peer is allowed to use, and a /32 is right for a single device. The panel takes a comma-separated list and writes one line each.

address, port and persistent-keepalive are for a peer the router initiates to — a site-to-site far end, not a laptop that roams. Leave them empty here.

Step 3 — Open the port#

The tunnel's UDP packets arrive on the uplink, addressed to the router.

set firewall ipv4 input filter rule 100 action accept
set firewall ipv4 input filter rule 100 description 'wireguard'
set firewall ipv4 input filter rule 100 protocol udp
set firewall ipv4 input filter rule 100 destination port 51820

Step 4 — Let the tunnel reach the LAN#

Traffic arriving on wg0 and going to the LAN passes through the forward chain, which defaults to drop.

set firewall ipv4 forward filter rule 40 action accept
set firewall ipv4 forward filter rule 40 description 'wireguard to the LAN'
set firewall ipv4 forward filter rule 40 inbound-interface name wg0

Narrow it if the tunnel should reach one host or one subnet rather than everything:

set firewall ipv4 forward filter rule 40 destination address 192.0.2.0/24

Step 5 — Configure the laptop#

The client configuration is not something the router generates. Write it by hand:

wg0.conf on the laptop
[Interface]
PrivateKey = <the laptop's private key>
Address = 10.10.0.2/24
DNS = 192.0.2.1

[Peer]
PublicKey = <the router's public key>
Endpoint = 203.0.113.2:51820
AllowedIPs = 192.0.2.0/24, 10.10.0.0/24
PersistentKeepalive = 25

AllowedIPs on the client's side means "route these through the tunnel". Listing your LAN sends only LAN traffic through it; 0.0.0.0/0 sends everything, which also needs a source NAT rule on the router so the tunnel's traffic can reach the internet:

set nat source rule 120 source address 10.10.0.0/24
set nat source rule 120 outbound-interface name eth1
set nat source rule 120 translation address masquerade

The four things that have to line up#

Almost every WireGuard problem is one of these being asymmetric:

  1. Keys. The router's peer entry holds the laptop's public key; the laptop's peer entry holds the router's public key. Swapping a public for a private key produces a tunnel that never handshakes and says nothing about why.
  2. Allowed IPs. The router allows the peer's address; the laptop routes the networks it wants through the tunnel. They are different lists and they mean different things.
  3. The endpoint. The laptop needs a reachable address and port for the router. A changing public address needs dynamic DNS.
  4. The firewall. One input rule for the port, one forward rule for the traffic.

Check it worked#

On the router, the interface is up and configured:

bash
show interfaces wireguard wg0
sudo wg show

wg show is the honest one: it reports the last handshake per peer and the bytes transferred. The WireGuard page cannot show you this — it shows tunnels, peers and configuration, and says so, because live handshake data needs wg show exposed by the agent, which it does not do.

From the laptop:

bash
ping -c 3 10.10.0.1        # the tunnel address
ping -c 3 192.0.2.1        # the router's LAN address

The first working and the second not is the forward rule missing. Neither working is the handshake, which is items 1 to 3 above.

Undoing it#

delete interfaces wireguard wg0 peer laptop

for one device, or the whole tunnel:

delete interfaces wireguard wg0
delete firewall ipv4 input filter rule 100
delete firewall ipv4 forward filter rule 40

Removing a peer is how you revoke a device. There is no revocation list; a peer that is not in the configuration cannot connect.

See also#


Checked against ui/src/pages/WireGuard.tsx · agent/main.go · agent/security.go · docs/apps.md

Updated 2026-09-02 wireguard vpn remote-access