WIUNIX ACADEMY
WireGuard hub and spoke with filtered BGP and FRRouting
Page 3 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.
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
LET’S BUILD
Constrain BGP before starting FRR
Using the existing firewall manager, allow hub UDP51871 and UDP51872 from the actual spoke egress addresses (or a deliberate roaming policy). Allow replies on spokes. Allow TCP179 only between 10.254.1.1↔10.254.1.2 on wg-ac-a and 10.254.2.1↔10.254.2.2 on wg-ac-b, never on public interfaces. Restrict forwarding to 10.71.10.0/24↔10.72.20.0/24 and required test/application services, with established replies and ICMP fragmentation-needed for PMTUD. Preserve management and do not NAT the LANs. An accept in another nftables base chain cannot override a later drop. The additive guard below only blocks public BGP; it does not open required traffic or replace the existing firewall. Run before FRR on each VM; a table name collision means stop.
Dedicated fresh lab gateways; Bash
sudo nft list table inet academy_bgp 2>/dev/null && exit 1
sudo nft -f - <<'NFT'
table inet academy_bgp {
chain input {
type filter hook input priority -10; policy accept;
tcp dport 179 iifname != { "wg-ac-a", "wg-ac-b" } counter drop
}
}
NFT
sudo nft list table inet academy_bgp
Public BGP is blocked; separately reviewed existing firewall rules permit only the described peers, UDP and selected LAN traffic.
LET’S BUILD
Bring up transport and check route ownership
Use the hub lines on the hub and the matching spoke line on each spoke. No remote LAN route should appear yet. A recent handshake proves cryptographic exchange, not BGP or forwarding. MTU1380 is a conservative starting example for a1500-byte underlay, not universal; smaller paths require a smaller reviewed MTU on both ends. Strict rp_filter can discard valid asymmetric traffic. On these fresh lab gateways enable forwarding first, then loose reverse-path checks; a production policy needs a separate review. Snapshot values were retained in the lab root.
Dedicated fresh lab gateways; Bash
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv4.conf.all.rp_filter=2 net.ipv4.conf.default.rp_filter=2
case "$ROLE" in
h) sudo wg-quick up 'wg-ac-a'; sudo wg-quick up 'wg-ac-b' ;;
a) sudo wg-quick up 'wg-ac-a' ;;
b) sudo wg-quick up 'wg-ac-b' ;;
*) exit 1 ;;
esac
sudo wg show
ip route show proto kernel
ip route show proto bgp
Matching interfaces are UP with connected /30 routes; traffic triggers a recent handshake. No remote LAN route exists until BGP installs it.
LET’S BUILD
Open the integrated routing configuration
On each fresh VM paste only its matching file below. The initial package configuration is backed up. Keep zebra enabled and set bgpd=yes in the distribution daemon file; enable no other protocol. No redistribute connected, default-originate, route reflector, broad permit or no-policy bypass belongs in this design. Prefix lists match exact CIDRs; implicit deny rejects everything else. maximum-prefix is a secondary limit on accepted prefixes, not a substitute for filters or a guarantee against control-plane overload.
Dedicated fresh lab gateways; Bash
sudo nano /etc/frr/daemons /etc/frr/frr.conf
The saved integrated file matches this node’s role; zebra and bgpd are enabled and no unrelated routing protocol is enabled.
LET’S BUILD
File: hub routing
Use this file only on hub. The LAN network must have an exact connected route on its owner; do not manufacture reachability with a blackhole route.
Dedicated fresh lab gateways; Bash
frr defaults traditional
service integrated-vtysh-config
hostname academy-hub
ip prefix-list FROM-A seq 10 permit 10.71.10.0/24
ip prefix-list FROM-B seq 10 permit 10.72.20.0/24
router bgp 65000
bgp router-id 10.254.1.1
bgp ebgp-requires-policy
no bgp default ipv4-unicast
neighbor 10.254.1.2 remote-as 65010
neighbor 10.254.1.2 update-source 10.254.1.1
neighbor 10.254.1.2 timers 3 9
neighbor 10.254.2.2 remote-as 65020
neighbor 10.254.2.2 update-source 10.254.2.1
neighbor 10.254.2.2 timers 3 9
address-family ipv4 unicast
neighbor 10.254.1.2 activate
neighbor 10.254.1.2 prefix-list FROM-A in
neighbor 10.254.1.2 prefix-list FROM-B out
neighbor 10.254.1.2 maximum-prefix 1
neighbor 10.254.1.2 next-hop-self
neighbor 10.254.2.2 activate
neighbor 10.254.2.2 prefix-list FROM-B in
neighbor 10.254.2.2 prefix-list FROM-A out
neighbor 10.254.2.2 maximum-prefix 1
neighbor 10.254.2.2 next-hop-self
exit-address-family
Both neighbors have exact inbound and outbound prefix lists, maximum-prefix1 and next-hop-self; hub advertises no local/default network.
LET’S BUILD
File: spoke A routing
Use this file only on spoke A. The LAN network must have an exact connected route on its owner; do not manufacture reachability with a blackhole route.
Dedicated fresh lab gateways; Bash
frr defaults traditional
service integrated-vtysh-config
hostname academy-a
ip prefix-list OWN seq 10 permit 10.71.10.0/24
ip prefix-list REMOTE seq 10 permit 10.72.20.0/24
router bgp 65010
bgp router-id 10.254.1.2
bgp ebgp-requires-policy
bgp network import-check
no bgp default ipv4-unicast
neighbor 10.254.1.1 remote-as 65000
neighbor 10.254.1.1 update-source 10.254.1.2
neighbor 10.254.1.1 timers 3 9
address-family ipv4 unicast
network 10.71.10.0/24
neighbor 10.254.1.1 activate
neighbor 10.254.1.1 prefix-list REMOTE in
neighbor 10.254.1.1 prefix-list OWN out
neighbor 10.254.1.1 maximum-prefix 1
exit-address-family
A advertises exactly 10.71.10.0/24 and accepts exactly 10.72.20.0/24 from AS65000, with network import-check enabled.
LET’S BUILD
File: spoke B routing
Use this file only on spoke B. The LAN network must have an exact connected route on its owner; do not manufacture reachability with a blackhole route.
Dedicated fresh lab gateways; Bash
frr defaults traditional
service integrated-vtysh-config
hostname academy-b
ip prefix-list OWN seq 10 permit 10.72.20.0/24
ip prefix-list REMOTE seq 10 permit 10.71.10.0/24
router bgp 65020
bgp router-id 10.254.2.2
bgp ebgp-requires-policy
bgp network import-check
no bgp default ipv4-unicast
neighbor 10.254.2.1 remote-as 65000
neighbor 10.254.2.1 update-source 10.254.2.2
neighbor 10.254.2.1 timers 3 9
address-family ipv4 unicast
network 10.72.20.0/24
neighbor 10.254.2.1 activate
neighbor 10.254.2.1 prefix-list REMOTE in
neighbor 10.254.2.1 prefix-list OWN out
neighbor 10.254.2.1 maximum-prefix 1
exit-address-family
B advertises exactly 10.72.20.0/24 and accepts exactly 10.71.10.0/24 from AS65000, with network import-check enabled.