OPNsense Forum
Archive => 23.1 Legacy Series => Topic started by: IsaacFL on July 20, 2023, 09:54:01 pm
-
I was cleaning up my firewall rules and noticed that the ipv6 Link Local (fe80::/10) is being added now to my group networks.
I have a Firewall Group, called IG_LOCAL which is all of my local interfaces. When I create a rule using the IG_LOCAL network, it is adding link local i.e. {(IG_LOCAL:network),fe80::/10}
I have attached a screenshot of some of my rules for the group. Here is the corresponding portion of the rules.debug file.
pass in log on IG_LOCAL inet6 proto {tcp udp} from {(IG_LOCAL:network),fe80::/10} to {!(IG_LOCAL:network),fe80::/10} port $PORT_EXT_DEF keep state label "769c1d81297045f5995b9e417dcec7ee" # IG: Default Allowed External Traffic
pass in on IG_LOCAL inet proto {tcp udp} from {(IG_LOCAL:network)} to {!(IG_LOCAL:network)} port $PORT_EXT_DEF_UNLOG keep state label "d6b7a1daa9884ab1063b3b2befdd9697" # IG: Unlogged External Traffic
pass in on IG_LOCAL inet6 proto {tcp udp} from {(IG_LOCAL:network),fe80::/10} to {!(IG_LOCAL:network),fe80::/10} port $PORT_EXT_DEF_UNLOG keep state label "d6b7a1daa9884ab1063b3b2befdd9697" # IG: Unlogged External Traffic
pass in quick on IG_LOCAL inet proto {tcp udp} from {(IG_LOCAL:network)} to {(self)} port {53} keep state label "e8b2d18b60eddedbc37a8affc7ad3295" # IG: DNS - Firewall
pass in quick on IG_LOCAL inet6 proto {tcp udp} from {(IG_LOCAL:network),fe80::/10} to {(self)} port {53} keep state label "e8b2d18b60eddedbc37a8affc7ad3295" # IG: DNS - Firewall
pass in quick on IG_LOCAL inet proto {tcp udp} from {(IG_LOCAL:network)} to $HOST_PIHOLE port {53} keep state label "7040cc54c75732b0eaf93823601201df" # IG: DNS - PiHole
pass in quick on IG_LOCAL inet6 proto {tcp udp} from {(IG_LOCAL:network),fe80::/10} to $HOST_PIHOLE port {53} keep state label "7040cc54c75732b0eaf93823601201df" # IG: DNS - PiHole
block return in log quick on IG_LOCAL inet proto {tcp udp} from {(IG_LOCAL:network)} to $EXT_PUBLIC_DNS port $PORT_EXT_PUBLIC_DNS label "e265696d9b53cf10cb05969a0a9c7613" # IG: DNS - Block Public DNS List
block return in log quick on IG_LOCAL inet6 proto {tcp udp} from {(IG_LOCAL:network),fe80::/10} to $EXT_PUBLIC_DNS port $PORT_EXT_PUBLIC_DNS label "e265696d9b53cf10cb05969a0a9c7613" # IG: DNS - Block Public DNS List
pass in quick on IG_LOCAL inet proto udp from {(IG_LOCAL:network)} to {(self)} port {123} keep state label "a8527e22120951fabfb8ab4a1159c11b" # IG: Firewall NTP
This is seems to be a new thing, at least since June which was the last time I downloaded rules.debug. Prior, it would just be {(IG_LOCAL:network)} for both inet and inet6.
Is there a reason for this?
-
Actually, it is being added to all of the interfaces, not just groups. ie {(em0:network),fe80::/10}
Just something to be aware of I guess.
-
https://github.com/opnsense/core/issues/5528 ;)
Cheers,
Franco
-
I agree with the issue, but not the solution.
Should probably defer to the pf developers for what is included in net just for those who check pf documentation? They have probably already considered the consequences.
Not sure how impacts performance, but it does now double the rules evaluation, when typically link local is not really wanted.
Pass “Lan net” to “dns.google” now will pass fe80::1 to 2001:4860:4860::8888. I don’t think we want that, so now have to explicitly block it?
Solution to this issue is to have a rule that passes udp fe80::/10 to fe80::/10,ff02::/16 either in the float or auto.
We already have an auto rule for icmp, just add for udp or just make one rule with "any".
-
fe80::/10 will not be passed across links. That's why it's called link local. It only works with a scope, i.e. fe80::1%igb0.
-
fe80::/16 will not be passed across links. That's why it's called link local. It only works with a scope, i.e. fe80::1%igb0.
Does the router actually examine the source address for scope and prevent it? I know it needs the scope on destination address to actually route it, but the scope for the source is known by the interface.
I am not familiar enough with the actual router implemention but I would be surprised if it actually examines with the source address. The packet destination address and where to forward it to is its only concern. If I did put the correct scope on it, wouldn’t it route it?
It seems like it could be used as an untraceable DOS method. And with the quality of most Linux developers as far as IPv6 I fully expect to see an IOT device sending the example I used before using fe80:: as a source address to a GUA destination.
-
OK ... let me rephrase that. No reasonable IP stack will send an IPv6 packet with a GUA as destination and a link local address as source.
-
OK ... let me rephrase that. No reasonable IP stack will send an IPv6 packet with a GUA as destination and a link local address as source.
Yes, but if everyone was reasonable we wouldn’t need firewalls.
-
I know that in ipv4 world there have been actual DOS attacks that used the link local 169.254.0.0/16 as source so that they are untraceable. I don't if its been done using ipv6. That is why we are supposed to block bogons as a source address, leaving the WAN.
I think the solution for the original issue would have been a float rule allowing ipv6 link local to multicast. It is legitimate traffic, and I probably would even do it as an auto rule. But to add link local to the "net" because of the unintended consequences, I don't think is the best solution if for no other reason, than the *BSD pf maintainers don't think think it should be there.
-
If you keep the Link Local as part of "net" you should be using fe80::/64 instead of fe80::/10.
Per RFC https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.6 (https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.6)
Link-Local addresses are for use on a single link. Link-Local
addresses have the following format:
| 10 |
| bits | 54 bits | 64 bits |
+----------+-------------------------+----------------------------+
|1111111010| 0 | interface ID |
+----------+-------------------------+----------------------------+
The lower 54 bits of the Link Local prefix should always be 0.
So at least for passing you only pass /64. For blocking the whole /10.