A Linux bridge is a very useful tool once you start getting heavily into virtualization. Combined with a Debian OpenVPN server, these advanced network concepts provide a powerful base for expansion. Virtual servers are great because they allow for separation of concerns. Additionally, a mistyped rm -rf is less fatal if it knocks out a single virtual “server” rather than the entire physical server.
Virtualization doesn’t stop at just servers. Virtual network stacks provide a plethora of advantages over completely hardware-based systems. Additionally, networks can be hybrids of both virtual and physical devices, creating a highly elastic and cost-effective system.
In this tutorial, we’re going to discuss one of several tools used to build virtual networks. Linux’s bridging functionality allows us to create a network segment within a single computer. Once we create it, we can attach physical and virtual devices to the segment. The network enables these devices to communicate between each other as if the network had a flat topology. This works regardless of the underlying infrastructure.
Bridges are roughly the same as switches. They both operate at layer 2 of the OSI model. This means that they forward packets based on MAC addresses rather than IPs. This provides the backbone upon which our layer 3 topology rests.
Let’s start with a basic example. I have a multi-homed server. I want this machine to act as a switch and transparently forward the packets received on one interface to the other interface and vice-versa. To accomplish this, we need to create a network bridge internally on the system. This bridge will have the two NICs added to it. It will then perform the forwarding we require.
Installation on Debian
Installing Linux Bridge Utilities
Begin by installing Linux’s bridge utilities. While the kernel itself contains the code which controls bridges, we’ll need a way to manage it. On Debian/Ubuntu, the command sudo apt install bridge-utils will do so. Once installed, we’re ready to start.
First, run sudo brctl show from the command line. This is the command which will show you a list of all the bridges currently configured on your system. we’ll be referencing this list at several points.
Creating a Linux Bridge
Now we’re ready to create our first bridge. To do so, run sudo brctl addbr TestBridge. Our bridge should now exist in the system. To confirm this, show the list of bridges on the system by typing sudo brctl show. You should see the new bridge listed similarly to the following:
Code language: CSS (css)
bridge name bridge id STP enabled interfaces TestBridge 8000.000000000000 no
Pay special attention to the section labelled “interfaces”. At the moment, our bridge is empty. Bridges support more than just physical interfaces. They can also have adapters from virtual machines and containers attached. In these instances, these interfaces behave exactly like their physical counterparts.
Adding Physical Interfaces to a Linux Bridge
In this example, our system has two physical interfaces, eth0 and eth1. For our purposes, both interfaces should be part of the bridge. To accomplish this, run sudo brctl addif TestBridge eth0. This adds the first Ethernet interface to the bridge.
When running sudo brctl show, you’ll notice that the output now looks like the following:
Code language: CSS (css)
bridge name bridge id STP enabled interfaces TestBridge 8000.000000000000 no eth0
Now we need to add the second interface. Run sudo brctl addif TestBridge eth1. At this point we’ve turned this server into a switch. The two interfaces forward packets for each other.
Configuring the system in this way allows us to add virtual hosts on to our network segment. Additionally, it also allows us to configure additional physical ports to later expand our network further. Adding a third NIC to the bridge allows us to further expand outward. A new host connected on this link could run additional virtual hosts. These systems would have IP addresses on the same network as our current two hosts.
Attaching Containers/VMs to a Linux Bridge
Let’s go a step further and integrate some basic virtual infrastructure into our network. Running a network in a hybrid configuration provides a great deal of additional utility. To keep this example simple, we’re going to run LXD containers on the same host performing the switching. I’ve previously written a Linux Containers introduction if you haven’t previously worked with this technology.
On Debian, you first need to install Canonical’s Snap package manager. To do so, run sudo apt install snapd. Once installed, run sudo snap install core lxd. This will pull down everything needed to run LXD.
Finally, run sudo lxd init. This will begin a basic setup process. For the purposes of this tutorial, stick to the defaults.
Creating a Container
We’re ready to begin. First, run sudo lxc launch images:debian/10 TestContainer. This will create our first container. Run sudo lxc ls to verify this. You should see TestContainer appear in the results.
LXD’s default profile automatically assigns one NIC to each container. This NIC connects to lxdbr0, the bridge created by LXD during the configuration process. We will now reconnect this NIC to the bridge we created earlier. Doing so allows it to communicate with the physical hosts on this network as if it was a physical host itself.
Adjusting the NIC
To make this change, run sudo lxc config edit TestContainer. This command will pull up your system’s text editor and allow you to modify the configuration of the container. Within this file, locate the section labelled “devices”. Within this, there is an eth1 device. Change the NIC’s parent from lxdbr0 to TestBridge. Once done, save the file and close it. Your container is now on the bridge.
Setting the IP Address
Now, we need to configure a static IP address within this container. To do so, run sudo lxc exec TestContainer bash. This drops you to a root prompt within the container. From there, modify /etc/network/interfaces as follows:
Code language: CSS (css)
auto eth1 iface eth1 inet static address 172.16.1.3 netmask 255.255.255.0 gateway 172.16.1.1
Run sudo systemctl restart networking within the container. This restarts the networking daemon and assign the static IP address to it. Your container is now accessible from the two physical hosts on your network.
There’s much more to Linux bridges and software defined networking as a whole. In future tutorials I will cover OpenVSwitch and how software defined networking technologies build large-scale production networks. Additionally I will discuss how these technologies come together to form cloud infrastructures such as OpenStack.