building a raspberry pi network tap/bridge
What’s a network tap?
A network tap is a device that is typically placed between two endpoints on a network to ‘tap into the wire’ and sniff/intercept the traffic passing by. All packets are forwarded to their intended destination so that there is no disruption of connectivity. Network taps are meant to be ‘invisible’ on the network and not modify the traffic in any way, since they are usually used to perform troubleshooting or analysis.
A typical Ethernet tap has three ports: two for bridging the two endpoints and one for monitoring. The latter is where the person performing the traffic analysis plugs in and is able to see the traffic moving between the other two interfaces.
Endpoint Bridge Ports
Since the Pi has only one Ethernet port it was necessary to add at least another. The only solution was to use a USB-to-Ethernet adapter, which luckily I had. In any case, they’re relatively cheap and easy to find.
Since a tap is supposed to be invisible on the network, I needed to have the interfaces configured so that the device could be dropped between any two network endpoints and begin forwarding traffic with little-to-no additional configuration. I decided to create a bridge interface to bridge both Ethernet ports and configure the bridge to be setup via DHCP, since it’s the least likely to cause problems.
NOTE: It is important to note that the on-board Ethernet uses the USB bus to transfer data. This means both NICs will be sharing a single bus while transferring data. This will likely lead to packet loss and degrade performance, but for my simple purposes this was acceptable.
Usually there is a third Ethernet port to serve as the monitor port, but I didn’t want to add another external device to minimize power consumption and overhead on the USB bus. Since there is a wireless NIC available, I decided I would use that as make-shift monitor port.
To accomplish this, I decided to configure it to operate as an access point and set up an SSH server on the Pi. This way I could connect via WiFi, login via SSH, and monitor the traffic directly from the Pi.
Putting It All Together
This will be the tutorial part of this post where you can follow along to build your own Raspberru Pi network tap. This tutorial assumes you’re comfortable working in the terminal since everything below will be done on the command-line. It also assumes you know how to install Raspbian to an SD card for use in a Pi.
Here’s a quick overview of the setup:
- Raspberry Pi3
- 16GB high-speed microSD storage
- USB-to-Ethernet adapter
Note: You will need to have a display and keyboard connected to the Pi for the initial configuration.
Configure Raspbian and Update
Once Raspbian was installed and I had booted into the OS, there were a few configuration changes that were necessary. This is all made very simple on Raspbian via the
raspi-config script. This gives a nice menu in the terminal for configuring the system and enabling/disabling services.
These are some of the settings I modified that you may also want to change.
- Expand Filesystem (definitely do this!)
- Internationalization options:
- Change locale: en_US.UTF8 (for most people in the US)
- Change timezone
- Change keyboard layout: English US (again, most in the US)
- Change WIFI Country: US (once again…)
- Internationalization options:
Note that Raspbian does not come with a US keyboard layout or locale enabled by default, so you will have to change those to the appropriate settings before continuing to avoid potential issues is you’re in the US. Don’t change the default password from the raspi-config menu before setting your appropriate keyboard layout and rebooting, especially if you use symbols in your password. You’ll probably lock yourself out of the system. Once the correct settings have been configured and you have rebooted, do change the default password for the
After making these changes, I updated the system.
$ sudo apt-get update && sudo apt-get upgrade
Configure the Wireless AP + SSH
Next, I set up the the wireless interface(
wlan0) to serve as an access point using
wlan0 IP settings
I started by configuring
wlan0 with static IP settings. I saved a copy of ‘/etc/network/interfaces’ as ‘interfaces.orig’ to preserve the default settings and edited the original file. I commented out the existing block for
wlan0 and added these settings:
iface wlan0 inet static address 10.0.1.1 network 10.0.1.0 netmask 255.255.255.0 broadcast 10.0.1.255
I restarted the network to apply the changes (this can also be done via reboot):
$ sudo /etc/init.d/networking restart
Install and configure hostapd + dnsmasq
hostapd is used to turn the wireless interface into an access point and
dnsmasq will serve IP addresses to clients via DHCP.
I began by installing both tools:
$ sudo apt-get install hostapd dnsmasq
I created a config file for
hostapd with these settings and saved it at ‘/etc/hostapd/hostapd.conf’.
# wireless interface to create access point interface=wlan0 # driver for the built-in wifi in the Pi driver=nl80211 # SSID ssid=berry-sensor # Use the 2.4GHz band hw_mode=g # Channel to use channel=1 # Required settings for built-in wireless ieee80211n=1 wmm_enabled=1 ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40] # Accept all MAC addresses macaddr_acl=0 # Use WPA authentication auth_algs=1 # Require clients to know the network name ignore_broadcast_ssid=0 # Use WPA2 wpa=2 # Use a pre-shared key wpa_key_mgmt=WPA-PSK # The network passphrase (this is just an example, make sure to change this) wpa_passphrase=raspberry # Use AES, instead of TKIP rsn_pairwise=CCMP
Next, I edited ‘/etc/default/hostapd’ and uncommented the following line and pointed it to the config file I had created.
Finally, I enabled the
hostapd service so that it is started at boot.
$ sudo systemctl enable hostapd
Next, I renamed the default
dnsmasq configuration file at ‘/etc/dnsmasq.conf’ to ‘dnsmasq.conf.orig’ to preserve the original settings. I created a new file with the following settings where the default config file used to be (‘/etc/dnsmasq.conf’).
interface=wlan0 # Use interface wlan0 listen-address=10.0.1.1 # Explicitly specify the address to listen on bind-interfaces # Bind to the interface to make sure we aren't sending things elsewhere domain-needed # Don't forward short names bogus-priv # Never forward addresses in the non-routed address spaces. dhcp-range=10.0.1.2,10.0.1.16,6h # DHCP range settings
Note:These IP addresses should match the settings used to configure the static IP settings of the wireless interface.
Finally, I enabled the
dnsmasq service so that it is started at boot.
$ sudo systemctl enable dnsmasq
Enable the SSH server
At this point, I enabled SSH on the Pi so that I could access it once I had connected as a wireless client. I did this via the menus provided by
raspi-config under Advanced Options>SSH.
Once everything had been configured, I rebooted the Pi so that all settings would be applied and the services would be started. I was able to associate with the AP and ssh into the Pi.
Configure the Ethernet NICs
The final step was to create a bridge interface to bridge the two Ethernet interfaces. This way the bridge interface can be monitored directly and traffic is forwarded automatically. The bridge interface is configured via dhcp, though this can be changed to static settings easily to match the network’s configuration.
I connected the USB-to-Ethernet adapter and proceeded.
Creating the Bridge Interface
I began by installing
bridge-utils to create the bridge interface.
$ sudo apt-get install bridge-utils
Next, I edited ‘/etc/network/interfaces’ to add an entry for the new bridge interface (
br0) and disable the existing entry for
eth0 and the new
eth1 interface, since the
br0 will bring up the interfaces it is assigned.
This was my final ‘/etc/network/interfaces’ file, with the settings for the wireless interface from before included:
# /etc/network/interfaces # loopback interface auto lo iface lo inet loopback # wireless AP interface allow-hotplug wlan0 iface wlan0 inet static address 10.0.1.1 network 10.0.1..0 netmask 255.255.255.0 broadcast 10.0.1.255 # bridge interface ( eth0 <-> eth1 ) auto br0 iface br0 inet dhcp bridge_ports eth0 eth1 bridge_stp off bridge_fd 0 bridge_maxwait 0 # These interfaces are disabled since br0 will bring them up itself. # iface eth0 inet manual # iface eth1 inet manual
I rebooted the Pi to enable the new network settings and bring up the bridge interface.
Testing Things Out
With everything installed and properly configured, it was time to test it out.
I associated to the Pi via wifi and logged in via ssh. I confirmed that the bridge interface was up before proceeding. I then connected an Ethernet cable from my laptop to
eth1 and another cable from my gateway device to
eth0. My laptop received an IP address via DHCP and I confirmed that I was able to reach the Internet.
Finally, I began a capture using
br0 and was able to see the traffic going between my laptop and the gateway device. I did notice quite a few dropped packets while performing captures, so I will have to look into that further to see if I can tweak anything to improve performance.