The OSPF TTL security check is a mechanism that protects OSPF against remote attacks. When you enable this feature, OSPF will send packets with a TTL of 255 and rejects any packets with a TTL that are smaller than a configured threshold. By default, once you enable this it will only accept packets with a TTL of 255. Since routing decrements the TTL by one, this means that only OSPF packets from directly connected devices will be accepted.
Let’s look at an example. I will use the following topology:
Above we have two routers running OSPF, behind R2 is an attacker that wants to attack R1. It will do so by sending spoofed unicast OSPF packets destined to 192.168.12.1:
H1 sends a spoofed OSPF, impersonating R2 and destined to R1. When R2 forwards this packet, the TTL will be decreased by 1 and R1 will receive the IP packet. Even if OSPF rejects the packet because the content is garbage, it still has to be processed by the control plane. If H1 sends enough packets, it might succeed in overloading the router’s control plane.
To stop a remote attack like this, we can implement the OSPF TTL security check.
By default, all OSPF packets have a TTL of 1 as you can see in the packet capture below:
When TTL security check is enabled, OSPF will only accept packets with a certain TTL value, 255 by default. When it receives packets with a lower TTL, they will be discarded.
Let’s give this a try. We can enable this globally for all interfaces like this:
R1(config)#router ospf 1 R1(config-router)#ttl all-interfaces
As soon as you enable this on one router, the neighbor adjacency with R2 will drop once the dead timer expires. Why? We can see the reason when we enable a debug:
R1#debug ip ospf adj OSPF adjacency debugging is on
On the console of R1, you will see this message:
R1# OSPF-1 ADJ Gi0/1: Drop packet from 192.168.12.2 with TTL: 1
R1 will now only accept packets with a TTL of 255 and since R2 is sending OSPF packets with a TTL of 1, they are discarded. Let’s enable TTL security on R2 as well:
R2(config)#router ospf 1 R2(config-router)#ttl all-interfaces
The OSPF neighbor adjacency will recover and both R1 and R2 are now sending OSPF packets with a TTL of 255 to each other:
Here’s a packet capture where you can see the new TTL value:
Above you can see that the TTL is now 255. Since this is the highest value possible for the TTL field, it is impossible for H1 to send a spoofed unicast OSPF packet to R1, preventing a remote attack like this.
The TTL security check is not applied to virtual links or sham links by default. If you want to use this, then you can use the area virtual-link ttl-security or area sham-link ttl-security commands.
That’s all there is to it. You can read more about TTL security in the following RFC: The Generalized TTL Security Mechanism (GTSM)
Want to take a look for yourself? Here you will find the configuration of each device.
hostname R1 ! ip cef ! interface GigabitEthernet0/1 ip address 192.168.12.1 255.255.255.0 ! router ospf 1 ttl-security all-interfaces network 192.168.12.0 0.0.0.255 area 0 ! end
hostname R2 ! ip cef ! interface GigabitEthernet0/1 ip address 192.168.12.2 255.255.255.0 ! interface GigabitEthernet0/2 ip address 192.168.2.254 255.255.255.0 ! router ospf 1 ttl-security all-interfaces network 192.168.12.0 0.0.0.255 area 0 ! end