Saturday, February 22, 2020

Unicast Reverse Path Forwarding (uRPF)

Normally when your router receives unicast IP packets it only cares about one thing:
  • What is the destination IP address of this IP packet so I can forward it?
If the IP packet has to be routed it willl check the routing table for the destination IP address, select the correct interface and it will be forwarded. Your router really doesn’t care about source IP addresses as it’s not important for forwarding decisions.
Because the router doesn’t check the source IP address it is possible for attackers to spoof the source IP address and send packets that normally might have been dropped by the firewall or an access-list.
When you use multicast, checking the source of multicast IP packets is a very important topic. Right now I’m only talking about unicast IP packets.
uRPF is a security feature that prevents these spoofing attacks. Whenever your router receives an IP packet it will check if it has a matching entry in the routing table for the source IP address. If it doesn’t match, the packet will be discarded. uRPF has two modes:
  • Strict mode
  • Loose mode
Let’s take a look at the difference between both modes and how to configure them.

Strict Mode

Strict mode means that that router will perform two checks for all incoming packets on a certain interface:
  • Do I have a matching entry for the source in the routing table?
  • Do I use the same interface to reach this source as where I received this packet on?
When the incoming IP packets passes both checks, it will be permitted. Otherwise it will be dropped. This is perfectly fine for  IGP routing protocols since they use the shortest path to the source of IP packets. The interface that you use to reach the source will be the same as the interface where you will receive the packets on. Here’s an illustration to demonstrate this:
URPF Strict
R1 has installed network 2.2.2.0 /24 in its routing table and in order to reach this network it will use the FastEthernet 0/0 interface. Suddenly this router receives an IP packet with source IP address 2.2.2.2 on both of its interfaces. The one it receives on the FastEthernet 0/0 will be accepted but the packet on the FastEthernet 0/1 interface will be dropped because this is not the interface we use to reach this source.
Let’s configure the example above to see how it works. I’ll use the following topology:
urpf demo topology
We will configure R1 with a static route so it can reach the loopback0 interface of R2:
R1(config)#ip route 2.2.2.2 255.255.255.255 192.168.12.2
This is what the routing table looks like now:
R1#show ip route   

C    192.168.12.0/24 is directly connected, FastEthernet0/0
C    192.168.13.0/24 is directly connected, FastEthernet0/1
     2.0.0.0/32 is subnetted, 1 subnets
S       2.2.2.2 [1/0] via 192.168.12.2
Now we’ll configure uRPF strict mode on both interfaces:
R1(config)#interface fastEthernet 0/0
R1(config-if)#ip verify unicast source reachable-via rx

R1(config)#interface fastEthernet 0/1
R1(config-if)#ip verify unicast source reachable-via rx
You can verify that it has been enabled on the interface like this:
R1#show ip interface fastEthernet 0/0 | include verify
  IP verify source reachable-via RX

R1#show ip interface fastEthernet 0/1 | include verify
  IP verify source reachable-via RX
To test uRPF we’ll send some pings from R2 first, these should be accepted:
R2#ping 192.168.12.1 source loopback 0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.12.1, timeout is 2 seconds:
Packet sent with a source address of 2.2.2.2 
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/4/8 ms
As expected this ping works. Now I’ll create a new loopback interface on R3 with the 2.2.2.2 IP address on it so that we can spoof this IP address:
R3(config)#interface loopback 0
R3(config-if)#ip address 2.2.2.2 255.255.255.255
Now we’ll send some pings from this loopback:
R3#ping 192.168.13.1 source loopback 0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.13.1, timeout is 2 seconds:
Packet sent with a source address of 2.2.2.2 
.....
Success rate is 0 percent (0/5)
The packets will make it to R1 but they will be dropped there, we can verify this as following:
R1#show ip interface fastEthernet 0/0 | include drops
  0 verification drops
  0 suppressed verification drops
R1#show ip interface fastEthernet 0/1 | include drops
  5 verification drops
  0 suppressed verification drops
Above you see that the spoofed packets on the FastEthernet 0/1 interface have been dropped.
hostname R1
!
ip cef
!
interface FastEthernet0/0
 ip address 192.168.12.1 255.255.255.0
 ip verify unicast source reachable-via rx
!
interface FastEthernet0/1
 ip address 192.168.13.1 255.255.255.0
 ip verify unicast source reachable-via rx
!
ip route 2.2.2.2 255.255.255.255 192.168.12.2
!
end
hostname R2
!
ip cef
!
interface Loopback0
 ip address 2.2.2.2 255.255.255.255
!
interface FastEthernet0/0
 ip address 192.168.12.2 255.255.255.0
!
end
hostname R3
!
ip cef
!
interface Loopback0
 ip address 2.2.2.2 255.255.255.255
!
interface FastEthernet0/0
 ip address 192.168.13.3 255.255.255.0
!
end
Now let’s take a look at loose mode…

Loose Mode

Loose mode means that the router will perform only a single check when it receives an IP packet on an interface:
  • Do I have a matching entry for the source in the routing table?
When it passed this check, the packet is permitted. It doesn’t matter if we use this interface to reach the source or not. Loose mode is useful when you are connected to more than one ISP and you use asymmetric routing.The only exception is the null0 interface, if you have any sources with the null0 interface as the outgoing interface then the packets will be dropped. Take a look at this illustration:
URPF Loose

R1 has been configured for uRPF loose mode and receives an IP packet with source IP address 2.2.2.2 on both interfaces. Since it has an entry for this source in its routing table it will accept both packets. It doesn’t care where it came from, as long as there is an entry in the routing table.
Let’s configure uRPF loose mode on R1 using the same topology:
urpf demo topology
I’ll install the same static route on R1 to network 2.2.2.2/32:
R1(config)#ip route 2.2.2.2 255.255.255.255 192.168.12.2
This time we’ll enable uRPF loose mode on the interfaces:
R1(config)#interface fastEthernet 0/0                 
R1(config-if)#ip verify unicast source reachable-via any 

R1(config)#interface fastEthernet 0/1                 
R1(config-if)#ip verify unicast source reachable-via any
Let’s verify that it has been enabled on the interfaces:
R1#show ip interface fastEthernet 0/0 | include verify
  IP verify source reachable-via ANY
R1#show ip interface fastEthernet 0/1 | include verify
  IP verify source reachable-via ANY
As you can see it’s enabled. To verify that it actually works I’ll enable a debug on R1:
R1#debug ip packet 
IP packet debugging is on
Now we will send some pings from R2 and R3 using 2.2.2.2 as the source:
R2#ping 192.168.12.1 source loopback 0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.12.1, timeout is 2 seconds:
Packet sent with a source address of 2.2.2.2 
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/4/8 ms
R3#ping 192.168.13.1 source loopback 0 repeat 1

Type escape sequence to abort.
Sending 1, 100-byte ICMP Echos to 192.168.13.1, timeout is 2 seconds:
Packet sent with a source address of 2.2.2.2 
.
Success rate is 0 percent (0/1)
The pings from R2 will make it as this is the valid entry. The pings from R3 won’t work because we don’t have a valid route but the packets will be accepted by R1…take a look below:
R1#
P: tableid=0, s=2.2.2.2 (FastEthernet0/0), d=192.168.12.1 (FastEthernet0/0), routed via RIB
IP: s=2.2.2.2 (FastEthernet0/0), d=192.168.12.1 (FastEthernet0/0), len 100, rcvd 3

IP: tableid=0, s=2.2.2.2 (FastEthernet0/1), d=192.168.13.1 (FastEthernet0/1), routed via RIB
IP: s=2.2.2.2 (FastEthernet0/1), d=192.168.13.1 (FastEthernet0/1), len 100, rcvd 3
The router is accepting both packets, even the spoofed one by R3. You can also check the interface to see if uRPF has accepted or dropped the packets:
R1#show ip interface fastEthernet 0/0 | include drops
  0 verification drops
  0 suppressed verification drops

R1#show ip interface fastEthernet 0/1 | include drops
  0 verification drops
  7 suppressed verification drops
There are no drops on the FastEthernet 0/0 interface, the packets on the FastEthernet 0/1 interface have been suppressed. This means that the incoming interface is incorrect but that we do have a valid entry in the routing table. Let me show you what happens when R1 receives an IP packet with an unknown source:
R3(config)#interface loopback 1
R3(config-if)#ip address 3.3.3.3 255.255.255.255

R3#ping 192.168.13.1 source loopback 1

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

R1#show ip interface fastEthernet 0/1 | include drops
  5 verification drops
  7 suppressed verification drops
I’ll create a new loopback interface with IP address 3.3.3.3. If I use this as the source then the packet will be dropped by R1 because it doesn’t have an entry in its routing table that matches 3.3.3.3.
hostname R1
!
ip cef
!
interface FastEthernet0/0
 ip address 192.168.12.1 255.255.255.0
 ip verify unicast source reachable-via any
!
interface FastEthernet0/1
 ip address 192.168.13.1 255.255.255.0
 ip verify unicast source reachable-via any
!
ip route 2.2.2.2 255.255.255.255 192.168.12.2
!
end
hostname R2
!
ip cef
!
interface Loopback0
 ip address 2.2.2.2 255.255.255.255
!
interface FastEthernet0/0
 ip address 192.168.12.2 255.255.255.0
!
end
hostname R3
!
ip cef
!
interface Loopback1
 ip address 2.2.2.2 255.255.255.255
!
interface FastEthernet0/0
 ip address 192.168.13.3 255.255.255.0
!
end
That’s how loose mode works. There are a couple of extra features that uRPF has to offer.

Additional Features

  • Logging and Exemptions: uRPF allows the usage of an access-list so you can decide what sources it should check and if required, log the packets that are dropped using access-list logging.
  • Self-pinging: Allow the router to ping itself using uRPF strict mode on the interface.
  • Default route: You can configure uRPF to check source IP addresses against a default route. You can use this when you want to accept all packets from your internet connection while protecting yourself against spoofed packets with source IP address from your internal network.
I hope this lesson has been helpful to you to understand uRPF. If you have any questions feel free to leave a comment!

No comments:

Post a Comment