Bridge filtering
nftables provides the bridge family as a replacement for ebtables.
Bridge chain types
The bridge family provides four chain types:
- prerouting: you can filter packets before the Forward Database (FDB) decision. The FDB provides the bridge port that is used for a given destination MAC address. If there is not entry in the FDB yet for a given destination MAC, then the packet is flooded to all bridge ports. After the FDB decision, packets can follow either the input or the forward path.
- input: you can filter packets that are passed up to the IP stack. If your bridge interface has an IP address and packets go to this IP address (or this IP address is used as gateway), then packets follow this path (in this case, packets leave the bridge to enter the IP stack, so packets are "routed").
- forward: you can use this hook to filter packets coming in from a bridge port that are delivered to another bridge port (this is the bridge forwarding path, in this case packets are "bridged").
- output: you can filter packets that are coming from the IP stack whose destination is the bridge port.
- postrouting: you can filter packets either coming from the IP stack or being forwarded from another bridge port.
Stateless filtering
If you would like to filter on TCP destination port in ipv4 packets:
% nft add rule bridge filter forward ether type ip tcp dport 22 accept
Another example to accept ARP packets:
% nft add rule bridge filter forward ether type arp accept
Stateful filtering
The bridge family supports connection tracking since Linux kernel 5.3.
You only have to match on conntrack state information from your ruleset to enable it.
For those that are familiar with iptables: this provides a replacement for br_netfilter and the -m physdev match for iptables.
Example: Stateful bridge firewall
The following example shows how to deploy a stateful bridge firewall, this assumes the bridge interface has no IP address.
Assuming a bridge with two ports, eth0 and eth1.
- A desktop computer is connected to bridge port eth0
- A web server (with SSH for remote administrador) is connected to bridge port eth1
- Uplink is bridge port eth2
The following policy allows for the desktop computer and the web server to initiate any connection. From the outside:
- no connection can be initiated to the desktop computer
- connections to the HTTP and SSH service to the server are allowed
From inside the bridge, the desktop computer and the web server can initiatiate connections to anywhere:
% nft add table bridge filter
% nft add chain bridge filter forward '{type filter hook forward priority 0; }'
% nft add rule bridge filter forward ct state established,related accept
% nft add rule bridge filter forward iif { eth0, eth1 } oif eth2 ct state new accept
% nft add rule bridge filter forward iif eth2 oif eth1 ct state new tcp dport { 22, 80, 443 } accept