RTBH between ASes Lab

Routing Infrastructure and Security Operations Workshop

 

Introduction

This lab is focused on demonstrating how to implement remotely triggered black hole filtering between adjacent ASes.

 

Lab Topology

The diagram below is a reminder of the lab topology:

 

Introduction

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.

 

Configuration Steps

Tidy up

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.

 

Removing no-export BGP Community

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

 

Using the standard RTBH BGP Community

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

 

Inbound eBGP policy and RTBH community - Peering Router

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.

 

Avoiding exporting peer RTBH routes to other peers

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.

 

Updating iBGP configuration on Peering Router

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:

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.

 

Outbound eBGP policy and RTBH community

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.

 

Testing the Trigger

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.

 

Wrapping Up

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.


  1. 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.↩︎