PF it seems I can’t filter traffic on bridge0 (or any other bridges)

Hello,

I’m running a FreeBSD 14.5-RELEASE as internet gateway / firewall / Jail+VM host.
I’ve added a bunch of Jails recently so I would like to add a bit of filtering inside the box, not just on the external interface.

Basically my pf.conf looks like this:

Code:
# macros
int_if = "igc1"
ext_if = "igc0.836"
vm_if = "bridge0"
wg_if = "wg0"

adblocker = "192.168.2.xx"
HA = "192.168.2.xx"

tcp_services = "{ 80, 8080, 443, ... }"
udp_services = "{ 443, 53, ... }"
admin_tcp_services = "{ 22, 311, 625, ... }"
admin_udp_services = "{ 3283, ... }"

icmp_types = "echoreq"

priv_nets = "{ 127.0.0.0/8, 172.16.0.0/12, 10.0.0.0/8 }"

table <admin_nets> persist { ... }
table <friends> persist { ... }
table <eduroam> persist { ... }
table <crowdsec-blacklists> persist
table <forbidden-dns> persist { 8.8.8.8, ... }

# options
set block-policy return
set loginterface $ext_if
set skip on lo0
set skip on tun0
set skip on $wg_if

# scrub
scrub in all

# nat
nat on $ext_if from $int_if:network to any -> ($ext_if)
nat on $ext_if from { 192.168.100.1/24 } to any -> ($ext_if)
nat on $ext_if from $vm_if:network to any -> ($ext_if)

rdr log on $int_if proto { udp, tcp } from ! 192.168.0.4 to ! $adblocker port domain -> $adblocker port domain

# filter rules
block log all

block log quick on $ext_if from 192.168.1.xx to any label "bidibule drop"
block log quick on $ext_if from 192.168.1.xx to any label "nexus4 drop"
block log quick on $int_if from $TV to <forbidden-dns> label "LGTV DNS drop"
block log quick on $vm_if from $HA to ! 192.168.0.0/16 label "Home Assistant drop"

pass in log quick on $ext_if inet proto tcp from <admin_nets> to ($ext_if) port 22 flags S/SA keep state
pass in quick on $ext_if inet proto tcp from { <friends>, <eduroam> } to ($ext_if) port 443 flags S/SA keep state
pass in quick on $ext_if inet proto udp from { <friends>, <eduroam> } to ($ext_if) port 443 keep state
pass in quick on $ext_if inet proto { tcp, udp } from { ... } to ($ext_if) port syslog flags S/SA keep state
pass inet proto {tcp,udp} from 192.168.2.0/24 to $adblocker port 53 keep state

# Anchors
anchor "blacklistd/*" in on $ext_if
block drop in log quick from <crowdsec-blacklists> to any

pass on $vm_if

pass in on $ext_if inet proto tcp from any to ($ext_if) port $tcp_services flags S/SA keep state
pass in on $ext_if inet proto udp from any to ($ext_if) port $udp_services keep state

##### admin
pass in log on $ext_if inet proto tcp from { <admin_nets>, <friends> } to { ($ext_if), ... } port $admin_tcp_services flags S/SA keep state
pass in log on $ext_if inet proto udp from { <admin_nets>, <friends> } to { ($ext_if), ... } port $admin_udp_services keep state

##### ICMP
pass in inet proto icmp all icmp-type $icmp_types keep state

pass in  on $int_if from $int_if:network to any keep state
pass out on $int_if from any to $int_if:network keep state

pass out on $ext_if proto tcp all flags S/SA keep state
pass out on $ext_if proto { udp, icmp } all keep state

I’ve also set up
Code:
net.link.bridge.pfil_member=1
net.link.bridge.pfil_bridge=1

And my network looks like this:
Code:
igc1: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
 options=4e427bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,WOL_MAGIC,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,HWSTATS,MEXTPG>
    ether xxxxxxxxxxxxx
    inet 192.168.0.1 netmask 0xffffff00 broadcast 192.168.0.255
    inet 192.168.0.204 netmask 0xffffff00 broadcast 192.168.0.255
    ... (and other classic Jails)
    media: Ethernet 1000baseT (1000baseT <full-duplex>)
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
bridge0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
    options=0
    ether yyyyyyyyyyyyyyy
    inet 192.168.2.1 netmask 0xffffff00 broadcast 192.168.2.255
    id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
    maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
    root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
    member: tap0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
            ifmaxaddr 0 port 11 priority 128 path cost 2000000
    ... (and other VNET Jails)
    groups: bridge vm-switch viid-99615@
    nd6 options=9<PERFORMNUD,IFDISABLED>
igc0.836: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
    options=4600703<RXCSUM,TXCSUM,TSO4,TSO6,LRO,RXCSUM_IPV6,TXCSUM_IPV6,MEXTPG>
    ether zzzzzzzzzzzzzzz
    inet a.b.c.d netmask 0xffffff00 broadcast a.b.c.255
    groups: vlan
    vlan: 836 vlanproto: 802.1q vlanpcp: 0 parent interface: igc0
    media: Ethernet autoselect (1000baseT <full-duplex>)
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
tap0: flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
    description: vmnet/hass/0/interne
    options=80000<LINKSTATE>
    ether wwwwwwwwwwwwww
    groups: tap vm-port
    media: Ethernet 1000baseT <full-duplex>
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
    Opened by PID 31696

This general setup is working but it does not allow me to block selected traffic from VM or VNet Jails hooked to the bridge bridge0. For example, the following line from pf.conf does nothing:
Code:
block log quick on $vm_if from $HA to ! 192.168.0.0/16 label "Home Assistant drop"

Any idea of what I could be missing?

Thanks!
 
Back
Top