Possible issue with handing of icmp6 on pfsense
-
So talking about out of the box config and I believe this applies to 2.2 and 2.4.
When I first used my phone on pfsense it had issues loading play store images, of which I know from experience is a mtu related problem.
I then added manual rules for ipv6 to allow the packet size packets and things were good again.
Today I had a look at the generated rules and it does look there is default rules that should work.
These below.
pass quick inet6 proto ipv6-icmp all icmp6-type unreach keep state pass quick inet6 proto ipv6-icmp all icmp6-type toobig keep state pass quick inet6 proto ipv6-icmp all icmp6-type neighbrsol keep state pass quick inet6 proto ipv6-icmp all icmp6-type neighbradv keep state
Now in my years of using PF I have not configured the direction of the traffic like the above rules which dont specify in or out. So I cannot say they are defenitly ok.
My custom rules however I now know after checking are not going to be working due to how I selected WAN and its locked them to do link local ip only.
Has anyone else had mtu issues on ipv6 with pfsense?
-
I just had to deal with this issue on my 2.3.3 snapshot machine. Out of the box it doesn't appear that pfSense is compliant with RFC 4890's recommendations for IPv6 ICMP filtering.
RFC 4890 requires echoreq, echorep, paramprob, timex, toobig, unreach as traffic that must not be dropped by a filtering firewall.
The default rules improperly implement this RFC with respect to transit traffic:
pass quick inet6 proto ipv6-icmp all icmp6-type unreach keep state pass quick inet6 proto ipv6-icmp all icmp6-type toobig keep state pass quick inet6 proto ipv6-icmp all icmp6-type neighbrsol keep state pass quick inet6 proto ipv6-icmp all icmp6-type neighbradv keep state
neighbrsol and neighbradv should not be passed by transit rules. They are properly passed by the link-local rules that follow.
With just the default transit rules my implementation would not pass IPv6 readiness testing.
I added the following manual rules to each interface to properly implement RFC4890 transit filtering. These rules are edited for clarity - the rule was added as a floating IPV6 rule and applied to all interfaces.
pass quick inet6 proto ipv6-icmp all icmp6-type echorep keep state pass quick inet6 proto ipv6-icmp all icmp6-type echoreq keep state pass quick inet6 proto ipv6-icmp all icmp6-type paramprob keep state pass quick inet6 proto ipv6-icmp all icmp6-type timex keep state label pass quick inet6 proto ipv6-icmp all icmp6-type toobig keep state label pass quick inet6 proto ipv6-icmp all icmp6-type unreach keep state label
After adding these rules my deployment now passes ipv6 readiness testing.
I have not reloaded my 2.2 deployment to check the default rules, but I do not recall encountering issues with 2.2's ability to pass ipv6 readiness testing.
-
What "readiness test" are you using to determine if it's OK?
In most cases, users pass out any ICMP which should take care of that. pf is usually smart enough to let through ICMP errors related to connections with open states.
We could consider a patch like the following to strictly allow what RFC 4890 claims should be allowed, though I'm not convinced it's necessary given the way most people intend a firewall to operate.
diff --git a/src/etc/inc/filter.inc b/src/etc/inc/filter.inc index 6890c98..08625d4 100644 --- a/src/etc/inc/filter.inc +++ b/src/etc/inc/filter.inc @@ -3118,13 +3118,20 @@ EOD; # See man icmp6(4) # 1 unreach Destination unreachable # 2 toobig Packet too big +# 3 timex Time exceeded +# 4 paramprob Parameter problem # 128 echoreq Echo service request # 129 echorep Echo service reply # 133 routersol Router solicitation # 134 routeradv Router advertisement # 135 neighbrsol Neighbor solicitation # 136 neighbradv Neighbor advertisement -pass {$log['pass']} quick inet6 proto ipv6-icmp from any to any icmp6-type {1,2,135,136} tracker {$increment_tracker($tracker)} keep state +pass {$log['pass']} quick inet6 proto ipv6-icmp from any to any icmp6-type {1,2,128,129} tracker {$increment_tracker($tracker)} keep state +pass {$log['pass']} quick inet6 proto ipv6-icmp from any to any icmp6-type 3 code 0 tracker {$increment_tracker($tracker)} keep state +pass {$log['pass']} quick inet6 proto ipv6-icmp from any to any icmp6-type 3 code 1 tracker {$increment_tracker($tracker)} keep state +pass {$log['pass']} quick inet6 proto ipv6-icmp from any to any icmp6-type 4 code 0 tracker {$increment_tracker($tracker)} keep state +pass {$log['pass']} quick inet6 proto ipv6-icmp from any to any icmp6-type 4 code 1 tracker {$increment_tracker($tracker)} keep state +pass {$log['pass']} quick inet6 proto ipv6-icmp from any to any icmp6-type 4 code 2 tracker {$increment_tracker($tracker)} keep state # Allow only bare essential icmpv6 packets (NS, NA, and RA, echoreq, echorep) pass out {$log['pass']} quick inet6 proto ipv6-icmp from fe80::/10 to fe80::/10 icmp6-type {129,133,134,135,136} tracker {$increment_tracker($tracker)} keep state