dotlinux guide

How to Set Up a Network Bridge on Linux: A Comprehensive Guide

In modern networking, the ability to connect multiple network segments seamlessly is critical for virtualization, containerization, and software-defined networking (SDN). A network bridge is a Layer 2 (Data Link Layer) device that connects two or more network segments, forwarding Ethernet frames between them based on MAC addresses. Unlike routers, bridges operate at Layer 2 and do not route IP packets; instead, they create a single broadcast domain, making devices on the bridge appear as if they are on the same physical network. On Linux, network bridges are powerful tools used in scenarios like: - Virtualization (e.g., KVM, Proxmox, or VMware guests needing direct LAN access) - Container networking (e.g., Docker with macvlan or Kubernetes) - Creating software-defined switches - Bridging physical and virtual interfaces (e.g., Wi-Fi to Ethernet, with caveats) This guide will demystify network bridges, walk through step-by-step setup methods, and share best practices to ensure robust and reliable configurations.

Table of Contents

  1. Understanding Network Bridges
  2. Prerequisites
  3. Methods to Set Up a Network Bridge
  4. Common Use Cases
  5. Best Practices
  6. Troubleshooting
  7. Conclusion
  8. References

1. Understanding Network Bridges

A network bridge operates at the OSI Layer 2, forwarding Ethernet frames between connected interfaces based on MAC addresses. Key concepts:

  • MAC Address Learning: Bridges dynamically learn MAC addresses by monitoring incoming frames, storing them in a MAC address table (e.g., brctl showmacs br0).
  • Frame Forwarding: For known MAC addresses, frames are forwarded only to the target interface; unknown or broadcast frames are flooded to all interfaces (except the source).
  • Spanning Tree Protocol (STP): Prevents loops in networks with redundant bridges by disabling redundant paths. Enabled by default in most Linux bridges.
  • Broadcast Domain: All devices on a bridge share the same broadcast domain, meaning ARP requests and broadcasts reach all connected devices.

Bridges vs. Switches vs. Routers:

  • A bridge is a software-defined Layer 2 device (Linux bridges are software-based).
  • A switch is a hardware-based bridge (dedicated ASICs for faster forwarding).
  • A router operates at Layer 3, routing IP packets between different networks (broadcast domains).

2. Prerequisites

Before setting up a bridge, ensure:

  • A Linux system (tested on Ubuntu 22.04, CentOS Stream 9, and Debian 12).
  • Root/sudo access (use sudo -i or prefix commands with sudo).
  • At least one physical (e.g., eth0, enp0s3) or virtual (e.g., tap0, veth0) network interface.
  • Tools:
    • iproute2 (for ip and bridge commands; preinstalled on most systems).
    • bridge-utils (optional, for brctl; install with sudo apt install bridge-utils or sudo dnf install bridge-utils).
    • For persistent setups: systemd-networkd, netplan, or NetworkManager (depending on your distro).

3. Methods to Set Up a Network Bridge

3.1 Temporary Bridge (iproute2 Tools)

A temporary bridge is ideal for testing. It will persist until reboot or manual deletion.

Step 1: Check Existing Interfaces

List interfaces and their IPs:

ip addr show

Example output might show eth0 (physical interface) with an IP like 192.168.1.100/24.

Step 2: Create the Bridge

Create a bridge named br0 (name is arbitrary):

sudo ip link add name br0 type bridge

Step 3: Bring Up the Bridge

Activate the bridge:

sudo ip link set dev br0 up

Step 4: Add Interfaces to the Bridge

Add a physical interface (e.g., eth0) to the bridge. Note: The interface will lose its existing IP, as the bridge will handle IP addressing.

# Remove existing IP from eth0 (if any)
sudo ip addr flush dev eth0

# Add eth0 to br0
sudo ip link set dev eth0 master br0

# Ensure eth0 is up
sudo ip link set dev eth0 up

Step 5: Assign an IP to the Bridge

Give the bridge an IP (static or via DHCP). For DHCP:

sudo dhclient br0

For static IP (e.g., 192.168.1.100/24, gateway 192.168.1.1):

sudo ip addr add 192.168.1.100/24 dev br0
sudo ip route add default via 192.168.1.1 dev br0

Step 6: Verify the Bridge

Check bridge status:

# List bridges and enslaved interfaces
sudo bridge link show br0

# Show bridge details (including MAC table)
sudo bridge fdb show br0

# Check IP assignment
ip addr show br0

Cleanup (Optional)

To delete the temporary bridge:

sudo ip link set dev eth0 nomaster  # Remove eth0 from br0
sudo ip link set dev br0 down       # Bring down the bridge
sudo ip link delete dev br0         # Delete the bridge
# Restore IP to eth0 (if needed)
sudo dhclient eth0

3.2 Persistent Bridge with systemd-networkd

systemd-networkd is a lightweight network manager used in minimal distros (e.g., Debian Server, Fedora Server). Configurations are stored in /etc/systemd/network/.

Step 1: Disable Conflicting Services

If using NetworkManager or dhcpcd, disable them:

sudo systemctl disable --now NetworkManager dhcpcd

Step 2: Enable systemd-networkd

sudo systemctl enable --now systemd-networkd systemd-resolved
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf  # Use systemd-resolved for DNS

Step 3: Create Bridge Configuration

Create a bridge config file (e.g., /etc/systemd/network/br0.netdev):

[NetDev]
Name=br0
Kind=bridge

[Bridge]
STP=yes  # Enable Spanning Tree Protocol (default: yes)
ForwardDelay=2  # STP forwarding delay (seconds; default: 15)

Step 4: Configure Bridge IP

Create an IP config file for br0 (e.g., /etc/systemd/network/br0.network):

[Match]
Name=br0

[Network]
DHCP=yes  # Use DHCP (set to "no" for static IP)
# For static IP:
# Address=192.168.1.100/24
# Gateway=192.168.1.1
# DNS=8.8.8.8 8.8.4.4

Step 5: Configure Slave Interfaces

Create a config file for the physical interface (e.g., eth0, /etc/systemd/network/eth0.network):

[Match]
Name=eth0  # Replace with your interface

[Network]
Bridge=br0  # Attach eth0 to br0

Step 6: Apply Changes

Restart systemd-networkd and verify:

sudo systemctl restart systemd-networkd
ip addr show br0
sudo bridge link show br0  # Should list eth0 as a slave

3.3 Persistent Bridge with Netplan (Ubuntu/Debian)

Netplan is the default network configuration tool in Ubuntu 18.04+ and Debian 12+. It uses YAML files to define networks.

Step 1: Locate Netplan Config

Netplan files are in /etc/netplan/ (e.g., 00-installer-config.yaml).

Step 2: Edit the Config File

Backup the original file first:

sudo cp /etc/netplan/*.yaml /etc/netplan/backup.yaml

Edit the file (use nano or vim):

sudo nano /etc/netplan/00-installer-config.yaml

Step 3: Define the Bridge

Replace the existing configuration with:

network:
  version: 2
  renderer: networkd  # Use systemd-networkd (or "NetworkManager" for desktop)
  ethernets:
    eth0:  # Physical interface (no IP here)
      dhcp4: no  # Disable DHCP on eth0
  bridges:
    br0:  # Bridge name
      interfaces: [eth0]  # Interfaces to enslave
      dhcp4: yes  # Use DHCP for br0
      # For static IP:
      # addresses: [192.168.1.100/24]
      # routes:
      #   - to: default
      #     via: 192.168.1.1
      # nameservers:
      #   addresses: [8.8.8.8, 8.8.4.4]
      parameters:
        stp: true  # Enable STP (default: true)
        forward-delay: 2  # STP forwarding delay

Step 4: Apply the Configuration

sudo netplan generate  # Generate backend configs
sudo netplan apply     # Apply changes

Step 5: Verify

ip addr show br0
sudo bridge link show br0

3.4 Persistent Bridge with NetworkManager

NetworkManager is used in desktop distros (e.g., Ubuntu Desktop, Fedora Workstation). Use nmcli (CLI) or nmtui (TUI).

Step 1: Create a Bridge

sudo nmcli connection add type bridge ifname br0 con-name br0

Step 2: Configure Bridge Settings (STP, IP)

Enable STP (default: enabled) and set IP (DHCP or static):

# Enable STP (optional, default is yes)
sudo nmcli connection modify br0 bridge.stp yes

# Set DHCP (default)
sudo nmcli connection modify br0 ipv4.method auto

# Or set static IP:
# sudo nmcli connection modify br0 ipv4.method manual ipv4.addresses 192.168.1.100/24 ipv4.gateway 192.168.1.1 ipv4.dns "8.8.8.8,8.8.4.4"

Step 3: Add a Slave Interface

Attach a physical interface (e.g., eth0) to br0. First, delete any existing connection for eth0:

# List existing connections to find eth0's con-name (e.g., "Wired connection 1")
sudo nmcli connection show

# Delete eth0's connection (replace "Wired connection 1" with your con-name)
sudo nmcli connection delete "Wired connection 1"

# Add eth0 as a slave to br0
sudo nmcli connection add type bridge-slave ifname eth0 con-name br0-slave-eth0 master br0

Step 4: Activate the Bridge

sudo nmcli connection up br0
sudo nmcli connection up br0-slave-eth0

Step 5: Verify

nmcli connection show br0
ip addr show br0
sudo bridge link show br0

4. Common Use Cases

Virtualization (KVM/Proxmox)

Bridges allow VMs to appear as physical devices on the LAN. For KVM:

  • Create a bridge (e.g., br0) and attach the physical interface.
  • In VM XML configs, set the network interface to use bridge=br0.

Docker/Moby Containers

Use macvlan driver with a bridge to assign containers MAC addresses on the LAN:

docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=br0 my-macvlan-net

Software Switch

Bridge multiple physical interfaces to create a software-defined switch (e.g., connect eth0, eth1, and eth2 to br0 for a 3-port switch).

Bridging Wi-Fi (Caveats)

Bridging Wi-Fi is possible but limited:

  • Most Wi-Fi drivers do not support bridging with WPA/WPA2 (requires wpa_supplicant on the bridge, not the interface).
  • Use hostapd to create a Wi-Fi AP and bridge it to Ethernet (advanced).

5. Best Practices

  1. Use Persistent Configurations: Avoid temporary bridges for production; use systemd-networkd, Netplan, or NetworkManager.
  2. Disable Unneeded Services: If using systemd-networkd, disable NetworkManager to prevent conflicts.
  3. Enable STP for Redundant Bridges: If multiple bridges are connected (e.g., in a lab), STP prevents loops. Disable STP only in simple, single-bridge setups.
  4. Assign IP to the Bridge, Not Slaves: Slave interfaces (e.g., eth0) should have no IP; the bridge (br0) handles IP addressing.
  5. Use Static IP for Critical Bridges: For servers, avoid DHCP for bridges to prevent IP changes.
  6. Monitor Bridge Traffic: Use ip -s link show br0 to check packet counts and errors.
  7. Avoid Bridging Loopback: Never add lo (loopback) to a bridge; it can cause packet loops.
  8. Test with Temporary Bridges First: Validate configurations with iproute2 before making them persistent.

6. Troubleshooting

No Connectivity After Setup

  • Check Slave Interfaces: Ensure interfaces are enslaved and up:
    sudo bridge link show br0  # Should list interfaces as "state UP"
  • Verify IP on Bridge: The bridge must have an IP (check with ip addr show br0).
  • STP Blocking Ports: STP may temporarily block ports (30-60 seconds). Check with:
    sudo bridge monitor  # Watch for STP state changes
    sudo brctl showstp br0  # Show STP status per port
  • Firewall Rules: Ensure the bridge is allowed in iptables/nftables:
    sudo iptables -L  # Check for DROP rules blocking br0

Bridge Not Persisting After Reboot

  • systemd-networkd: Ensure .network files are in /etc/systemd/network/ and systemd-networkd is enabled.
  • Netplan: Validate YAML syntax with sudo netplan try (tests config without applying permanently).
  • NetworkManager: Ensure the bridge connection is set to “autoconnect”:
    sudo nmcli connection modify br0 connection.autoconnect yes

7. Conclusion

Network bridges are versatile tools for connecting network segments at Layer 2, enabling use cases like virtualization, container networking, and software-defined switching. Linux offers multiple methods to configure bridges, from temporary iproute2 setups for testing to persistent configurations with systemd-networkd, Netplan, or NetworkManager.

By following best practices—such as using static IPs, enabling STP for redundancy, and monitoring traffic—you can build robust, reliable bridge setups. Always test configurations in a non-production environment first, and refer to distribution-specific documentation for edge cases.

8. References