Re: FreeBSD 14 Firewall Passes ALL traffic!

From: Dan Lists <lists.dan_at_gmail.com>
Date: Mon, 11 Aug 2025 16:30:25 UTC
On Mon, Aug 11, 2025 at 9:40 AM Dan Lists <lists.dan@gmail.com> wrote:

> On Fri, Aug 8, 2025 at 4:22 PM Souji Thenria <mail@souji-thenria.net>
> wrote:
>
>> On Fri Aug 8, 2025 at 6:51 PM CEST, Dan Lists wrote:
>> > On Fri, Aug 8, 2025 at 11:38 AM Souji Thenria <mail@souji-thenria.net>
>> > wrote:
>> >
>> >>
>> >> On 8. Aug 2025, at 18:13, Dan Lists <lists.dan@gmail.com> wrote:
>> >>
>> >> 
>> >> We have a transparent (bridged) firewall that we have been using since
>> >> around 2015, maybe earlier.
>> >>
>> >> After upgrading to FreeBSD 14 the firewall passes all traffic across
>> the
>> >> bridge!  That is obviously VERY bad.
>> >>
>> >> The firewall does block traffic to the server itself, but not traffic
>> >> passing on the bridge interface.
>> >>
>> >> I've tested the exact same rules on FreeBSD 12 and 13 and they work
>> fine.
>> >> I verified that the rules are the same, as well and the loaded kernel
>> >> modules.  I tried 14.0, 14.2, and 14.3 and all of them pass all
>> traffic on
>> >> the bridge interface.
>> >>
>> >> I looked at the release notes and I did not see anything that would
>> cause
>> >> this.
>> >>
>> >> I am at a loss on how to debug this.
>> >>
>> >> Please Help!
>> >>
>> >> Thanks
>> >>
>> >>
>> >>
>> >> Hi Dan,
>> >>
>> >> I hope this mail is not that badly formatted since I’m writing it on my
>> >> phone.
>> >>
>> >> There was a change. There is also a post in the FreeBSD forum [0].
>> Based
>> >> on that you need to set sysctl net.link.bridge.pfil_bridge=1.
>> >>
>> >> Regards,
>> >> Souji
>> >>
>> >> [0]
>> >>
>> https://forums.freebsd.org/threads/pf-rule-not-working-after-upgrade-to-14-0.93874/
>> >>
>> >
>> > Sorry, I should have mentioned that I've tried setting that and it still
>> > doesn't work.
>> >
>> > I've tried some random things, and the problem seems to be using 'via
>> > <interface>'.
>> >
>> > I have  outside em1 <--> bridge0 <--> em2 outside.
>> >
>> > I have rules like  "ipfw add deny log tcp from any to IP in via em1".
>> The
>> > idea is that I can block incoming traffic but allow outbound connections
>> > with state.  If I remove "in via em1" or change it to "[in] via
>> bridge0" it
>> > blocks incoming traffic but does not allow outbound traffic from IP.
>>
>> I'm not familiar with ipfw. However, if I understand you correctly, your
>> firewall is not acting on the bridge interface itself, but rather on
>> both "real" interfaces. I feel like this should be fairly
>> straightforward.
>>
>> Maybe you can post your firewall rules here, and someone with more
>> experience with ipfw can help.
>>
>> --
>> Souji Thenria
>> Website: www.souji-thenria.net
>
>
> A stripped down version of the rules is attached.   I have been using
> essentially the same rules since FreeBSD 10, maybe 15+ years.  I have tried
> the exact same rule set on FreeBSD 12, 13, and 14.
>
> With FreeBSD 14, anywhere in the world can connect to 12.34.56.78 on port
> 443.  If I change 'in via em1' to 'recv em1' it blocks incoming traffic but
> does not allow outbound traffic with state.
>
> This is a change from previous behavior.  I'm not sure if it was intended
> or a consequence of some other change.  I'd like some help figuring out how
> to solve the problem.
>
> Thanks again.
>

Gmail doesn't want to display the rules file without downloading.   I
figure others have that issue too.   Here are the lines copied.

 #!/bin/sh

alias ipfw="ipfw -q"

# Set the maximum number of dynamic rules
sysctl net.inet.ip.fw.dyn_max=65536 > /dev/null
sysctl net.inet.ip.fw.dyn_buckets=4096 > /dev/null

# Flush the old rules
$ipfw -f flush

# This brakes IPv6!
sysctl net.inet.ip.fw.one_pass=0 > /dev/null
$ipfw add 100 reass ip4 from any to any in

$ipfw add allow tcp from 'table(staff_ips)' to me 22 in
$ipfw add allow tcp from me 22 to 'table(staff_ips)' out

$ipfw add 39999 check-state

$ipfw add allow tcp from 'table(staff_ips)' to 12.34.56.78 443 in  via em1
$ipfw add allow tcp from 12.34.56.78 443 to 'table(staff_ips)' out via em1

# Deny most traffic inbound on em1
$ipfw add deny $logall all from not me to not me in via em1

# Allow everyting behind firewall to ping out by default
$ipfw add allow icmp from not me to not me out via em1 keep-state

# Allow all traffic on 'inside' interface and the bridge
$ipfw add allow all from not me to not me via em2
$ipfw add allow all from not me to not me via bridge0

# Block multicast without logging
$ipfw add deny ip4 from any to 224.0.0.0/8

# Block (windows) probes without logging
$ipfw add deny udp from any to any 137-139

# Allow essential icmp messages
$ipfw add 60000 allow icmp from any to any out
$ipfw add 60100 allow icmp from any to any in icmptypes 0   // echo-reply
$ipfw add 60200 allow icmp from any to any in icmptypes 3   // destination
unreachable
$ipfw add 60300 allow icmp from any to any in icmptypes 11  // time exceeded

# Allow essential icmp6 messages
$ipfw add 61000 allow ipv6-icmp from any to any out
$ipfw add 61100 allow ipv6-icmp from fe80::/10 to any in
$ipfw add 61200 allow ipv6-icmp from any to ff02::/32 in
$ipfw add 61300 allow ipv6-icmp from any to any in icmp6types 1   //
destination unreachable
$ipfw add 61400 allow ipv6-icmp from any to any in icmp6types 2   // packet
too big
$ipfw add 61500 allow ipv6-icmp from any to any in icmp6types 3   // time
exceeded
$ipfw add 61600 allow ipv6-icmp from any to any in icmp6types 4   //
parameter problem
$ipfw add 61700 allow ipv6-icmp from any to any in icmp6types 129 //
echo-reply
$ipfw add 61800 allow ipv6-icmp from any to any in icmp6types
133,134,135,136

# Allow everything out with state
$ipfw add 63000 allow tcp from any to any out setup keep-state
$ipfw add 63100 allow udp from any to any out keep-state
$ipfw add 63200 allow ip  from any to any out

$ipfw add 65520 deny icmp from any to any in icmptypes 8 // echo request
$ipfw add 65521 deny ipv6-icmp from any to any in icmp6types 128 // echo
request
$ipfw add 65522 deny udp  from any to any 33434-33534 in // traceroute
$ipfw add 65523 deny ip from any to 255.255.255.255
$ipfw add 65530 deny log ip from any to any