How would you design and configure dual-homed internet access with two ISPs using BGP?
Show the answer
Say this first
I get provider-independent space and a public ASN, then run eBGP to each ISP, ideally from two edge routers joined by iBGP with next-hop-self. I announce only my own prefix, filtered outbound so I never become a transit path. Inbound I take a default plus partial routes, or full tables, with prefix filters and maximum-prefix. I pick the primary exit with local preference, make the backup less attractive for inbound traffic with AS path prepending or, better, the backup ISP's local preference community, and then test failover in both directions.
Go deeper
Choices to talk through
- Active/standby or load sharing. Standby is simpler to reason about. Sharing needs per-prefix tuning.
- One edge router or two. Two routers remove a single point of failure. They run iBGP between loopbacks,
and the inside gets a default from both (OSPF
default-information originate, or HSRP/VRRP on the LAN). - What to receive. Default only (cheap, no real path choice), default plus partial (the ISP's own and its customers' routes, a good middle ground), or full tables (best exits, needs memory for about a million IPv4 routes plus IPv6).
R1 (primary, ISP1)
ip prefix-list OUR-PREFIXES seq 5 permit 203.0.113.0/24
!
ip prefix-list FROM-ISP seq 5 deny 203.0.113.0/24 le 32
ip prefix-list FROM-ISP seq 10 deny 10.0.0.0/8 le 32
ip prefix-list FROM-ISP seq 15 deny 172.16.0.0/12 le 32
ip prefix-list FROM-ISP seq 20 deny 192.168.0.0/16 le 32
ip prefix-list FROM-ISP seq 25 permit 0.0.0.0/0 le 24
!
route-map ISP1-IN permit 10
match ip address prefix-list FROM-ISP
set local-preference 200
!
route-map ISP1-OUT permit 10
match ip address prefix-list OUR-PREFIXES
!
ip route 203.0.113.0 255.255.255.0 Null0
!
router bgp 64500
bgp router-id 10.255.0.1
bgp log-neighbor-changes
network 203.0.113.0 mask 255.255.255.0
neighbor 192.0.2.1 remote-as 64496
neighbor 192.0.2.1 description ISP1
neighbor 192.0.2.1 route-map ISP1-IN in
neighbor 192.0.2.1 route-map ISP1-OUT out
neighbor 192.0.2.1 maximum-prefix 2000 80
neighbor 10.255.0.2 remote-as 64500
neighbor 10.255.0.2 update-source Loopback0
neighbor 10.255.0.2 next-hop-selfR2 (backup, ISP2)
Same structure, with the same OUR-PREFIXES and FROM-ISP lists, plus:
route-map ISP2-IN permit 10
match ip address prefix-list FROM-ISP
!
route-map ISP2-OUT permit 10
match ip address prefix-list OUR-PREFIXES
set as-path prepend 64500 64500
!
router bgp 64500
neighbor 198.51.100.1 remote-as 64497
neighbor 198.51.100.1 route-map ISP2-IN in
neighbor 198.51.100.1 route-map ISP2-OUT out
neighbor 198.51.100.1 maximum-prefix 2000 80permit 0.0.0.0/0 le 24 accepts the default and anything up to /24. The deny lines drop our own block and
RFC 1918 space; a production bogon list is longer.
Testing
Shut the ISP1 session in a change window. Outbound should move to ISP2 within seconds. Inbound depends on the rest of the internet, so watch interface counters and a looking glass for a few minutes. Then restore and confirm traffic returns.
They will ask next
Why maximum-prefix on sessions where you only expect a few hundred routes?
If the ISP leaks a full table at you by mistake, the edge router could run out of memory or start carrying traffic it should not. The limit shuts the session first.
Can you announce to ISP2 only when ISP1 fails?
Yes, with conditional advertisement:
neighbor 198.51.100.1 advertise-map ADVERTISE non-exist-map WATCHannounces our prefix to ISP2 only when the route matched by WATCH (something learned from ISP1) is gone. It gives a clean standby but slower failover, since the internet has to learn the new path from scratch.What is the smallest prefix you can count on being accepted?
A /24 for IPv4 and a /48 for IPv6. Longer prefixes are filtered by most networks.
Traps
- Forgetting the outbound filter and leaking one ISP's routes to the other.
- Using weight for the primary choice when two routers are involved. Only local preference reaches both.