← Start of tutorial

WIUNIX ACADEMY

WireGuard hub and spoke with filtered BGP and FRRouting

Page 2 of 6. Review the earlier steps and prerequisites before continuing.

YOUR SYSTEM. YOUR STEPS.

Where are you working?

Choose your OS and version. The prerequisites, commands and troubleshooting follow your environment.

Debian 13Reviewed against official documentation ·

USE YOUR OWN VALUES

Configure this tutorial

Set the example values for your environment; related explanations and copy panels update together. Never enter passwords, private keys or tokens. Values stay in this tab and are not sent to the server or share links. Check actual DNS, certificates and network policy before running commands.

Different IP addresses, domains or ports? Open the settings below, change the values and select “Apply to tutorial”, then copy the updated commands.

Set values for my environment19 editable values
03

LET’S BUILD

Generate keys without printing private material

On each gateway create its own fresh root and key. Public keys may be exchanged after authenticating the remote administrator. Never copy a private key to another node, browser settings, chat or Git. The hub can use one private key on its two separate interfaces; each spoke has its own key. Files that will contain PrivateKey must be mode0600 before editing. Retain private backups in protected storage.

bash

Dedicated fresh lab gateways; Bash

set -eu
sudo install -d -m 0700 '/srv/academy-wgbgp'
sudo sh -c 'umask 077; wg genkey > "/srv/academy-wgbgp/private.key"; wg pubkey < "/srv/academy-wgbgp/private.key" > "/srv/academy-wgbgp/public.key"'
sudo cat '/srv/academy-wgbgp/public.key'
sudo install -d -m 0700 /etc/wireguard
sudo cp -a /etc/frr '/srv/academy-wgbgp/frr-before'
sudo sh -c 'ip route show table all > "/srv/academy-wgbgp/routes-before.txt"; sysctl net.ipv4.ip_forward net.ipv4.conf.all.rp_filter net.ipv4.conf.default.rp_filter > "/srv/academy-wgbgp/sysctl-before.txt"'
How do I know it worked?

Only a public key appears on screen; private.key is0600 in the new0700 root and initial FRR/routes/sysctls are retained.

04

LET’S BUILD

Open both protected hub tunnel files

Hub only. Paste the following file contents into their named files. In the protected editor replace REPLACE_PRIVATE_KEY from this node’s private file and replace public-key placeholders from the authenticated peers. Do not run the template as shell. Close the editor before enabling anything. No endpoint is required on the hub: it learns authenticated spoke endpoints. Do not enable SaveConfig, which can overwrite reviewed files.

bash

Dedicated fresh lab gateways; Bash

test "$ROLE" = h
sudo install -m 0600 /dev/null '/etc/wireguard/wg-ac-a.conf'
sudo install -m 0600 /dev/null '/etc/wireguard/wg-ac-b.conf'
sudo nano '/etc/wireguard/wg-ac-a.conf' '/etc/wireguard/wg-ac-b.conf'
How do I know it worked?

Both hub files are0600; public keys belong to A/B and the private key belongs only to this hub. No placeholders remain before activation.

05

LET’S BUILD

File: hub link to A

Only A’s inner address and source LAN are allowed on this peer.

ini · /etc/wireguard/wg-ac-a.conf

Dedicated fresh lab gateways; Bash

[Interface]
Address = 10.254.1.1/30
ListenPort = 51871
PrivateKey = REPLACE_PRIVATE_KEY
Table = off
MTU = 1380

[Peer]
PublicKey = REPLACE_PEER_PUBLIC_KEY
AllowedIPs = 10.254.1.2/32, 10.71.10.0/24
How do I know it worked?

The A-link file has hub 10.254.1.1/30, UDP51871, Table=off and only 10.254.1.2/32 plus 10.71.10.0/24 for its authenticated peer.

06

LET’S BUILD

File: hub link to B

This separate interface has its own connected /30 and UDP listener.

ini · /etc/wireguard/wg-ac-b.conf

Dedicated fresh lab gateways; Bash

[Interface]
Address = 10.254.2.1/30
ListenPort = 51872
PrivateKey = REPLACE_PRIVATE_KEY
Table = off
MTU = 1380

[Peer]
PublicKey = REPLACE_PEER_PUBLIC_KEY
AllowedIPs = 10.254.2.2/32, 10.72.20.0/24
How do I know it worked?

The B-link file has hub 10.254.2.1/30, UDP51872, Table=off and only 10.254.2.2/32 plus 10.72.20.0/24 for its authenticated peer.

07

LET’S BUILD

Open the appropriate protected spoke file

Run only the matching line on each spoke, then use its matching file below. Each file’s peer public key is the hub’s public key. Insert only the local private key using the protected editor. Keepalive25 is useful for NAT; remove it when no mapping needs preservation. The documentation endpoint is not an operational internet address: use the real reachable hub in settings.

bash

Dedicated fresh lab gateways; Bash

case "$ROLE" in
 a) sudo install -m 0600 /dev/null '/etc/wireguard/wg-ac-a.conf'
    sudo nano '/etc/wireguard/wg-ac-a.conf' ;;
 b) sudo install -m 0600 /dev/null '/etc/wireguard/wg-ac-b.conf'
    sudo nano '/etc/wireguard/wg-ac-b.conf' ;;
 *) printf '%s
' 'Spokes only'; exit 1 ;;
esac
How do I know it worked?

Only the matching spoke file is created, with mode0600, its local private key and the authenticated hub public key.

08

LET’S BUILD

File: A to hub

The hub peer carries B’s LAN, not an internet default.

ini · /etc/wireguard/wg-ac-a.conf

Dedicated fresh lab gateways; Bash

[Interface]
Address = 10.254.1.2/30
ListenPort = 51871
PrivateKey = REPLACE_PRIVATE_KEY
Table = off
MTU = 1380

[Peer]
PublicKey = REPLACE_PEER_PUBLIC_KEY
AllowedIPs = 10.254.1.1/32, 10.72.20.0/24
Endpoint = 198.51.100.10:51871
PersistentKeepalive = 25
How do I know it worked?

A uses 10.254.1.2/30 and sends only 10.254.1.1/32 and 10.72.20.0/24 to the hub endpoint 198.51.100.10:51871; no default AllowedIPs.

09

LET’S BUILD

File: B to hub

The hub peer carries A’s LAN. Never use identical competing AllowedIPs for two peers on one interface.

ini · /etc/wireguard/wg-ac-b.conf

Dedicated fresh lab gateways; Bash

[Interface]
Address = 10.254.2.2/30
ListenPort = 51872
PrivateKey = REPLACE_PRIVATE_KEY
Table = off
MTU = 1380

[Peer]
PublicKey = REPLACE_PEER_PUBLIC_KEY
AllowedIPs = 10.254.2.1/32, 10.71.10.0/24
Endpoint = 198.51.100.10:51872
PersistentKeepalive = 25
How do I know it worked?

B uses 10.254.2.2/30 and sends only 10.254.2.1/32 and 10.71.10.0/24 to the hub endpoint 198.51.100.10:51872; no default AllowedIPs.

Explore all tutorials ↗