This lab is focused on demonstrating how to implement remotely triggered black hole filtering between adjacent ASes.
The diagram below is a reminder of the lab topology:

In the previous lab we set up the RTBH infrastructure for own autonomous system. We are now going to extend this to add RTBH filtering capability between adjacent ASes. This is a common service offered to their BGP customers by many transit providers, and is often set up between peers as well to deal with incidents occurring between their respective networks.
To support inter-AS RTBH we need to tag our problem destinations with the industry standard community set aside for RTBH use. This community is defined in RFC7999 and recorded by IANA, and is 65535:666.
The first step is to tidy up the Trigger Router from the previous lab: remove any tag 666 static routes you created to test your RTBH filtering configuration. Once they are removed, verify using the router trace command that you can reach those destinations again.
The previous lab set the community on the Trigger Router for the destination we wanted to be blocked to be no-export. We need to remove this setting, as we want to announce this “to be blocked” destination to our neighbouring AS. On the Trigger Router:
route-map black-hole-triggerv4 permit 10
no set community no-export
and
route-map black-hole-triggerv6 permit 10
no set community no-export
We will now make sure that the standard RTBH community is still present in the route-maps we created earlier. Some versions of Cisco IOS have a habit to deleting all communities configured in a route-map statement, even though only a single one was specified.
The following configuration should be already on the Trigger Router:
route-map black-hole-triggerv4 permit 10
set community 65535:666
and
route-map black-hole-triggerv6 permit 10
set community 65535:666
Because our neighbours will be setting up inter-AS RTBH as well, we need to add support to our eBGP sessions for them sending any prefixes with the RTBH community set. That way, we can drop traffic to prefixes which they tell us are under attack in their network.
Previous labs set up inbound BGP filters on our Border and Peering routers. It is unlikely that our upstream provider is going to send us destinations with the RTBH community set, so we will just focus on configuring the Peering router only.
We need to add a line to allow a prefix (host address only) tagged with the RTBH community to have its next-hop set to the discard prefix. So we need to match a host prefix from our BGP neighbour’s address space, and match the RTBH community.
We need to modify the incoming route-map to look for a prefix with the incoming RTBH community set on it, and let that prefix into the BGP local table without applying any policy.
First, we define a prefix-list for IPv4 and for IPv6 which only allows a host address for the range of addresses used in this workshop. Here is an example:
ip prefix-list RTBHv4-filter permit 100.68.0.0/16 ge 32
!
ipv6 prefix-list RTBHv6-filter permit 2001:DB8::/32 ge 128
These will only match single host addresses. We want the filter to be quite specific1 - the last thing we want is for our peer or customer to send us routes which are found outside their or your AS and they cut you off from those destinations.
Then, we create a new line in the Route-Server route-map - we make it line 1 in the configuration below:
route-map IXP-RSv4-in permit 1
description Look for RTBH routes from IX peers
match ip address prefix-list RTBHv4-filter
match community RTBH
!
route-map IXP-RSv4-in permit 5
description Filter and tag prefixes from IXP RS
match ip address prefix-list IXP-RSv4
set local-preference 150
set community X0:1300
!
Note that line 5 already exists - please check that what you have matches the example shown.
We need to do the same for the private peer route-map, again line 1 below:
route-map private-peerv4-in permit 1
description Look for RTBH routes from private peers
match ip address prefix-list RTBHv4-filter
match community RTBH
!
route-map private-peerv4-in permit 5
description Filter and tag prefixes from Private Peer
match ip address prefix-list ASY0-ROUTESv4
set local-preference 200
set community X0:1100
!
Do the same for IPv6! Something like this, for the Route-Server route-map:
route-map IXP-RSv6-in permit 1
description Look for RTBH routes from IX peers
match ipv6 address prefix-list RTBHv6-filter
match community RTBH
!
route-map IXP-RSv6-in permit 5
description Filter and tag prefixes from IXP RS
match ipv6 address prefix-list IXP-RSv6
set local-preference 150
set community X0:1300
!
and the private-peer route-map:
route-map private-peerv6-in permit 1
description Look for RTBH routes from private peers
match ipv6 address prefix-list RTBHv6-filter
match community RTBH
!
route-map private-peerv6-in permit 5
description Filter and tag prefixes from Private Peer
match ipv6 address prefix-list ASY0-ROUTESv6
set local-preference 200
set community X0:1100
!
This updates the inbound policy on the Peering Router with its EBGP neighbours.
We normally don’t want to announce our peer RTBH routes to other operators. For example, if a peer of ours has an address under attack, they would announce it to us with the RTBH community set. The prefix arrives on our peering router, but because our RTBH policy is only implemented when we distribute the prefix through our IBGP, using the configuration as it is now, it will be announced to our other EBGP peers without any checks (because its community, 65535:666, matches our outbound filter).
To protect against this, we are going to add the no-export community to the extra route-map entries we created earlier on the Peering Router, like this:
route-map IXP-RSv4-in permit 1
set community no-export additive
!
route-map private-peerv4-in permit 1
set community no-export additive
!
route-map IXP-RSv6-in permit 1
set community no-export additive
!
route-map private-peerv6-in permit 1
set community no-export additive
!
We include the additive keyword so that no-export is added to whatever existing communities the peer is sending us. We don’t want to over write the RTBH community, otherwise we won’t implement RTBH as they are wishing us to do.
We also need to fix the iBGP configuration on the peering router to catch any prefix with the RTBH community and set its next-hop to the discard address. To do this we need to create a route-map to be used for iBGP policy. As in the previous lab, we have to fix the next-hop as there is no next-hop-self keyword supported in Cisco IOS route-maps for both IPv4 and IPv6.
The new IPv4 route-map is shown here:
route-map ibgpv4 permit 10
description Catch RTBH routes
match community RTBH
set ip next-hop 192.0.2.1
set local-preference 1000
set origin IGP
set community no-export
!
route-map ibgpv4 permit 20
description next-hop-self for normal routes
set ip next-hop 100.68.X.3
!
and the IPv6 route-map is shown here:
route-map ibgpv6 permit 10
description Catch RTBH routes
match community RTBH
set ipv6 next-hop 100::1
set local-preference 1000
set origin IGP
set community no-export
!
route-map ibgpv6 permit 20
description next-hop-self for normal routes
set ipv6 next-hop 2001:DB8:X::3
!
Explaining each line:
match community looks for a route with the RTBH community set on it
Then set the next-hop to the discard address, put a very high local preference on the destination (higher than any other policy preference in the network)
Make origin IGP (no real reason - redistribute commands create origin UNKNOWN)
Mark the received route as no-export so it won’t accidentally head outside the autonomous system.
Fix the next-hop of remaining routes so they originate from the router Loopback (like next-hop-self does)
Finally, once the two route-maps are created, we apply them to the iBGP peer-group. Remember to delete the next-hop-self line in the peer-group as well:
router bgp X0
address-family ipv4
no neighbor ibgpv4-rr next-hop-self
neighbor ibgpv4-rr route-map ibgpv4 out
!
address-family ipv6
no neighbor ibgpv6-rr next-hop-self
neighbor ibgpv6-rr route-map ibgpv6 out
!
After this is done, refresh the BGP sessions, and the Peering router should now be ready to handle prefixes from peers arriving with the RTBH community set on it.
We need to modify our filters on our eBGP sessions to allow the standard RTBH community out of our network. On the Border Router, previous labs have created the transit provider route-map called Transit-out - we need to add the RTBH community to the list of permitted communities. Here is what the route-map now looks like:
route-map Transit-out permit 5
match community aggregate customer-pi RTBH
!
We need to do the same on the Peering Router, for all our private peers:
route-map private-peer-out permit 5
match community aggregate customer-pi RTBH
!
and for our IXP Route Server peers:
route-map IXP-RS-out permit 5
match community aggregate customer-pi RTBH
!
Then, we need to add in the send-community configuration on our EBGP sessions so that RTBH community will actually be sent along with the RTBH prefixes. If we miss the send-community configuration out, our neighbours will simply see the host routes from us, with no community attached.
router bgp X0
address-family ipv4
neighbor <p2p> send-community
address-family ipv6
neighbor <p2p> send-community
!
Once the RTBH community has been added to the route-maps on the Border and Peering routers, and send-community has been configured on the EBGP sessions, refresh the BGP sessions so that the community filter is applied.
On a side note, see how easy it is to modify BGP peering policy because we have already implemented BGP communities across the network. To allow the RTBH prefix out, we simply added that community to our configuration.
We are now going to test the trigger configuration - and the target will be the loopback address used on the Customer Router which we will “pretend” is under attack from the outside.
What we are going to do is use the Trigger Router to announce this loopback address to the other ASes connected to the group.
The configuration is simple, a single static route with tag 666 on it, like this, on the Trigger Router:
ip route 100.68.X.64 255.255.255.255 null0 tag 666
Once applied, check the BGP table on all the routers in the group - they should show the route to 100.68.X.64 as having next-hop 192.0.2.1.
Do the same for the IPv6 loopback on the Customer router:
ipv6 route 2001:DB8:X:4000::/128 null0 tag 666
Again, check the BGP table to make sure that the next-hop for 2001:DB8:X:4000::/32 points to 100::1.
Check with the other groups. Once they have completed their configurations, trying pinging or tracing to their customer routers and their loopback interfaces. What happens?
What do you see in the BGP table now? Do you see the RTBH routes appearing from the upstream provider, across the IX, and through the private peering?
Here is the IPv4 BGP table from the Border Router in Group 1, from an earlier version of this lab:
B1#show ip bgp
BGP table version is 71, local router ID is 100.68.1.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
x best-external, a additional-path, c RIB-compressed,
t secondary path,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 0.0.0.0 100.121.1.0 0 121 i
*>i 100.68.1.0/24 100.68.1.2 0 100 0 i
*>i 100.68.1.28/30 100.68.1.2 0 100 0 i
*>i 100.68.1.64/32 192.0.2.1 0 1000 0 i
*>i 100.68.1.64/26 100.68.1.4 0 100 0 i
* 100.68.2.0/24 100.121.1.0 50 0 121 20 i
*>i 100.68.1.3 0 200 0 20 i
* 100.68.2.64/32 100.121.1.0 50 0 121 20 i
*>i 192.0.2.1 0 1000 0 20 i
* 100.68.3.0/24 100.121.1.0 50 0 121 30 i
*>i 100.68.1.3 0 150 0 30 i
* 100.68.3.64/32 100.121.1.0 50 0 121 30 i
*>i 192.0.2.1 0 1000 0 30 i
* 100.68.4.0/24 100.121.1.0 50 0 121 40 i
*>i 100.68.1.3 0 150 0 40 i
* 100.68.4.64/32 100.121.1.0 50 0 121 40 i
*>i 192.0.2.1 0 1000 0 40 i
*> 100.68.5.0/24 100.121.1.0 50 0 121 122 50 i
*> 100.68.5.64/32 100.121.1.0 50 0 121 122 50 i
*> 100.68.6.0/24 100.121.1.0 50 0 121 122 60 i
*> 100.68.6.64/32 100.121.1.0 50 0 121 122 60 i
*> 100.68.7.0/24 100.121.1.0 50 0 121 122 70 i
*> 100.68.7.64/32 100.121.1.0 50 0 121 122 70 i
*> 100.68.8.0/24 100.121.1.0 50 0 121 122 80 i
*> 100.68.8.64/32 100.121.1.0 50 0 121 122 80 i
*>i 100.68.101.0/24 100.68.1.4 0 100 0 64512 i
* 100.68.102.0/24 100.121.1.0 50 0 121 20 i
*>i 100.68.1.3 0 200 0 20 i
* 100.68.103.0/24 100.121.1.0 50 0 121 30 i
*>i 100.68.1.3 0 150 0 30 i
* 100.68.104.0/24 100.121.1.0 50 0 121 40 i
*>i 100.68.1.3 0 150 0 40 i
*> 100.68.105.0/24 100.121.1.0 50 0 121 122 50 i
*> 100.68.106.0/24 100.121.1.0 50 0 121 122 60 i
*> 100.68.107.0/24 100.121.1.0 50 0 121 122 70 i
*> 100.68.108.0/24 100.121.1.0 50 0 121 122 80 i
*> 100.121.0.0/16 100.121.1.0 0 50 0 121 i
*> 100.122.0.0/16 100.121.1.0 50 0 121 122 i
* 100.127.0.0/24 100.121.1.0 50 0 121 131 i
*>i 100.68.1.3 0 150 0 131 i
*> 100.127.2.0/24 100.121.1.0 50 0 121 122 132 i
Are you able to explain the cause of all the entries you see now?
Do you see the IPv4 /32 being announced by other groups? Here is the one being sent by Group 4:
B1#show ip bgp 100.68.4.64
BGP routing table entry for 100.68.4.64/32, version 38
BGP Bestpath: deterministic-med
Paths: (2 available, best #2, table default, not advertised to EBGP peer)
Not advertised to any peer
Refresh Epoch 2
121 40
100.121.1.0 from 100.121.1.0 (100.64.0.2)
Origin IGP, localpref 50, valid, external
rx pathid: 0, tx pathid: 0
Refresh Epoch 1
40
192.0.2.1 from 100.68.1.2 (100.68.1.2)
Origin IGP, metric 0, localpref 1000, valid, internal, best
Community: no-export
Originator: 100.68.1.3, Cluster list: 100.68.1.2
rx pathid: 0, tx pathid: 0x0
The best path is of course pointing to the Null interface via the 192.0.2.1 next-hop value. But note you also see the path via the upstream provider - this is because the upstream is doing no filtering whatsoever in this lab (not the normal occurrence in today’s global Internet). You’d not normally see your upstream provider passing on RTBH prefixes from other customers!
Finally: Demonstrate your inter-AS RTBH set up to the workshop instructors.
Once the lab instructor gives you the go-ahead, please remove the two static routes you added to test the Trigger. We will need to use our customer router again for the following labs, so we need to ensure that the Loopback interface address is routable.
Simply go to the Trigger Router and do:
no ip route 100.68.X.64 255.255.255.255 null0 tag 666
no ipv6 route 2001:DB8:X:4000::/128 null0 tag 666
and the two host routes will become usable again.
In real life the inbound filter will match exactly the address space learned from each customer. Inter-AS RTBH is usually used in a customer to transit provider relationship - the transit provider only allows host addresses from the customer’s address space to be sent with the RTBH community set.↩︎