Loose uRPF – why?

There are quite a few articles in the wild, explaining the Unicast Reverse Path Forwarding (uRPF) feature and its two modes: strict and loose. Although the operational difference between the two modes is the primary focus of such posts, they rarely cover why these two flavours exist in the first place, at least under the Google search for “loose vs strict uRPF”. Today I’d like to close such a gap and highlight the connection between loose uRPF and the yet unknown feature.

Before we start discussing the modes, a quick recap is in order. RPF is a feature from the multicast world that prevents loops in the data plane: it compares the source address of IP packet to the RIB; if the ingress interface matches the route towards the source address, packet is forwarded further, otherwise it’s a loop and the packet is discarded. Unicast RPF stems from the same idea – verify that the packet comes from a valid direction. Strict uRPF operates in the same way as its counterpart from the multicast feature set; loose uRPF, however, does not check the interface – just the availability of a valid route. There is a single notable exception to such a description though: if next-hop interface for the source address is Null0, the packet is also discarded. Cisco provides the use case for the feature as well:

To provide ISPs with a DDoS resistance tool on the ISP-to-ISP edge of a network, Unicast RPF was modified from its original strict mode implementation to check the source addresses of each ingress packet without regard for the specific interface on which it was received. This modification is known as “loose mode.”

Security Configuration Guide: Unicast Reverse Path Forwarding, Cisco IOS XE 17 (Cisco ASR 920 Routers)

Does the ISP-to-ISP DDoS protection sound familiar? It is indeed part of the Remotely Triggered Blackhole (RTBH). The destination-based RTBH uses BGP communities to notify ISP which destination is under attack, so that the ISP can temporarily drop offending traffic. Obviously, the legitimate traffic is discarded too in such a case. Wouldn’t it be better if the traffic could be dropped based on the offending source IP? This is exactly the use case for the source-based RTBH: if loose uRPF is added to the destination-based RTBH setup, attacker’s IP address can be marked by BGP community and further forwarded to the void. Here is a nice article on the RTBH that explains the solution, using IOS XR platform.

Disclaimer: there wil be no extra revelations further down the text, so if you already grasped the idea, feel free to skip the rest of the post.

Let’s build a simple topology to verify the loose uRPF within the RTBH feature:

ISP network consists of 2 PE routers that are using the same BGP AS. CE1 and CE2 are customer routers that peer with ISP using eBGP. Important note: IOS XE requires that a directly connected eBGP neighbour and its prefixes are reachable via the same physical egress interface, otherwise, the received routes are considered inaccessible. The workaround is simple though – disable-connected-check on PE, that performs next-hop replacement.  Here is the basic routing and addressing config:

CE1#show run | section interface|router|ip route
interface Loopback0
 ip address 3.3.3.3 255.255.255.255
interface FastEthernet0/0
 ip address 192.168.13.3 255.255.255.0
router bgp 3
 bgp router-id 3.3.3.3
 no bgp default ipv4-unicast
  neighbor 192.168.13.1 remote-as 12
 address-family ipv4
  network 3.3.3.3 mask 255.255.255.255
  neighbor 192.168.13.1 activate
  neighbor 192.168.13.1 send-community both
CE2#show run | section interface|router
interface Loopback0
 ip address 4.4.4.4 255.255.255.255
interface FastEthernet0/0
 ip address 192.168.24.4 255.255.255.0
router bgp 4
 bgp router-id 4.4.4.4
 no bgp default ipv4-unicast
 neighbor 192.168.24.2 remote-as 12
 address-family ipv4
  network 4.4.4.4 mask 255.255.255.255
  neighbor 192.168.24.2 activate
  neighbor 192.168.24.2 send-community both
PE1#show run | section interface|router    
interface Loopback0
 ip address 1.1.1.1 255.255.255.255
 ip ospf 1 area 0
interface FastEthernet0/0
 ip address 192.168.13.1 255.255.255.0
interface FastEthernet1/0
 ip address 192.168.12.1 255.255.255.0
 ip ospf 1 area 0
router ospf 1
 router-id 1.1.1.1
router bgp 12
 bgp router-id 1.1.1.1
 no bgp default ipv4-unicast
 neighbor 2.2.2.2 remote-as 12
 neighbor 2.2.2.2 update-source Loopback0
 neighbor 192.168.13.3 remote-as 3
 neighbor 192.168.13.3 disable-connected-check
 !
 address-family ipv4
  redistribute connected
  neighbor 2.2.2.2 activate
  neighbor 2.2.2.2 send-community both
  neighbor 192.168.13.3 activate
  neighbor 192.168.13.3 send-community both
PE2#show run | section interface|router
interface Loopback0
 ip address 2.2.2.2 255.255.255.255
 ip ospf 1 area 0
interface FastEthernet0/0
 ip address 192.168.24.2 255.255.255.0
interface FastEthernet0/1
 ip address 192.168.25.2 255.255.255.0
interface FastEthernet1/0
 ip address 192.168.12.2 255.255.255.0
 ip ospf 1 area 0
router ospf 1
 router-id 2.2.2.2
router bgp 12
 bgp router-id 2.2.2.2
 no bgp default ipv4-unicast
 neighbor 1.1.1.1 remote-as 12
 neighbor 1.1.1.1 update-source Loopback0
 neighbor 192.168.24.4 remote-as 4
 neighbor 192.168.25.5 remote-as 5
 !
 address-family ipv4
  redistribute connected
  neighbor 1.1.1.1 activate
  neighbor 1.1.1.1 send-community
  neighbor 192.168.24.4 activate
  neighbor 192.168.24.4 send-community both
  neighbor 192.168.25.5 activate
  neighbor 192.168.25.5 send-community both

Attacker#show run | section interface|router
interface Loopback0
 ip address 5.5.5.5 255.255.255.255
interface FastEthernet0/1
 ip address 192.168.25.5 255.255.255.0
router bgp 5
 bgp router-id 5.5.5.5
 no bgp default ipv4-unicast
 neighbor 192.168.25.2 remote-as 12
 address-family ipv4
  network 5.5.5.5 mask 255.255.255.255
  neighbor 192.168.25.2 activate
  neighbor 192.168.25.2 send-community both

First, let’s implement destination-based RTBH. Community of 12:666 would be the marker to discard the traffic through Null0.

PE1#show run | s ip route|ip community|ip bgp|route-map|router bgp
router bgp 12
 address-family ipv4
  neighbor 192.168.13.3 route-map RTBH in
ip bgp-community new-format
ip community-list standard RTBH permit 12:666
ip route 10.0.0.0 255.255.255.255 Null0
route-map RTBH permit 10
 match community RTBH
 set local-preference 200
 set ip next-hop 10.0.0.0
route-map RTBH permit 20
PE2#show run | s ip route|ip community|ip bgp|route-map|router bgp
router bgp 12
 address-family ipv4
  neighbor 192.168.24.4 route-map RTBH in
  neighbor 192.168.25.5 route-map RTBH in
ip bgp-community new-format
ip community-list standard RTBH permit 12:666
ip route 10.0.0.0 255.255.255.255 Null0
route-map RTBH permit 10
 match community RTBH
 set local-preference 200
 set ip next-hop 10.0.0.0
route-map RTBH permit 20

Attacker has initiated the DDoS attack on CE1 3.3.3.3/32:

Attacker#ping 3.3.3.3 source loopback0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 3.3.3.3, timeout is 2 seconds:
Packet sent with a source address of 5.5.5.5 
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 40/48/52 ms

In order to block the offending traffic, CE1 has to announce 3.3.3.3/32 with community of 12:666.

CE1#show run | section route-map|router bgp
router bgp 3
 address-family ipv4
  network 3.3.3.3 mask 255.255.255.255 route-map RTBH
route-map RTBH permit 10
 set community 12:666

The attack has ceased on PE2 due to the data plane filter:

Attacker#ping 3.3.3.3 source loopback0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 3.3.3.3, timeout is 2 seconds:
Packet sent with a source address of 5.5.5.5 
UUUUU
Success rate is 0 percent (0/5)

The important feature of RTBH – traffic is discarded as soon as possible on provider edge, thus limiting the impact on the ISP network.

PE2#show ip bgp 3.3.3.3/32
BGP routing table entry for 3.3.3.3/32, version 27
Paths: (1 available, best #1, table default)
  Advertised to update-groups:
     3         
  Refresh Epoch 2
  3
    10.0.0.0 from 1.1.1.1 (1.1.1.1)
      Origin IGP, metric 0, localpref 200, valid, internal, best
      Community: 12:666
PE2#
PE2#show ip cef 3.3.3.3/32 det
3.3.3.3/32, epoch 0, flags rib only nolabel, rib defined all labels
  recursive via 10.0.0.0
    attached to Null0

There is an unfortunate side effect though – CE2 has lost connectivity as well:

CE2#ping 3.3.3.3 source loopback 0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 3.3.3.3, timeout is 2 seconds:
Packet sent with a source address of 4.4.4.4 
UUUUU
Success rate is 0 percent (0/5)

Destination-based RTBH might be a good tool to limit the impact of DDoS attack to gain additional information about attacker. Let’s assume that CE1 already knows the source IP address – 5.5.5.5/32. Time to introduce source-based RTBH with the addition of loose uRPF!

PE1#show run int f0/0
interface FastEthernet0/0
 ip verify unicast source reachable-via any
PE2#show run int f0/0  
interface FastEthernet0/0
 ip verify unicast source reachable-via any
PE2#show run int f0/1
interface FastEthernet0/1
 ip verify unicast source reachable-via any

ISP is set up, so let’s swap the announcements on CE1 to trigger source-based RTBH:

CE1#show run | s ip route|router bgp
router bgp 3
 address-family ipv4
  network 3.3.3.3 mask 255.255.255.255
  network 5.5.5.5 mask 255.255.255.255 route-map RTBH
ip route 5.5.5.5 255.255.255.255 Null0

ISP is filtering the traffic from attacker on the entry points to its network:

PE2#show ip bgp 5.5.5.5/32
BGP routing table entry for 5.5.5.5/32, version 29
Paths: (2 available, best #1, table default)
  Advertised to update-groups:
     3         
  Refresh Epoch 3
  3
    10.0.0.0 from 1.1.1.1 (1.1.1.1)
      Origin IGP, metric 0, localpref 200, valid, internal, best
      Community: 12:666
  Refresh Epoch 4
  5
    192.168.25.5 from 192.168.25.5 (5.5.5.5)
      Origin IGP, metric 0, localpref 100, valid, external
PE2#
PE2#show ip cef 5.5.5.5/32 det
5.5.5.5/32, epoch 0, flags rib only nolabel, rib defined all labels
  recursive via 10.0.0.0
    attached to Null0

This time, however, only the offending party is neutralized, valid connections are still operational:

CE2#ping 3.3.3.3 so lo 0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 3.3.3.3, timeout is 2 seconds:
Packet sent with a source address of 4.4.4.4 
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 44/53/72 ms
Attacker#ping 3.3.3.3 source loopback0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 3.3.3.3, timeout is 2 seconds:
Packet sent with a source address of 5.5.5.5 
.....
Success rate is 0 percent (0/5)

In production you would not probably allow customers to announce the prefixes in such a direct way, one would rather restrict the allowed prefixes or even use a dedicated router within ISP to generate the prefixes for RTBH. Nevertheless, the underlying idea of loose uRPF combined with static route to Null0 stays the same, so I hope this post bridges the gap between the uRPF mode and its use case.

Kudos for review: Anastasiia Kuraleva

Follow on Telegram, LinkedIn, Twitter

One thought on “Loose uRPF – why?

Leave a comment