User Tools

Site Tools


computing:classic-bridging

This is an old revision of the document!



  • classic-bridging
  • Jonathan Haack
  • Haack's Networking
  • webmaster@haacksnetworking.org

classic-bridging


Introduction

This tutorial is for Debian users who want to create network bridges, or virtual switches, on production hosts. By production hosts, I mean something that’s designed to run virtual appliances (VMs, containers, etc.).

This tutorial assumes you have access to PTR records and/or have a block of external IPs.

In this tutorial, I’ll break down two differing setups I use. To be clear, the tutorial is about much more than bridging — it’s just that the bridges are the most important part because they route incoming traffic to the appliances.

The first setup is at Brown Rice (co-located server). The second setup is at Pebble Host (dedicated host — actual hardware provisioned on your behalf).

Here are the technical specifications for each host:

  • Brown RiceGreen Datacenter: Super Micro (Xeon Silver), 384GB RAM, 10.4TB zfs R10 JBOD (Co-Located)
  • Pebble HostDedicated Hosting: Ryzen 7 8700G, 64GB RAM, 2TB NVME

I prefer to use virsh + qemu/kvm on the physical (bare metal) host.

For my machine in Taos, I run the Debian host OS on a separate SSD on a dedicated SATA port that’s not part of the SAS back-plane. At Pebble, I don’t have this luxury; everything runs on the boot volume. This limitation fits the use-case, however, as I only have Pebble setup to run 5-7 virtual appliances, while the server co-located at Brown Rice has upwards of 30 virtual appliances.

Each location has a different set of requirements due to how they broadcast IP/prefixes, whether they filter traffic or not, and how they allocate IPs.

Brown Rice treats the prefixes/blocks they provide as public and, according to that logic, everything is open and exposed. The onus of responsibility rests exclusively on the client.

Pebble Host, on the other hand, serves over 50K clients. MAC address filtering becomes practically necessary due to potential conflicts within vendor OUIs (especially virsh). Filtering is also done for security, compliance, accountability, etc.

Brown Rice Setup

The SuperMicro has a built-in 10Gbps NIC, with 4 ports and 1 IPMI port.

Before we start tinkering with the operating system on the host, we need to establish A, AAAA, SPF, DMARC, and PTR records for the host. After that, we will setup IPMI access in the SuperMicro’s BIOS.

At Brown Rice, my machine has four cables plugged in, allocated as follows:

  • Interface 01 — enp1s0f0, dedicated cable (IPv4) just for the physical host
  • Interface 02 — enp1s0f1, dedicated cable (IPv4) just for bridging IPv4
  • Interface 03 — enp2s0f0, separate cable (IPv6) just for bridging IPv6
  • Interface 04 — enp2s0f1, empty
  • Interface 05 — IPMI; setup via American Megatrends BIOS, access is source-IP restricted

To setup IPMI, boot the production host and enter the BIOS (American Megatrends on this vintage SuperMicro). Configure:

  • Network interface
  • Turn off non-essential services
  • Create source-IP firewall rule to limit IPMI access

After configuring the network interface and hardening (disable ssh, iKVM, Virtual Media, SNMP unless needed), add source IP whitelist rules (DROP everything else at the end).

Use a small VPS + SOCKS proxy (e.g. ssh -D 8080 to VPS + FoxyProxy) to appear from an approved IP when accessing the firewalled IPMI panel.

NOTE: Self-signed TLS certificate is acceptable given the source IP restrictions and hardening.

Your primary DNS records (A/AAAA/SPF/DMARC) and PTR (IPv4 via panel, IPv6 via email request) should already be set up.

Now install Debian without NetworkManager (core utilities only). Remove it if already present:

sudo apt remove --purge NetworkManager

Configure primary interface in /etc/network/interfaces:

auto enp1s0f0
iface enp1s0f0 inet static
        address 8.28.86.100
        netmask 255.255.255.0
        gateway 8.28.86.1
        nameservers 8.8.8.8
sudo systemctl restart networking
ping4 google.com

Raise dedicated bridge interfaces (no address):

# bridge ipv4
auto enp1s0f1
iface enp1s0f1 inet manual
 
# bridge ipv6
auto enp2s0f0
iface enp2s0f0 inet6 manual

Install bridge-utils and create bridge:

sudo apt install bridge-utils
brctl addbr br0

Configure bridge (IPv6 only on bridge, since IPv4 host address already exists on primary interface):

auto br0
iface br0 inet6 static
        address 2602:fb41:0:11::2/64
        gateway 2602:fb41:0:11::1
        bridge_ports enp1s0f1 enp2s0f0
        accept_ra 2
        bridge_stp off
        bridge_fd 0
sudo systemctl restart networking
ping6 google.com
ping4 google.com     # double-check IPv4 still works

(Continue with UFW firewall setup, virt-install / preseed for VMs, connecting them to br0, etc. — as described in the original article.)

Pebble Host Setup

(One NIC — enp4s0 — handles both IPv4 and IPv6.)

Pebble requires VMAC (specific virtual MAC addresses) for VMs to pass their traffic filtering.

Create bridge with same MAC as physical interface:

auto br0
iface br0 inet static
        address 45.143.197.68
        netmask 255.255.255.192
        gateway 45.143.197.65
        bridge_ports enp4s0
        bridge_stp off
        bridge_fd 0
        hwaddress ether xx:xx:xx:xx:xx:xx   # <-- same MAC as enp4s0
 
iface br0 inet6 static
        address 2a10:e780:11:15::4/64
        gateway 2a10:e780:11:15::1

Additional static routes may be needed for routed blocks.

VMs connected to br0 must use an approved VMAC in their config (virt-install / libvirt XML).

Closing Notes

Both setups rely on classic /etc/network/interfaces + bridge-utils (not NetworkManager, not systemd-networkd bridges in this case).

Bridges act as virtual switches, passing traffic directly to VMs with public IPs.

Security differs greatly: open exposure at Brown Rice vs. MAC filtering + restrictions at Pebble.

Use preseed + virt-install scripts for fast, repeatable VM deployment.

If you run into issues or want to discuss variations, feel free to reach out on Matrix:

oemb1905 2025/11/09 03:07

computing/classic-bridging.1768065925.txt.gz · Last modified: by oemb1905