Page MenuHomeFreeBSD

ipsec: Handle ICMP NEEDFRAG message.
ClosedPublic

Authored by wma on Jul 2 2021, 4:38 AM.

Details

Summary

It will be needed for upcoming PMTU implementation in ipsec.
For now simply create/update an entry in tcp hostcache when needed.
The code is based on https://people.freebsd.org/~ae/ipsec_transport_mode_ctlinput.diff

Diff Detail

Lint
Lint Skipped
Unit
Unit Tests Skipped

Event Timeline

wma requested review of this revision.Jul 2 2021, 4:38 AM
This revision is now accepted and ready to land.Jul 15 2021, 10:27 AM
This revision now requires review to proceed.Jul 19 2021, 11:16 AM

Any objections for committing this after adding a hook to udp_userreq?

In D30992#706244, @wma wrote:

Any objections for committing this after adding a hook to udp_userreq?

Is there any protection against blind attackers?

Any reason this is done for IPv4 only?

Basic protection is guaranteed by IPSEC code. PMTUD NEEDFRAG msg contains a header of packet which caused the router to send such ICMP response. IPSEC handles PMTU change only if that header matches an existing tunnel.

It's for IPv4 simply because I don't use IPv6 for IPSEC dev. Let me know if you think adding v6 support is desired. I'd rather like to do it in seperate review/commit as it will take me some time to run proper testing.

In D30992#706299, @wma wrote:

Basic protection is guaranteed by IPSEC code. PMTUD NEEDFRAG msg contains a header of packet which caused the router to send such ICMP response. IPSEC handles PMTU change only if that header matches an existing tunnel.

What does an attacker need to guess? Just the IP addresses?

It's for IPv4 simply because I don't use IPv6 for IPSEC dev. Let me know if you think adding v6 support is desired. I'd rather like to do it in seperate review/commit as it will take me some time to run proper testing.

OK. Makes sense. It would be nice to keep features between IPv4 and IPv6 in sync eventually.

The longer I look into it the more I think the UDP part should be moved to the UDP code. Althoug it would be cleaner to have it here, due to limitations in RFC1191 payload length it is impossible to associate tunnel ID if knowing only UDP flow. I will handle it in a separate review and propose sth more generic.

Meanwhile, reverting back to the original version which handles only IP+ESP tunneling.
Answering your question what an attacker needs to know, it is required to have IP address and SPI-ID to match an existing IPSEC tunnel. There isn't much more we can validate as the ICMP response packet contains only 8 bytes of original packet data after its IP header.
RFC1191 addresses such scenario and makes the PMTUD unable to set MTU lower than some minimal value to prevent setting it to too low value for a specific flow.

In D30992#706540, @wma wrote:

The longer I look into it the more I think the UDP part should be moved to the UDP code. Althoug it would be cleaner to have it here, due to limitations in RFC1191 payload length it is impossible to associate tunnel ID if knowing only UDP flow. I will handle it in a separate review and propose sth more generic.

Meanwhile, reverting back to the original version which handles only IP+ESP tunneling.
Answering your question what an attacker needs to know, it is required to have IP address and SPI-ID to match an existing IPSEC tunnel. There isn't much more we can validate as the ICMP response packet contains only 8 bytes of original packet data after its IP header.

Sorry for not knowing IPSEC better... Is the SPI-ID a random number or most likely a number like 1, 2, or 3?
The PTB message may contain more than 8 bytes (which is often needed for encapsulation stuff), so you
might want to validate more, if available.

The reason I'm asking is how easy it is for an off-path attacker to reduce the path MTU, since this value
is cached in the OS and also used for other protocols.

We don't need to be perfect here, but for SCTP the attacker must guess the port numbers (when assuming a popular service, this is 14 bit of randomness) and the verification tag (which is 32-bit randomness). In the case of TCP, you have the 14 bit of randomness of the port plus the sequence number is validated.

RFC1191 addresses such scenario and makes the PMTUD unable to set MTU lower than some minimal value to prevent setting it to too low value for a specific flow.

Sure. But operating at a lower MTU reduces the efficiency. BTW, what are you using as a lower bound?

SPI is a 32-bit semi-random value which would be quite hard to guess, unless somebody can sniff the traffic (but such case is a problem for all rfc1191-enabled protocols regardless of any anti-tampering checks).
To be 100% sure the packet belong to IPSEC tunnel (and that's how it works in ipsec module) is to use SPI and analyse ESP-Trailer and ESP-Authentication to confirm the originator of the packet is the machine we expect and data was not modified. Unfortunately, both of these are the last entries in IPSEC packet thus are not available in PTB response.

I'm using 576 bytes, default suggested in rfc. The user, however, can set sth else with sysctl.

In D30992#706545, @wma wrote:

SPI is a 32-bit semi-random value which would be quite hard to guess, unless somebody can sniff the traffic (but such case is a problem for all rfc1191-enabled protocols regardless of any anti-tampering checks).

OK, that is fine.

To be 100% sure the packet belong to IPSEC tunnel (and that's how it works in ipsec module) is to use SPI and analyse ESP-Trailer and ESP-Authentication to confirm the originator of the packet is the machine we expect and data was not modified. Unfortunately, both of these are the last entries in IPSEC packet thus are not available in PTB response.

I'm using 576 bytes, default suggested in rfc. The user, however, can set sth else with sysctl.

OK.

This revision is now accepted and ready to land.Jul 30 2021, 10:14 AM
This revision was automatically updated to reflect the committed changes.