For about a year I've run without a firewall on the IPv6 side of my server because I couldn't figure it out at the time and then I forgot I was meant to come back to it. Not that it is actually much of a worry, as I'm the only user on the server, had (and still have) very few ports open and corresponding services running, and until just recently I'd never pointed any domains at my IPv6 address. But since I've now remembered, I'd prefer to have something in place.

When I tried to replicate what I had on the IPv4 side of things it would result in me killing my IPv6 connectivity. I thought about building my own kernel to enable npf instead of ipf to see if that solved problems, but never got any further than thinking about it.

After a great deal of trial and error I've finally figured out that the key to getting IPv6 to work whilst still having a ipf6.conf is to leave ICMP completely alone. Whether it's due to bugs in ipfilter or my incompetence on networking (it is confusing) a default block on TCP/UDF/ICMP will seemingly always take precedence over any allows on ICMP. I even got to a point where I was logging blocks and tweaking the rules until I'd made sure no ICMP packets were being blocked in or out, but IPv6 still wasn't working! As soon as I changed my default blocks to target only TCP/UDP it worked.

I.e. I have this kind of setup on IPv4:

#Default blocks
block in on xennet0
block out on xennet0

#Allow anything out
pass out quick on xennet0 proto tcp/udp from any to any keep state keep frags
pass out quick on xennet0 proto icmp from any to any keep state

#Allow just these in
pass in quick on xennet0 proto tcp from any to any port = smtp flags S keep state

And I tried the same on IPv6, with necesssary amendments and being more permissive because IPv6 seems to more dependent on ICMP for network autoconfiguration:

#Default blocks
block in log on xennet0
block out log on xennet0

#Allow anything out
pass out quick on xennet0 proto tcp/udp from any to any keep state keep frags
#Unsure if first one below does anything
pass out quick on xennet0 proto ipv6 from any to any keep state
pass out quick on xennet0 proto ipv6-icmp from any to any keep state

#Allow just these in
pass in quick on xennet0 proto ipv6-icmp from any to any keep state
pass in quick on xennet0 proto tcp from any to any port = smtp flags S keep state

But the ipv6-icmp rules were not effective, even if the logs said they were. I could restart the network and get IPv6 connectivity, but it would die as soon as I tried to use it. However, the following approach does work:

#Default blocks
block in on xennet0 proto tcp/udp
block out on xennet0 proto tcp/udp

#Allow anything out
pass out on xennet0 proto tcp/udp from any to any keep state keep frags

#Allow just these in
pass in quick on xennet0 proto tcp from any to any port = smtp flags S keep state

So it's still not perfect (I could do with restricting what's allowed out for starters), but it's definitely better than having no firewall at all on IPv6. And if someone does manage to bring the server down with a maliciously crafted ICMP packet over IPv6 then fair game to them.


[EDIT: 2015-10-19] Update for NetBSD 7: For whatever reason, even mentioning ICMP in the IPv4 rules killed IPv6 connectivity. The IPFilter version had changed, I believe, between NetBSD 6 and 7. Also, searching the NetBSD mailing list archives I saw a couple of KERN bug reports relating to NetBSD 7 (prior to release), Xen and Ipf. So perhaps it just has issues. I should really get around to building a Xen kernel with npf support. In the meantime, however, doing the same thing in ipf.conf and ipf6.conf did the trick. I.e: don't mention icmp and explicity target tcp/udp on the block and pass out rules.