PF with IPv6
bc979 at lafn.org
Mon May 3 00:40:34 UTC 2021
> On 1 May 2021, at 07:37, Paul Mather <paul at gromit.dlib.vt.edu> wrote:
> On Fri, 30 Apr 2021 21:20:48 -0700, Doug Hardie <bc979 at lafn.org <mailto:bc979 at lafn.org>> wrote:
>> Message: 3
>> Date: Fri, 30 Apr 2021 21:20:48 -0700
>> From: Doug Hardie <bc979 at lafn.org <mailto:bc979 at lafn.org>>
>> To: FreeBSD Questions <freebsd-questions at freebsd.org <mailto:freebsd-questions at freebsd.org>>
>> Subject: PF with IPv6
>> Message-ID: <2CD4806C-F1A4-4DDE-8C2F-2B0A08EA2A18 at sermon-archive.info <mailto:2CD4806C-F1A4-4DDE-8C2F-2B0A08EA2A18 at sermon-archive.info>>
>> Content-Type: text/plain; charset=us-ascii
>> FreeBSD 13-RELEASE. I have a small test network setup and tried to block all IPv6 except those addressed to a specific address. /etc/pf.conf contained:
>> ext_if = "bge0"
>> LAN3 = "2001:1000:0:3000::/64"
>> pass in quick log on $ext_if proto ipv6 from $LAN3 to $LAN3
>> block in log on $ext_if proto ipv6 from any to any
>> Nothing got blocked. pftop showed all zeros for both rules. I then added at the end:
>> pass in quick log on $ext_if proto icmp6 from $LAN3 to $LAN3
>> block in log on $ext_if proto icmp6 from any to any
>> A lot of stuff got blocked. The log shows many entries like:
>> 15:59:41.597632 rule 3/0(match): block in on bge0: (hlim 1, next-header Options (0) payload length: 32) fe80::120c:6bff:fe5d:4404 > ff02::1: HBH (rtalert: 0x0000) (pad1)(pad1) ICMP6, multicast listener query
>> 0x0000: 6000 0000 0020 0001 fe80 0000 0000 0000 `...............
>> 0x0010: 120c 6bff fe5d 4404 ff02 0000 0000 0000 ..k..]D.........
>> 0x0020: 0000 0000 0000 0001 3a00 0502 0000 0000 ........:.......
>> 0x0030: 8200 98aa ....
>> Rule 3 is the block for ICMP6, but those are clearly IP6 packets that should have been blocked by rule 1. Is there a problem with IPv6 and pf?
> It's not clear to me precisely what you are trying to achieve. The "proto" keyword in PF rules refers to protocols in /etc/protocols. Your rules appear to be targeting the specific case of filtering IPv6 encapsulated in IPv4. I don't believe that is what you intend.
> The more standard way in PF to block IPv6 vs IPv4 traffic is to use "inet" (IPv4) or "inet6" (IPv6) to target IPv4 or IPv6 packets.
> Note, the last rule you added that you say did start blocking things is more typical of rules to block ICMP6. Because you omit "inet" or "inet6" on the rule it will be applied to both IPv4 and IPv6 packets. But, the "proto icmp6" part is specifically targeting ICMP6.
> So, to summarise, use "inet" and "inet6" to select IPv4 and IPv6 and "proto" to select the protocol you want to target (e.g., "tcp", "udp", "icmp", "icmp6", etc.). E.g., "pass in log quick on $ext_if inet6 from ..." to allow all IPv6 for the rule, or ""pass in log quick on $ext_if inet6 proto tcp from ..." to allow only IPv6 TCP traffic, etc.
First, it appeared to me that since ipv6 is listed in /etc/protocols, that it could be used as a protocol. However, after reading the man page again, I see where it wants family, not protocol. With that change it does work.
What I was trying to do was to simulate a multi LAN configuration using only one physical LAN. This is quite easy to do with IPv4, but even with a bunch of pf rules, there are issues with the multicast packets. Hosts should only listen to packets addressed to their virtual LAN but multicast packets are not identifiable by which virtual LAN they were sent to. So I ended up adding a bunch of switches and building the complete multi LAN configuration.
More information about the freebsd-questions