Home / Alt manpages / ebtables-nft(8)

  • ebtables-nft(8)
  • Admin command
  • linux

Build a Safe Bridge Firewall Rule with ebtables-nft

One wrong ebtables-nft rule can cut off bridge traffic that never even touches an IP address. This walks through adding, checking and removing a rule cleanly. The examples target ebtables-nft 1.8.10 (nf_tables), supplied here by the iptables 1.8.10-3ubuntu2 package.

Allow about 15 minutes, plus time to identify the correct bridge interface and MAC address. You need a shell, the installed ebtables-nft command, and root privileges for table access. The inspection commands are read-only; appending a rule changes live packet handling and counts as a service-disrupting operation.

1. Identify the bridge port and the rule table

Gather the real names before you write anything. This command is from the separate ip utility, not from ebtables:

$ ip link show
$ ip link show master BRIDGE_NAME
  • Replace BRIDGE_NAME with the real bridge device, such as br0.
  • Confirm the port on this host. The second command lists interfaces enslaved to that bridge; do not copy an example port name until you have checked it. A typo here can make a test rule look inactive, and picking the wrong port can cut off legitimate traffic.

Ebtables has three tables. filter is the default and holds INPUT, OUTPUT and FORWARD. nat is for MAC address changes around forwarding, and broute has the early BROUTING chain. This guide only touches the default filter table and its FORWARD chain, where bridged frames get filtered.

2. Save a readable baseline

Listing is a privileged read because the nftables-backed command has to fetch the kernel rule set:

$ sudo ebtables-nft -L --Ln --Lc
Bridge table: filter
Bridge chain: INPUT, entries: 0, policy: ACCEPT
Bridge chain: FORWARD, entries: 0, policy: ACCEPT
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT

Your output will differ if rules already exist, and the exact formatting is not a stable interface for scripts. --Ln adds rule numbers, --Lc prints packet and byte counters. Permission denied means rerun with sudo. If the existing policy looks wrong, do not work around it by flushing the chain.

For a reloadable representation, use the command form that --Lx produces:

$ sudo ebtables-nft -L --Lx

Keep that output in a root-readable temporary file if you need a record for recovery. The manpage documents --Lx as output that reconstructs the table, including user-defined chains. It is a snapshot, not a transaction, so take it immediately before any planned change.

3. Add one narrowly scoped test rule

Decide exactly what should match before you change any state. This example drops IPv4 Ethernet frames arriving through one bridge port and heading for one destination MAC address:

$ sudo ebtables-nft -A FORWARD \
    -i BRIDGE_PORT \
    -p IPv4 \
    -d 02:00:00:00:00:42 \
    -j DROP
  • Replace BRIDGE_PORT and the example MAC with values you have already verified.
  • -A appends to the selected chain.
  • -i matches the physical bridge port receiving the frame.
  • -p IPv4 restricts the rule to IPv4 Ethernet frames.
  • -d matches the Ethernet destination address.
  • -j DROP discards matching frames; everything else keeps moving through the chain.

Warning

There is no dry-run switch in the documented command set. A wrong rule goes live the moment the command succeeds. Keep a management path that does not depend on the affected bridge, and have an undo command ready before you press enter.

Checkpoint

List the numbered chain immediately:

$ sudo ebtables-nft -L FORWARD --Ln --Lc
Bridge chain: FORWARD, entries: 1, policy: ACCEPT
1. -i BRIDGE_PORT -p IPv4 -d 02:00:00:00:00:42 -j DROP, pcnt = 0 -- bcnt = 0

The presentation may show protocol names or slightly different spacing. What matters is that the rule sits in FORWARD, its match values are right, and the counters start at zero. A zero counter means no frame has matched yet; it does not prove the rule is wrong.

4. Observe traffic without guessing

Run the same listing after a controlled test from a permitted host:

$ sudo ebtables-nft -L FORWARD --Ln --Lc

The matching rule's packet counter (pcnt) and byte counter (bcnt) should climb once frames match. If they stay at zero, check the physical port, destination MAC, protocol and chain. A frame destined for the bridge itself belongs to INPUT, and a locally generated frame belongs to OUTPUT; neither matches this FORWARD rule.

To reset the counters once you have recorded a measurement, use the combined list-and-zero operation:

$ sudo ebtables-nft -L FORWARD --Ln --Lc -Z

This prints the counters before zeroing them. Zeroing does not remove or alter the rule itself. Avoid resetting counters that another operator is using for monitoring without agreeing the measurement window first.

5. Remove the test rule and recover

Removal is another live change. If the rule is still number 1 and the chain has not moved on, delete it by number:

$ sudo ebtables-nft -D FORWARD 1
$ sudo ebtables-nft -L FORWARD --Ln --Lc

Numbered deletion is easy to get wrong once another rule has been inserted ahead of it. On a shared or changing table, list the chain first and confirm the number immediately before deleting. The manpage also allows deleting by specifying the whole rule, which removes the first match:

$ sudo ebtables-nft -D FORWARD \
    -i BRIDGE_PORT \
    -p IPv4 \
    -d 02:00:00:00:00:42 \
    -j DROP
  • Verify the rule is gone.
  • Do not reach for -F as a shortcut if the original table had a non-default policy or other rules: flushing removes every rule from the selected chain, or every chain when none is named, and it does not touch the chain policy.
  • --init-table is not an undo button either, unless your recorded baseline is known to be the true starting state: it replaces the current table data outright.

Deleting a rule does not restore traffic that another rule is still dropping, and it does not undo a separate change you made in nat or broute. Reverse those explicitly if you touched a policy or created a user-defined chain during a larger task. A user-defined chain cannot be deleted while rules still jump to it.

6. Know the boundaries before expanding the rule

Use --help to see which extensions this userspace program actually offers:

$ ebtables-nft -h list_extensions

Match extensions load dynamically from the ebtables userspace tool, so the syntax skips iptables' separate -m option. Common documented matches cover source and destination MAC addresses, interface names, ARP fields, IPv4 and IPv6 fields, VLAN tags, STP fields, packet type and rate limits. Build one match at a time and check its listing before you combine several conditions.

The nft-based build does not implement the old atomic options such as --atomic-save and --atomic-commit, and the supplied manpage says the string match is unsupported. Do not lift a legacy ebtables script and assume those still exist. For anything persistent, store and review a complete --Lx representation through the host's normal firewall configuration process, then test restoration separately.

Done means

  • Confirmed the port and MAC from this host, not from an example.
  • Captured the existing table before changing it.
  • Placed the rule correctly, in the intended chain with the intended match fields.
  • Checked pcnt and bcnt after controlled traffic.
  • Removed the temporary rule and confirmed it is absent.
  • Left unrelated rules alone and skipped the unsupported atomic options.