Project

General

Profile

Actions

Bug #11418

closed

'NAT-T: Force' is broken for IPv6 IPsec

Added by Azamat Khakimyanov about 3 years ago. Updated about 2 months ago.

Status:
Resolved
Priority:
Very Low
Assignee:
-
Category:
IPsec
Target version:
Start date:
02/14/2021
Due date:
% Done:

0%

Estimated time:
Plus Target Version:
24.03
Release Notes:
Force Exclusion
Affected Version:
2.4.5-p1
Affected Architecture:

Description

While I tested IPsec I found that 'NAT-T: Force' is broken for IPv6. I've tried IKEv1 and IKEv2 with both 'Mutual certificate' and 'Mutual PSK' - tunnel is always initiated successfully (via UDP 4500) but I see no traffic on remote side.
I tried: Force-Auto, Force-Force - doesn't matter, no traffic on remote side.
Packet Capture showed that local pfSense forwards traffic into IPsec but I don't see it on remote. As soon as I turn to 'NAT-T: Auto' on both sides everything is working correctly (via UDP 500)

My Setup is
- local device: SG-2220 with WAN IPv6: 2001:xxxx:fe09:c84a and LAN IPv6: 2001:zzzz:208:a2ff:fe09:c84b
- remote device: SG-2440 with WAN IPv6: 2001:xxxx:fe0a:acae and LAN IPv6: 2001:yyyy:208:a2ff:fe0a:acaf

I see all defaults firewall rules:
Local:
pass out inet6 proto udp from (self) to 2001:xxxx:fe0a:acae port = isakmp keep state label "IPsec: 2001:xxxx:fe0a:acae - outbound isakmp"
pass in on igb0 inet6 proto udp from 2001:xxxx:fe0a:acae to (self) port = isakmp keep state label "IPsec: 2001:xxxx:fe0a:acae - inbound isakmp"
pass out inet6 proto udp from (self) to 2001:xxxx:fe0a:acae port = sae-urn keep state label "IPsec: 2001:xxxx:fe0a:acae - outbound nat-t"
pass in on igb0 inet6 proto udp from 2001:xxxx:fe0a:acae to (self) port = sae-urn keep state label "IPsec: 2001:xxxx:fe0a:acae - inbound nat-t"
pass out inet6 proto esp from (self) to 2001:xxxx:fe0a:acae keep state label "IPsec: 2001:xxxx:fe0a:acae - outbound esp proto"
pass in on igb0 inet6 proto esp from 2001:xxxx:fe0a:acae to (self) keep state label "IPsec: 2001:xxxx:fe0a:acae - inbound esp proto"

Remote:
pass out inet6 proto udp from (self) to 2001:xxxx:fe09:c84a port = isakmp keep state label "IPsec: 2001:xxxx:fe09:c84a - outbound isakmp"
pass in on igb0 inet6 proto udp from 2001:xxxx:fe09:c84a to (self) port = isakmp keep state label "IPsec: 2001:xxxx:fe09:c84a - inbound isakmp"
pass out inet6 proto udp from (self) to 2001:xxxx:fe09:c84a port = sae-urn keep state label "IPsec: 2001:xxxx:fe09:c84a - outbound nat-t"
pass in on igb0 inet6 proto udp from 2001:xxxx:fe09:c84a to (self) port = sae-urn keep state label "IPsec: 2001:xxxx:fe09:c84a - inbound nat-t"
pass out inet6 proto esp from (self) to 2001:xxxx:fe09:c84a keep state label "IPsec: 2001:xxxx:fe09:c84a - outbound esp proto"
pass in on igb0 inet6 proto esp from 2001:xxxx:fe09:c84a to (self) keep state label "IPsec: 2001:xxxx:fe09:c84a - inbound esp proto"

and I use 'IPv4-IPv6 Allow All' rule on LAN and IPsec on both sides

With 'NAT-T: Auto' when I ping from LAN to LAN I see that ping works
Local
WAN udp 2001:xxxx:fe0a:acae500 -> 2001:xxxx:fe09:c84a500 MULTIPLE:MULTIPLE 4 / 4 6 24 B / 624 B
IPsec ipv6-icmp 2001:zzzz:208:a2ff:fe09:c84b6440 -> 2001:yyyy:208:a2ff:fe0a:acaf6440 NO_TRAFFIC:NO_TRAFFIC 10 / 10 560 B / 560 B
WAN esp 2001:xxxx:fe09:c84a -> 2001:xxxx:fe0a:acae MULTIPLE:MULTIPLE 10 / 10 1 KiB / 1 KiB

Remote
WAN udp 2001:xxxx:fe0a:acae500 -> 2001:xxxx:fe09:c84a500 MULTIPLE:MULTIPLE 3 / 3 468 B / 468 B
WAN esp 2001:xxxx:fe09:c84a -> 2001:xxxx:fe0a:acae MULTIPLE:MULTIPLE 10 / 10 1 KiB / 1 KiB
IPsec ipv6-icmp 2001:zzzz:208:a2ff:fe09:c84b6440 -> 2001:yyyy:208:a2ff:fe0a:acaf6440 NO_TRAFFIC:NO_TRAFFIC 10 / 10 560 B / 560 B

but when I use 'NAT-T: Force' I get
Local and Remote
WAN udp 2001:xxxx:fe09:c84a500 -> 2001:xxxx:fe0a:acae500 MULTIPLE:MULTIPLE 2 / 2 672 B / 784 B
WAN udp 2001:xxxx:fe09:c84a4500 -> 2001:xxxx:fe0a:acae4500 MULTIPLE:MULTIPLE 7 / 6 3 KiB / 3 KiB

so there are no states for WAN ESP and there are no states for IPv6-ICMP

Actions #1

Updated by Jim Pingle about 3 years ago

  • Project changed from pfSense Packages to pfSense
  • Category changed from IPsec Profile Wizard to IPsec
  • Assignee deleted (Jim Pingle)
  • Priority changed from Normal to Very Low

This is a problem in strongSwan and/or FreeBSD and not in pfSense software. See https://wiki.strongswan.org/issues/939#note-20

It required a kernel-level fix for Linux, likely would require same for FreeBSD if it's even possible/desirable.

NAT-T should be unnecessary with IPv6, so the impact potential here seems very low to me.

Actions #2

Updated by Richard Laager 9 months ago

This is a problem for us. In short, what is happening is that stateful firewalls in the middle are not associating the IKE and ESP traffic together. So while the ESP keeps the tunnel alive, the stateful firewall in the middle times out its state table entry for the IKE traffic. Later, when the ESP traffic stops for a bit, or when the rekey interval expires, the server needs to talk IKE to the client, but the traffic is blocked by the stateful firewall in the middle.

With IPv4, this is fine, as NAT-T means that the IKE and ESP traffic are enscapsulated in UDP and use the same UDP port. So the ESP traffic keeps the state table entry active and subsequent server -> client IKE communication is fine. But we cannot use NAT-T for IPv6 because of the issue here.

I see two possible solutions (assuming that you need your VPN to work on IPv6 through stateful firewalls you do not control):
A) FreeBSD needs to support IPsec NAT-T / ESP-in-UDP for IPv6.
B) strongSwan needs to support a mode where DPD (dead peer detection) only takes into account IKE traffic, not ESP traffic, such that it would continually send the IKE R_U_THERE packets, which keep the IKE firewall state active.

I want to stress that I'm talking about a stateful firewall in the middle, not any firewalling happening on the pfSense box itself.

Actions #3

Updated by Richard Laager 9 months ago

I submitted option B to strongSwan here: https://github.com/strongswan/strongswan/issues/1759

Actions #4

Updated by Richard Laager about 2 months ago

FYI: Wiktel and MICE (https://micemn.net) sponsored work by Klara (https://klarasystems.com), who landed a patch in FreeBSD:
https://cgit.freebsd.org/src/commit/?id=80044c785cb040a2cf73779d23f9e1e81a00c6c3
https://cgit.freebsd.org/src/commit/?id=dc02374f54455e354495870c24f86bb2966a7960

So the next step here is getting pfSense to bring in that patch (preferably directly as a backport, but alternatively via a newer FreeBSD kernel over time).

Actions #5

Updated by Marcos M about 2 months ago

  • Status changed from New to Feedback
  • Target version changed from Future to 2.8.0
  • Plus Target Version set to 24.03
  • Release Notes set to Force Exclusion

24.03 will have the upstream fixes - this can be tested currently in 24.03 dev snapshots.

Actions #6

Updated by Azamat Khakimyanov about 2 months ago

  • Status changed from Feedback to Resolved

Tested on 24.03-DEVELOPMENT (built on Fri Jan 26 9:00:00 MSK 2024)

There is no any issue with 'NAT-T: Force'. I was able to initiate IPv6 IPsec tunnel and traffic went through it without any problem with 'NAT-T: force' chosen. Tested both 'Mutual PSK' and 'Mutual Certificate'

I marked this bug as resolved.

Actions

Also available in: Atom PDF