While standard packet filters like iptables and nftables operate primarily at the network and transport layers (Layer 3 and Layer 4 of the OSI model), virtualised hypervisors, container bridges, and software-defined switches frequently require filtering at the Data Link layer (Layer 2). The ebtables utility provides packet-filtering capabilities for transparent Linux Ethernet bridges. By inspecting raw Ethernet frames as they transit software bridge ports (such as br0 or KVM/QEMU tap interfaces), administrators can block rogue DHCP servers, prevent ARP spoofing attacks, enforce MAC address whitelists, and filter 802.1Q VLAN tags before frames reach upper-layer IP routing stacks in Ubuntu.
Understanding Linux Bridge Filtering and ebtables Tables
When multiple network interfaces or virtual tap devices are aggregated into a Linux bridge, packets are forwarded based on destination MAC addresses stored in the bridge forwarding database (FDB). The ebtables kernel module intercepts frames across three distinct built-in tables:
- filter (default): Contains the
INPUT(frames destined for the local host bridge),OUTPUT(locally originated frames), andFORWARD(frames passing between two bridged slave interfaces) chains. - nat: Used for Layer 2 frame alteration, containing
PREROUTING,OUTPUT, andPOSTROUTINGchains. Supports Source MAC (snat) and Destination MAC (dnat) modifications. - broute: The bridge routing table. Allows administrators to decide whether a received frame should be bridged across slave ports or forwarded up to the Layer 3 IP routing table.
Installing ebtables and Kernel Modules on Ubuntu
Modern Ubuntu installations (including Ubuntu 22.04 LTS and 24.04 LTS) include ebtables-nft as a compatibility layer on top of the modern nftables framework, alongside native kernel bridging modules.
Install the package using apt:
sudo apt update && sudo apt install -y ebtables bridge-utils
Verify that bridge netfilter support is loaded into the Linux kernel:
sudo modprobe br_netfilter
lsmod | grep br_netfilter
To ensure bridge traffic does not inadvertently bypass iptables or ebtables rules, configure sysctl parameters:
sudo sysctl -w net.bridge.bridge-nf-call-iptables=1
sudo sysctl -w net.bridge.bridge-nf-call-arptables=1
Inspecting Current Bridge Rules
To inspect active rules within the default filter table, execute:
sudo ebtables -L --Lc --Ln
The --Lc flag displays packet and byte counters, while --Ln prints line numbers for precise rule management. To inspect rules across the NAT or broute tables, supply the -t switch:
sudo ebtables -t nat -L
sudo ebtables -t broute -L
Filtering Frames by MAC Address and Interface
A frequent security requirement in virtualised hosting environments is restricting guest VMs to their assigned Layer 2 hardware address, preventing guest-level MAC address spoofing.
To drop all frames originating from a specific virtual interface (e.g. vnet0) where the source MAC does not match the provisioned address:
# Drop spoofed source MAC addresses on bridge interface
sudo ebtables -A FORWARD -i vnet0 -s ! 52:54:00:12:34:56 -j DROP
To allow only a specific list of MAC addresses to communicate across the bridge and drop all other unrecognised hardware addresses:
# Change default policy of FORWARD chain to DROP
sudo ebtables -P FORWARD DROP
# Permit legitimate hosts
sudo ebtables -A FORWARD -s 52:54:00:12:34:56 -j ACCEPT
sudo ebtables -A FORWARD -d 52:54:00:12:34:56 -j ACCEPT
Blocking Rogue DHCP Servers on Bridged Networks
When multiple virtual machines or client devices share a common broadcast domain, an unauthoritative machine can disrupt network operations by advertising invalid DHCP leases. Block rogue DHCP offer and ACK packets originating from untrusted bridge ports:
# Drop DHCP replies (UDP port 67/68) from untrusted slave interface vnet1
sudo ebtables -A FORWARD -i vnet1 -p IPv4 --ip-proto udp --ip-sport 67 -j DROP
Filtering 802.1Q VLAN Tags and ARP Protocols
To prevent VLAN hopping or drop unencapsulated frames, ebtables can inspect 802.1Q Ethernet headers:
# Drop frames carrying VLAN ID 100 on interface eth1
sudo ebtables -A FORWARD -i eth1 -p 802_1Q --vlan-id 100 -j DROP
Similarly, mitigate ARP cache poisoning by preventing ARP replies containing falsified sender IP addresses:
# Prevent IP spoofing in ARP payloads
sudo ebtables -A FORWARD -p ARP --arp-ip-src ! 192.168.10.50 -i vnet0 -j DROP
Persisting ebtables Rules Across System Reboots
To ensure Layer 2 rules survive reboots, save the active configuration to the standard persistence file:
sudo ebtables-save | sudo tee /etc/ebtables.rules
Restore the rules automatically upon network activation using a systemd service:
sudo nano /etc/systemd/system/ebtables-restore.service
Add the following service configuration:
[Unit]
Description=Restore ebtables rules
Before=network-pre.target
Wants=network-pre.target
[Service]
Type=oneshot
ExecStart=/sbin/ebtables-restore /etc/ebtables.rules
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Enable the persistence unit:
sudo systemctl daemon-reload
sudo systemctl enable ebtables-restore.service
Deploying ebtables on Ubuntu bridges establishes deterministic Layer 2 security boundaries, isolating virtual guests and preserving hardware integrity across enterprise virtualisation clusters.