Bridging with the Raspberry Pi

Intro
Now I’m into playing with networking stuff on the Pi. So for a small investment I got a USB to ethernet adapter – $25 from Amazon. My first few experiments with it – turning it into a bridge – were largely successful.

The details
You need the bridge-utils package:

$ sudo apt-get install bridge-utils

For me it was easiest to connect to my Pi via the Wifi adapter I have on it (see this post describing how I used that to make a router). Then I could blow up the wired ethernet without disrupting my connection.

The first thing I noticed after plugging in the adapter is that it was automagically recognized and, for instance, the ifconfig -a command now shows an eth1 device. So no device driver needed to be installed, which was pretty sweet.

Listing the USB devices now looks like this:

$ lsusb

Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 0b95:1780 ASIX Electronics Corp. AX88178
Bus 001 Device 005: ID 7392:7811 Edimax Technology Co., Ltd EW-7811Un 802.11n Wireless Adapter [Realtek RTL8188CUS]

In short I want to take my two wired ports, eth0 and eth1, bridge them and send real traffic through them to see what happens. Bridging here means connecting two separate networks at a layer-2 level, so MAC addresses are proxied through the bridge and layer-3 communications occur transparently over the bridge as if it weren’t even there.

So…

$ sudo brctl addbr br0

creates a bridge named br0.

$ sudo brctl addif br0 eth0
$ sudo brctl addif br0 eth1

Adds those two physical ports to the bridge.

By the way I got all this from this reliable Linux Foundation source.

Now if I got it right, I should be able to unplug any wired device and put the Pi in between the switch and the device, no matter what its network is!

So I plugged my PC into one port, the other port into the switch the PC had been plugged into, and…

Well, for instance, showmacs output looks like this:

$ sudo brctl showmacs br0

port no mac addr                is local?       ageing timer
  1     00:00:00:0c:c8:1f       no                 1.30
  1     00:01:00:02:c8:1f       no               197.23
  2     00:02:cf:80:cc:99       no                 0.07
  2     00:90:a9:bb:3d:76       no                 0.94
  1     5e:00:00:fb:c8:1f       no               134.11
  1     5e:00:00:fd:c8:1f       no                57.49
  1     5e:7f:ff:fa:c8:1f       no                29.55
  2     64:66:b3:3b:bd:51       no                12.34
  1     8c:ae:4c:ff:27:69       yes                0.00
  2     b8:27:eb:dd:21:03       yes                0.00
  1     c8:1f:66:00:63:fe       no                 0.15

00:02:cf:80:cc:99 belongs to my upstream router, which is plugged into eth0, so I conclude that port 2 is eth0 and port 1 must be eth1. Maybe the port number was determined by the order in which I added the interface to the bridge?

Then I ran speedtest on my PC – there was no measurable slowdown in speed.

I loaded up the Pi with a cpu-intensive job:

$ yes > /dev/null

and re-ran speedtest. Still no hit to performance.

A brief review
I don’t think everyone will have appreciated what we’ve accomplished so let me review. We have created a passive, stealth man-in-the-middle (MITM) device with a management interface!

There are lots of uses for that, some not so noble. A more nefarious usage would be to connect up to a device and record all traffic passing back and forth to it (tcpdump -i br0). But there are also lots of good things we can achieve as well. For instance, Intrusion Detection System or Intrusion Prevention System (IDS/IPS). Firewall. Transparent proxy filter. IDS/IPS may be possible with Snort. I have to ask one of my security pals if that’s still the popular open source choice for IPS. Five years ago it was the package of choice.

What’s on my plate
Now I’d like to tinker with the Pi so that I can in fact slow down traffic and emulate slower connections! But I don’t know how yet…

I need to show how to make the bridging permanent using /etc/network/interfaces file.

To be continued…

This entry was posted in Admin, Network Technologies, Raspberry Pi, Security and tagged , , . Bookmark the permalink.

5 Responses to Bridging with the Raspberry Pi

  1. Marc Ilgen says:

    I’m actually trying to do something similar, and I’m not sure how to go about it. Can I ask some questions? Suppose I want to create a layer 2 bridge on a Raspberry Pi (or Banana Pi) that passes all traffic between the native ethernet port and a second ethernot port that uses a USB to ethernet adapter. I think this is what you did right? Did you first have to install this device behind your router so that it was assigned its own internal IP address (say 192.168.1.x)? What if I wanted to set this up so that it was located between my modem and my router? Since it is now outside the router, would the bridge still function properly? Would it still have an IP address if it were located between modem and router?

    • john says:

      Well, since bridging works at layer 2, the physical layer, what you are trying to do should work, assuming the layer 2 protocol between the modem and router is ethernet. It is a bit confusing. I would pop a WiFi dongle on that Pi to give it an addressable IP for out-of-band management.

      Don’t use Banana Pis – they burn up! Get a Raspberry Pi 2 instead.

  2. Carlito says:

    Hi John,

    I am also trying to implement what Marc is doing. I have:
    modem -> Pi (eth0 + eth1 = br0) -> routes -> rest of my devices.

    I followed your linux foundation link and ended up with this /etc/network/interfaces files:


    auto lo br0

    iface lo inet loopback

    iface eth0 inet manual
    iface eth1 inet manual

    iface br0 inet static
    bridge_ports eth0 eth1
    address 192.168.3.1
    netmask 255.255.255.0

    Questions:
    1. does my interfaces look ok?
    2. when I do route -n I get 169.25.0.0 for both eth0 and eth1 (this is called zeroconf according to google :) ). How do I get rid of them?
    3. In this setup how can I automatically provide my own DNS servers only to the routers ? Currently ISP's DHCP servers are providing it but I want to provide my own DNS server.

    Thanks a bunch for taking the time!

  3. Eric says:

    Hi John, thank you for yout tutorial!

    I had to perform the following command for the br0 interface to show up and actually work: sudo ifconfig br0 up

    I did this on a Raspberry Pi 4 with its embedded interface as eth0 and a USB ethernet interface as eth1.

    So simple and quick, thanks!

  4. Danal Estes says:

    Thank you for the tutorial. This is fairly easy to combine with network name spaces. Example on a Pi with built in Ether and two USB ether: (these will all need sudo if not run from rc.local)

    # First, define the namespaces themselves
    ip netns add if_2GHz
    ip netns add if_5GHz
    ip netns add if_lan
    ip netns add if_bridge

    # Then, move the interfaces
    # Second USB ether
    ip link set eth2 netns if_bridge
    # First USB ether
    ip link set eth1 netns if_bridge
    # Build the bridge
    ip netns exec if_bridge brctl addbr br0
    ip netns exec if_bridge brctl addif br0 eth2
    ip netns exec if_bridge brctl addif br0 eth1

    # Built in Ether
    ip link set eth0 netns if_lan
    ip netns exec if_lan ifconfig eth0 192.168.7.240
    ip netns exec if_lan route add default gw 192.168.7.1

    Result:
    sudo ip netns exec if_bridge bash
    root@netm:/home/pi/netm# sudo brctl show br0
    bridge name bridge id STP enabled interfaces
    br0 8000.d037457c94ae no eth1
    eth2
    root@netm:/home/pi/netm# ip link list
    1: lo: mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    2: br0: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether d0:37:45:7c:94:ae brd ff:ff:ff:ff:ff:ff
    3: eth1: mtu 1500 qdisc noop master br0 state DOWN mode DEFAULT group default qlen 1000
    link/ether d0:37:45:87:ed:38 brd ff:ff:ff:ff:ff:ff
    4: eth2: mtu 1500 qdisc noop master br0 state DOWN mode DEFAULT group default qlen 1000
    link/ether d0:37:45:7c:94:ae brd ff:ff:ff:ff:ff:ff

Leave a Reply

Your email address will not be published. Required fields are marked *