Hub & Spoke VPN tunnels routed via BGP
Below is an example of BGP dynamic routing in the context of a VPN network in a Hub and Spoke star configuration.
Tunnels configuration
For the configuration of a Hub & Spoke IPsec policy, please refer to the HOW TO mentioned below. In our case, the differences from this procedure consist of configuring traffic endpoints through virtual interfaces, instead of remote networks in the IPsec policy (see following paragraph).
Go to http://documentation.stormshield.eu/. Refer to HOW TO: IPsec VPN - Hub and Spoke Configuration, and refer to case no. 1: internal traffic via IPsec tunnels.
Main site
TunnelA
Local network: | Ipsec1 interface (172.16.0.1) |
Peer: |
Site_SpokeA |
Remote network: | Remote_tunnelA (172.16.0.2) |
TunnelB
Local network: | Ipsec2 interface (172.16.0.5) |
Peer: |
Site_SpokeB |
Remote network: | Remote_tunnelB (172.16.0.6) |
Spoke A
Local network: | Ipsec1 interface (172.16.0.2) |
Peer: |
Site_FW_Hub |
Remote network: | Remote_tunnelA (172.16.0.1) |
Spoke B
Local network: | Ipsec1 interface (172.16.0.6) |
Peer: |
Site_FW_Hub |
Remote network: | Remote_tunnelA (172.16.0.5) |
BGP configuration of the main site (Hub)
protocol direct { | ||
} | ||
protocol kernel { | ||
learn; | # Learn all alien routes from the kernel | |
persist; | # Don't remove routes on bird shutdown | |
scan time 20; | # Scan kernel routing table every 20 seconds | |
import all; | # Default is import all | |
export all; | # Default is export none | |
preference 254; | # Protect existing routes | |
} | ||
# This pseudo-protocol watches all interface up/down events. | ||
protocol device { | ||
scan time 10; | # Scan interfaces every 10 seconds | |
} | ||
filter f_import { | ||
if source = RTS_BGP then |
||
accept; |
||
else | ||
reject; |
||
} | ||
filter f_export { | ||
# local shared networks and BGP routes | ||
if( (net = 192.168.0.0/24) || (source = RTS_BGP) ) then |
||
accept; |
||
else |
||
reject; |
||
} | ||
router id <ip_pub_hub>; | ||
template bgp star { | ||
local as 65000; |
||
import filter f_import; |
||
export filter f_export; |
||
hold time 5; |
||
multihop; |
||
rr client; |
||
next hop self; |
||
} | ||
protocol | bgp router_spokeA from star { | |
neighbor 172.16.0.2 as 65000; | ||
source address 172.16.0.1; |
||
} | ||
protocol bgp router_spokeB from star { | ||
neighbor 172.16.0.6 as 65000; |
||
source address 172.16.0.5; |
||
} |
BGP configuration of the Spoke A satellite site
protocol direct { | ||
} | ||
protocol kernel { | ||
learn; |
# Learn all alien routes from the kernel |
|
persist; | # Don't remove routes on bird shutdown | |
scan time 20; | # Scan kernel routing table every 20 seconds | |
import all; | # Default is import all | |
export all; | # Default is export none | |
preference 254; | # Protect existing routes | |
} | ||
protocol device { | ||
scan time 10; |
# Scan interfaces every 10 seconds |
|
} | ||
filter filter_export_net { | ||
if(net = 192.168.1.0/24) then { |
||
accept; |
||
} | ||
else reject; |
||
} |
||
router id <ip_pub_spokeA>; | ||
protocol bgp router_tunnel1 { | ||
local as 65000; |
||
neighbor 172.16.0.1 as 65000; |
||
hold time 5; |
||
multihop; |
||
import all; |
||
export filter filter_export_net; |
||
source address 172.16.0.2; |
||
} |
BGP configuration of the Spoke B satellite site
protocol direct { | ||
} |
||
protocol kernel { | ||
learn; |
# Learn all alien routes from the kernel |
|
persist; |
# Don't remove routes on bird shutdown |
|
scan time 20; |
# Scan kernel routing table every 20 seconds |
|
import all; |
# Default is import all |
|
export all; |
# Default is export none |
|
preference 254; |
# Protect existing routes |
|
} | ||
protocol device { | ||
scan time 10; |
# Scan interfaces every 10 seconds |
|
} |
||
filter |
filter_export_net { |
|
if(net = 192.168.2.0/24) then { |
||
accept; |
||
} | ||
else reject; |
||
} |
||
router id <ip_pub_spokeB>; | ||
protocol bgp router_tunnel2 { | ||
local as 65000; |
||
neighbor 172.16.0.5 as 65000; |
||
hold time 5; |
||
multihop; |
||
import all; |
||
export filter filter_export_net; |
||
source address 172.16.0.6; |
||
} |
Verification of routing tables
Routing table on the main site (Hub):
bird> show route | ||
0.0.0.0/0 | via 10.60.0.254 on em0 [kernel1 10:16] * (254) | |
10.60.3.127/32 | dev lo0 [kernel1 10:16] * (254) | |
192.168.0.0/24 | dev em1 [direct1 10:16] * (240) | |
192.168.1.0/24 | dev em2 [direct1 10:16] * (240) | |
192.168.1.0/24 | via 172.16.0.2 on enc1 [router_tunnelA 10:22]*(100/0)[AS65001i] | |
192.168.2.0/24 | via 172.16.0.6 on enc1 [router_tunnelB 10:21]*(100/0)[AS65002i] | |
192.168.0.254/32 | dev lo0 [kernel1 10:16] * (254) | |
192.168.1.254/32 | dev lo0 [kernel1 10:16] * (254) | |
172.16.0.0/30 | dev lo1 [direct1 10:16] * (240) | |
10.60.0.0/16 | dev em0 [direct1 10:16] * (240) | |
172.16.0.4/30 | dev lo2 [direct1 10:16] * (240) |
Routing table on spokeA:
bird> show route | ||
0.0.0.0/0 | via 10.60.0.254 on em0 [kernel1 13:32] * (254) | |
192.168.0.0/24 | via 172.16.0.1 on enc1 [router_tunnelA 13:32] * (100/0) [i] | |
192.168.2.0/24 |
via 172.16.0.1 on enc1 [router_tunnelA 13:32] * (100/0) [i] |
|
192.168.1.0/24 | dev em1 [direct1 13:32] * (240) | |
172.16.0.0/30 | dev lo1 [direct1 13:32] * (240) | |
10.60.3.128/32 | dev lo0 [kernel1 13:32] * (254) | |
10.60.0.0/16 | dev em0 [direct1 13:32] * (240) |