← Start of tutorial

WIUNIX ACADEMY

WireGuard hub and spoke with filtered BGP and FRRouting

Page 4 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
16

LET’S BUILD

Validate, then start BGP

On each node check file ownership and parse bgpd configuration. Parse success is not forwarding evidence. Start the newly configured lab service, then inspect sessions and zebra routes. Do not use bgpd --listenon to constrain binding: it implies no-kernel behavior. The firewall is the exposure boundary here. Timers3/9 are for this controlled lab; internet loss/CPU pressure can cause flaps. Choose production timers from measurements. Graceful restart is not enabled; retaining stale routes cannot create a second hub.

bash

Dedicated fresh lab gateways; Bash

sudo chown frr:frr /etc/frr/frr.conf
sudo chmod 0640 /etc/frr/frr.conf
sudo /usr/lib/frr/bgpd -C -f /etc/frr/frr.conf
sudo systemctl start frr
sudo vtysh -c 'show bgp ipv4 unicast summary' -c 'show ip route bgp'
ip route show proto bgp
How do I know it worked?

Hub has two Established neighbors and two accepted LANs; each spoke has one Established neighbor and only the opposite LAN installed via its hub tunnel address.

17

LET’S BUILD

Start a temporary receiver on B

In a second terminal on B, keep this process in the foreground. Stop with Ctrl-C after A’s request. Use the gateway LAN address, not all interfaces. Permit this port only for the exact remote lab source.

bash

B; separate terminal

python3 -m http.server 8087 --bind '10.72.20.1' --directory /usr/share/doc/wireguard-tools
How do I know it worked?

Receiver listens on the selected B address and port.

18

LET’S BUILD

Check both routing planes and real traffic

Run this panel on A. Run the corresponding checks from B with gateway/source and destination swapped. Expect B’s prefix through 10.254.1.1 on wg-ac-a, with B’s ASN after the hub ASN in the AS path. A’s connected LAN must remain local. No unexpected default may be installed by BGP. Then start a temporary receiver on B in a separate terminal, test from A, and stop it with Ctrl-C. A fresh response body proves receiver traffic, while route/session checks establish BGP; neither alone replaces the other. These tests use gateway addresses, not separate LAN clients.

bash

Dedicated fresh lab gateways; Bash

test "$ROLE" = a
sudo vtysh -c 'show bgp ipv4 unicast 10.72.20.0/24' -c 'show ip route 10.72.20.0/24'
ip route get '10.72.20.1' from '10.71.10.1'
ip route show proto bgp
ping -c 3 -I '10.71.10.1' '10.72.20.1'
curl --fail --noproxy '*' --interface '10.71.10.1' --connect-timeout 3 'http://10.72.20.1:8087/'
How do I know it worked?

A sees B through 10.254.1.1, AS path 65000 65020, no BGP default, successful sourced ping and a fresh HTTP response from B.

19

LET’S BUILD

Give LAN clients a deliberate return path

If these gateways are the LAN clients’ default routers, remote site traffic already reaches them. If another router is the default gateway, install only the remote site CIDR toward the local WireGuard gateway on that router, and retain its original configuration. A router must already reach the next-hop on its LAN. Do not replace the default route or NAT to conceal a missing return path. Permit selected application services in all relevant firewalls. Test from real clients in both directions separately; a gateway ping does not prove this branch.

bash

Dedicated fresh lab gateways; Bash

# Run only the matching branch on the existing Linux LAN router.
read -r -p 'LAN router (a/b): ' LAN_ROLE
case "$LAN_ROLE" in
 a) sudo ip route add '10.72.20.0/24' via '10.71.10.1' ;;
 b) sudo ip route add '10.71.10.0/24' via '10.72.20.1' ;;
 *) exit 1 ;;
esac
How do I know it worked?

Each real LAN client has a reviewed outbound and return route; persist only through that router’s owning network manager.

20

LET’S BUILD

Withdraw one prefix without stopping WireGuard

Controlled lab only: remove B’s network advertisement. Watch A’s BGP RIB and kernel every second with timestamps; the prefix must disappear from both while tunnel addresses remain reachable. This deliberate withdrawal does not wait for the hold timer. Restore the exact network statement and verify the route and receiver again. Do not save the temporary withdrawal. Measure actual convergence; nine seconds is a hold-timer bound for a silent neighbor under suitable conditions, not an application RTO guarantee.

bash

Dedicated fresh lab gateways; Bash

test "$ROLE" = b
sudo vtysh -c 'configure terminal' -c 'router bgp 65020' -c 'address-family ipv4 unicast' -c 'no network 10.72.20.0/24'
How do I know it worked?

B’s running BGP configuration temporarily omits only 10.72.20.0/24; the tunnel and management remain active.

21

LET’S BUILD

Observe withdrawal on A

On A, repeat this panel with timestamps until the remote route disappears. The connected hub address must remain reachable. Keep the independent management path available.

bash

A

test "$ROLE" = a
date -Ins
sudo vtysh -c 'show bgp ipv4 unicast 10.72.20.0/24'
ip route show '10.72.20.0/24'
ping -c 2 '10.254.1.1'
How do I know it worked?

No B prefix in BGP/kernel; connected hub peer is reachable.

Explore all tutorials ↗