Admin Network Technologies Raspberry Pi Security

Bridging with the Raspberry Pi

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.


$ 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…

10 replies on “Bridging with the Raspberry Pi”

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?

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.

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

1. does my interfaces look ok?
2. when I do route -n I get 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!

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!

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
ip netns exec if_lan route add default gw

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
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

Would you expect Ethernet usage statistics to still work when bridging the 2 ports together or does routing need to be active to collect usage stats?

Well, I think layer 2 stuff like that will work. You of course would tailor your commands to the bridge device br0. But I lost that adapter and haven’t done a bridge in quite some time so I can’t test it.

Hi John,

This article helped a bit but surely the point is to boot a Raspberry Pi
and have it come up as a bridge? I went through some pain for this as if you didn’t have a RJ45 cable plugged into the bridging port then the boot time was very slow “Waiting for a Raise Network Interface” job to complete. Anyway I got it working with the following entries in /etc/network/interfaces.d:

file br0:
auto br0
iface br0 inet manual
bridge_ports none
# Allow 802.1x PAE packets
post-up echo 8 > /sys/class/net/br0/bridge/group_fwd_mask

eth0 (others eth1, eth2 essentially the same):
auto eth0
allow-hotplug eth0
iface eth0 inet manual
post-up brctl addif br0 eth0

Just spreading some (hopefully correct and at least tested) Raspberry Pi instructions!

Post should have a tab in the eth0 file before the post-up command. Something stripped this out when posting even though I did lt-tab-gt.

Hey it’s been awhile and I can’t remember why I really created this post. I must have had something concrete in mind. But anyway, thanks for the tip for making it work upon boot-up.

Leave a Reply

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