← Start of tutorial

WIUNIX ACADEMY

WireGuard hub and spoke with filtered BGP and FRRouting

Page 5 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.

Ubuntu 24.04 LTSReviewed 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
22

LET’S BUILD

Restore B and check the receiver again

Run on B, then repeat the route and receiver checks on A. If the independent console is unavailable, postpone disruptive exercises. Do not save a temporary failed state.

bash

B

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

The exact prefix reappears and the receiver responds through the hub.

23

LET’S BUILD

Test policy in a disposable copy

In the isolated test, B attempted to announce a default and an unrelated prefix; explicit output and input prefix filters kept both out of the hub and A. Do not inject test routes into production. Inspect advertised routes and exact prefix lists here. An Established session displaying (Policy) rather than a count indicates missing inbound/outbound policy; fix the exact filter, never disable ebgp-requires-policy. Excess accepted prefixes can shut a neighbor down; investigate before clearing it. Negative route-leak testing and session-loss timing are distinct from a ping.

bash

Dedicated fresh lab gateways; Bash

# Hub
sudo vtysh -c 'show ip prefix-list' -c 'show bgp ipv4 unicast neighbors 10.254.1.2 advertised-routes' -c 'show bgp ipv4 unicast neighbors 10.254.2.2 advertised-routes'
ip route show default
How do I know it worked?

Hub advertises only 10.72.20.0/24 to A and only 10.71.10.0/24 to B; no default or unrelated prefix appears.

24

LET’S BUILD

Find the failing layer before changing routes

No handshake: check endpoint UDP/NAT/key identity, not BGP. Handshake but Idle/Active: check connected /30, exact TCP179 policy, source addresses and ASN. Established with no route: check exact connected LAN, network import-check, AF activation and both prefix lists. RIB without kernel route: inspect zebra, nexthop resolution and competing administrative distance. Small ping works but HTTP stalls: inspect PMTUD and effective MTU; allow ICMP errors instead of globally disabling PMTUD. Never print showconf or dump private keys into reports.

bash

Dedicated fresh lab gateways; Bash

sudo wg show
ip -d link show 'wg-ac-a'
sudo ss -lntp '( sport = :179 )'
sudo vtysh -c 'show bgp ipv4 unicast summary' -c 'show ip route'
sudo journalctl -u frr --since '-10 minutes' --no-pager
sysctl net.ipv4.ip_forward net.ipv4.conf.all.rp_filter
sudo nft list ruleset
# A only: one bounded PMTU probe; reduce size if the real path is smaller
ping -c 2 -M do -s 1200 -I '10.71.10.1' '10.72.20.1'
How do I know it worked?

The first failing layer is identified from handshake/session/policy/zebra/FIB/receiver evidence before any route is changed.

Persist only after the lab is healthy

The commands so far deliberately do not enable tunnel boot or persist sysctl/firewall. After checking the route inventory, persist the reviewed sysctls and nftables guard through the existing OS/firewall owner; do not overwrite the global ruleset or run sysctl --system blindly. Enable the matching wg-quick units and FRR only on the fresh VMs, then schedule a console-backed reboot test separately. FRR reconnects when tunnel addresses return; service ordering alone is not a readiness guarantee. Reboot, NAT roaming and independent-host failure are not established by a same-host namespace lab.

25

LET’S BUILD

Reverse only the lab-owned changes

With console access, stop this new lab FRR first and verify its learned routes vanish while management is retained. For a real migration, prepare and verify the approved previous static paths before shutting neighbors; this lab created no remote static paths on gateways. Keep WireGuard while validating routing recovery, then bring down only the matching lab tunnels. Remove only the exact router routes added in the optional branch. Restore saved sysctl values individually after deciding no other workload needs forwarding; retain keys/config/evidence for inspection. Remove only the named guard after BGP has stopped. Never flush route tables or the entire firewall.

bash

Dedicated fresh lab gateways; Bash

# Fresh lab gateways only, in the original ROLE shell
sudo systemctl stop frr
ip route show proto bgp
# Check management before this step
case "$ROLE" in
 h) sudo wg-quick down 'wg-ac-a'; sudo wg-quick down 'wg-ac-b' ;;
 a) sudo wg-quick down 'wg-ac-a' ;;
 b) sudo wg-quick down 'wg-ac-b' ;;
 *) exit 1 ;;
esac
sudo nft delete table inet academy_bgp
sudo cat '/srv/academy-wgbgp/sysctl-before.txt'
How do I know it worked?

Only lab-owned paths/services are removed; management, unrelated routes, firewall tables and protected recovery inputs remain.

26

LET’S BUILD

Reverse only the optional LAN-router route

Only on the Linux LAN router where this lab added the exact route; otherwise skip. Preserve all pre-existing routes. Gateway recovery above does not require this panel.

bash

Optional existing Linux LAN router

read -r -p 'LAN router (a/b): ' LAN_ROLE
case "$LAN_ROLE" in
 a) sudo ip route del '10.72.20.0/24' via '10.71.10.1' ;;
 b) sudo ip route del '10.71.10.0/24' via '10.72.20.1' ;;
 *) exit 1 ;;
esac
How do I know it worked?

Only the optional exact route is removed.

Explore all tutorials ↗