funwithlinux guide

Setting Up a Transparent Bridge Firewall using iptables

A **transparent bridge firewall** is a network security device that operates at Layer 2 (Data Link Layer) of the OSI model, functioning as an invisible "filter" between two network segments (e.g., LAN and WAN). Unlike traditional routers or firewalls, it does not require an IP address on its bridge interfaces, making it undetectable to the network. This makes it ideal for scenarios where you want to secure a network without reconfiguring existing IP addresses, gateways, or DNS settings—common in enterprise environments, small offices, or home labs. In this guide, we will walk through setting up a transparent bridge firewall using Linux and `iptables`, a powerful command-line tool for managing network rules. By the end, you will have a functional firewall that filters traffic between two network segments while remaining "invisible" to connected devices.

Table of Contents

  1. Prerequisites
  2. Understanding the Network Topology
  3. Step 1: Prepare the System
  4. Step 2: Configure the Linux Bridge
  5. Step 3: Enable Bridge-Netfilter (bridge-nf) Support
  6. Step 4: Configure iptables Rules for the Bridge
  7. Step 5: Test the Firewall
  8. Step 6: Persist Configurations Across Reboots
  9. Troubleshooting Common Issues
  10. Conclusion
  11. References

Prerequisites

Before starting, ensure you have the following:

  • A Linux Machine: Any modern Linux distribution (e.g., Ubuntu 22.04, Debian 12, CentOS Stream 9). We will use Ubuntu 22.04 for examples.
  • Two Network Interfaces: The firewall needs at least two physical Ethernet ports (e.g., eth0 and eth1) to bridge between LAN and WAN.
  • Root Access: You will need sudo or root privileges to modify system settings.
  • Basic Networking Knowledge: Familiarity with IP addresses, subnets, and iptables will help, but we will explain key concepts.

Understanding the Network Topology

A transparent bridge firewall sits in-line between two network segments (e.g., your local LAN and the internet/WAN). Unlike a router, it does not act as a gateway—devices on the LAN continue using their original gateway (e.g., your ISP router) for internet access. The bridge simply filters traffic passing between the segments.

Example Topology:

[LAN Devices (PCs, Servers)] <--> [eth0] Firewall [eth1] <--> [ISP Router/WAN]  
  • eth0: Connects to the LAN switch.
  • eth1: Connects to the WAN (e.g., ISP router).
  • br0: The Linux bridge interface that bonds eth0 and eth1, enabling traffic to flow between them.

Step 1: Prepare the System

First, update your system and install required tools for bridge configuration and firewall management:

Install Dependencies

sudo apt update && sudo apt upgrade -y  
sudo apt install -y bridge-utils iptables iptables-persistent  
  • bridge-utils: Tools to manage Linux bridges (e.g., brctl).
  • iptables: The firewall utility.
  • iptables-persistent: Saves iptables rules across reboots.

Step 2: Configure the Linux Bridge

A Linux bridge (br0) will bond eth0 and eth1, allowing traffic to flow between the LAN and WAN. We will configure the bridge manually (NetworkManager may interfere, so we disable it for the interfaces).

Step 2.1: Disable NetworkManager for Bridge Interfaces

NetworkManager can override manual bridge settings. Disable it for eth0 and eth1:

# Create a NetworkManager config file to ignore eth0 and eth1  
sudo tee /etc/NetworkManager/conf.d/bridge.conf <<EOF  
[keyfile]  
unmanaged-devices=interface-name:eth0;interface-name:eth1  
EOF  

# Restart NetworkManager  
sudo systemctl restart NetworkManager  

Step 2.2: Configure the Bridge Interface

Edit /etc/network/interfaces to define the bridge and physical interfaces. Replace eth0 and eth1 with your actual interface names (check with ip link show).

sudo nano /etc/network/interfaces  

Add the following configuration:

# Disable IP addresses on physical interfaces  
auto eth0  
iface eth0 inet manual  
  up ip link set $IFACE promisc on  # Enable promiscuous mode for bridging  

auto eth1  
iface eth1 inet manual  
  up ip link set $IFACE promisc on  

# Define the bridge interface (br0)  
auto br0  
iface br0 inet manual  # No IP address (transparent mode); omit "manual" to add a management IP  
  bridge_ports eth0 eth1  # Bond eth0 and eth1  
  bridge_stp off  # Disable Spanning Tree Protocol (optional, for small networks)  
  bridge_fd 0     # No forward delay (optional)  
  bridge_maxwait 0  
  • Promiscuous Mode: Required for the bridge to forward all traffic (not just traffic destined for its MAC address).
  • Management IP (Optional): To manage the firewall via SSH, assign an IP to br0 by replacing inet manual with:
    iface br0 inet static  
      address 192.168.1.254/24  # LAN IP for management  
      gateway 192.168.1.1      # ISP router IP (if needed for internet access)  

Step 2.3: Apply Bridge Configuration

Restart the network to apply changes:

sudo systemctl restart networking  

Verify the bridge is active:

brctl show  

Output should look like this:

bridge name     bridge id               STP enabled     interfaces  
br0             8000.abcdef123456       no              eth0  
                                                        eth1  

Check interface status:

ip addr show eth0  
ip addr show eth1  
ip addr show br0  # No IP unless configured for management  

Step 3: Enable Bridge-Netfilter Support

By default, Linux bridges forward traffic at Layer 2 without involving iptables (Layer 3). To make iptables filter bridged traffic, enable bridge-nf (bridge netfilter) modules:

Temporarily Enable Bridge-NF

sudo sysctl -w net.bridge.bridge-nf-call-iptables=1   # IPv4  
sudo sysctl -w net.bridge.bridge-nf-call-ip6tables=1  # IPv6 (optional)  
sudo sysctl -w net.bridge.bridge-nf-call-arptables=1  # ARP (optional)  

Persist Bridge-NF Settings

To retain these settings after a reboot, create a sysctl config file:

sudo tee /etc/sysctl.d/bridge.conf <<EOF  
net.bridge.bridge-nf-call-iptables = 1  
net.bridge.bridge-nf-call-ip6tables = 1  
net.bridge.bridge-nf-call-arptables = 1  
EOF  

Load the new sysctl settings:

sudo sysctl -p /etc/sysctl.d/bridge.conf  

Step 4: Configure iptables Rules for the Bridge

Now we will define iptables rules to filter traffic passing through the bridge. We will start with a default-deny policy and explicitly allow necessary traffic.

Step 4.1: Reset Existing Rules

Clear any existing iptables rules to start fresh:

sudo iptables -F  # Flush all chains  
sudo iptables -X  # Delete custom chains  
sudo iptables -Z  # Zero packet/byte counters  

Step 4.2: Set Default Policies

Block all traffic by default, then allow specific rules:

sudo iptables -P INPUT DROP    # Block traffic to the firewall itself  
sudo iptables -P FORWARD DROP  # Block traffic passing through the bridge  
sudo iptables -P OUTPUT DROP   # Block traffic from the firewall itself  

Step 4.3: Allow Essential Traffic

1. Allow ARP (Critical for Layer 2 Communication)

ARP (Address Resolution Protocol) resolves IP addresses to MAC addresses. Blocking ARP will break LAN connectivity:

# Allow ARP requests and replies  
sudo iptables -A FORWARD -p arp --arp-op request -j ACCEPT  
sudo iptables -A FORWARD -p arp --arp-op reply -j ACCEPT  

2. Allow Established/Related Connections

Permit traffic for existing connections (e.g., a web browser session after the initial request):

sudo iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT  

3. Allow LAN-to-WAN Traffic (e.g., Web, Email)

Allow specific ports from the LAN (eth0) to the WAN (eth1). Adjust ports as needed:

# Allow HTTP (80) and HTTPS (443)  
sudo iptables -A FORWARD -i eth0 -o eth1 -p tcp --dport 80 -j ACCEPT  
sudo iptables -A FORWARD -i eth0 -o eth1 -p tcp --dport 443 -j ACCEPT  

# Allow DNS (53) for domain resolution  
sudo iptables -A FORWARD -i eth0 -o eth1 -p udp --dport 53 -j ACCEPT  
sudo iptables -A FORWARD -i eth0 -o eth1 -p tcp --dport 53 -j ACCEPT  

# Allow SSH (22) to WAN (optional, e.g., for remote server management)  
sudo iptables -A FORWARD -i eth0 -o eth1 -p tcp --dport 22 -j ACCEPT  
  • -i eth0 -o eth1: Traffic from LAN (eth0) to WAN (eth1).
  • Use -m physdev --physdev-in eth0 --physdev-out eth1 instead if interfaces might change names.

4. Block WAN-to-LAN Traffic (Default Deny)

The default FORWARD DROP policy already blocks unsolicited WAN-to-LAN traffic (e.g., port scans). To log blocked traffic (optional):

sudo iptables -A FORWARD -j LOG --log-prefix "BLOCKED FORWARD: " --log-level 4  

5. Allow Management Access (If br0 Has an IP)

If you assigned a management IP to br0 (Step 2.2), allow SSH access to the firewall:

# Allow SSH from LAN to firewall's management IP  
sudo iptables -A INPUT -i br0 -p tcp --dport 22 -j ACCEPT  

Step 4.4: Verify Rules

Check your iptables configuration:

sudo iptables -L -v --line-numbers  

The -v flag shows packet/byte counters, helping you debug traffic flow.

Step 5: Test the Firewall

Verify Connectivity

  1. Connect a LAN device (e.g., a PC) to the LAN switch (connected to eth0).
  2. Ensure the LAN device uses the original gateway (e.g., ISP router IP: 192.168.1.1).
  3. Test internet access: Open a browser and visit a website (e.g., https://google.com).
  4. Test blocked ports: Use telnet or nc to check if a blocked port (e.g., 23/Telnet) is denied:
    # On LAN PC:  
    telnet example.com 23  # Should fail (blocked by iptables)  

Debug with Tcpdump

Use tcpdump to monitor traffic on the bridge interfaces:

# Monitor HTTP traffic on eth0 (LAN)  
sudo tcpdump -i eth0 'port 80'  

# Monitor blocked traffic (if logging is enabled)  
tail -f /var/log/syslog | grep "BLOCKED FORWARD"  

Step 6: Persist Configurations

Save iptables Rules

iptables-persistent will save rules to /etc/iptables/rules.v4 (IPv4) and load them on boot:

sudo iptables-save | sudo tee /etc/iptables/rules.v4  
sudo systemctl enable iptables-persistent  

Verify Bridge Persistence

The bridge configuration in /etc/network/interfaces (Step 2.2) will persist across reboots. To confirm:

sudo reboot  
# After reboot:  
brctl show  
iptables -L  

Troubleshooting Common Issues

No Connectivity Between LAN and WAN

  • Check the Bridge: Ensure eth0 and eth1 are in br0 (brctl show).
  • Promiscuous Mode: Verify with ip link show eth0—look for PROMISC in the output.
  • Bridge-NF Settings: Confirm net.bridge.bridge-nf-call-iptables=1 with sysctl net.bridge.bridge-nf-call-iptables.
  • ARP Allowed: Ensure the ARP rules in iptables are present (iptables -L FORWARD).

iptables Not Blocking Traffic

  • Default Policy: Confirm FORWARD policy is DROP (iptables -L).
  • Rule Order: Rules are processed top-to-bottom. Ensure specific allow rules come before general deny rules.

Firewall Unreachable (Management IP)

  • INPUT Chain: If using a management IP, ensure INPUT chain allows SSH (Step 4.4).
  • Gateway: If the firewall needs internet access (e.g., for updates), add a default route:
    sudo ip route add default via 192.168.1.1 dev br0  # Replace with your gateway  

Conclusion

You have now set up a transparent bridge firewall using Linux and iptables. This firewall filters traffic between LAN and WAN without disrupting existing network configurations, making it ideal for securing legacy networks or environments where reconfiguring IPs is impractical.

Advanced Next Steps

  • IPv6 Support: Repeat the steps with ip6tables for IPv6 traffic.
  • QoS: Add traffic shaping with tc (traffic control) to prioritize critical traffic.
  • nftables: Migrate to nftables (the successor to iptables) for better performance.
  • Intrusion Detection: Integrate snort or suricata to detect malicious traffic.

References