Bridges and switches learn where devices reside by making a table of MAC
addresses associated with ports. For example, when a frame is received on a
physical or virtual port from system A, the source MAC address and the
incoming port of system A is added to the table. Then the frame is broadcast
out all other ports since the destination port for the MAC address of system
B is not yet known. When system B responds, the same thing happens but in
the opposite direction. The source MAC address and incoming port association
for system B are placed in the table. Now the bridge/switch knows which
ports both systems are connected and can direct network frames only between
these two ports, using the most efficient path. The Linux kernel maintains a
timer for each table entry to prevent table fill up. When a system stops
sending frames, like when it is shut down, the kernel waits 300 seconds by
default and then removes that entry from the table.
There are occasions where we need to have certain devices see all the traffic going across the bridge, not just from one port to another. For instance, we may have Intrusion Detection System (IDS) or packet sniffing virtual machines that need to see all traffic for analysis and anomaly alerting. In this case, we need the Linux bridge to act like an Ethernet hub. Hubs are legacy devices that repeat all frames out every port so all devices see all traffic in contrast to the one-to-one mechanism that Linux bridges natively use.
To allow all devices to see all frames, the timer (also called ageing value) is set to zero. In essence, the table is essentially disabled and source MAC address to port mappings aren't recorded. Each frame received is then sent out all ports all the time because there the destination is always unknown (no entry in the table). The drawback is that every system has to process each frame to determine if it's for itself, taking up processing time versus having directed frames sent to it. Modern systems and VMs have plenty of computing power, so this has a minimal impact in today's environments. This is an interesting way to manipulate the Linux bridge to get the results we need.
Configuration
There are two ways to change the ageing timer to get this hub affect, dynamically and statically. We'll cover both below.
bridge-utils
The bridge-utils package has a program that allow you to change the ageing value on the fly. The brctl command (stands for "bridge control") has been around for a long time, but is a great tool for Linux bridge manipulation.
Install:
root@prxmx1:~# apt-get -y install bridge-utils
Show brctl command options:
root@prxmx1:~# brctl --help
Usage: brctl [commands]
commands:
addbr <bridge> add bridge
delbr <bridge> delete bridge
addif <bridge> <device> add int to bridge
delif <bridge> <device> delete int from bridge
hairpin <bridge> <port> {on|off}turn hairpin on/off
setageing <bridge> <time> set ageing time
setbridgeprio <bridge> <prio> set bridge priority
setfd <bridge> <time> set bridge forward delay
sethello <bridge> <time> set hello time
setmaxage <bridge> <time> set max message age
setpathcost <bridge> <port> <cost> set path cost
setportprio <bridge> <port> <prio> set port priority
show [ <bridge> ] show a list of bridges
showmacs <bridge> show a list of mac addrs
showstp <bridge> show bridge stp info
stp <bridge> {on|off} turn stp on/off
root@prxmx1:~#
Let's create a temporary bridge which we will use to create our bridge hub.
root@prxmx1:~# brctl addbr br0Commands explanation:
root@prxmx1:~# brctl addif br0 eth1
root@prxmx1:~# brctl addif br0 eth2
root@prxmx1:~# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.000c297a82bc no eth1
eth2
root@prxmx1:~#
- brctl addbr br0 - creates the linux bridge in the linux kernel
- brctl addif eth1 - adds the eth1 interface to the bridge br0
- brctl addif eth2 - adds the eth2 interface to the bridge br0
-
brctl show - shows all the configured linux bridge info
As you can see from the previous --help output, one of the options for brctl is setageing.
If we set the setageing parameter to zero, then all interfaces attached to
the bridge will receive all network frames regardless of the destination. This is
what we want so our IDS device will see all the network traffic. The bridge
will essentially time out every entry in the kernel MAC address table immediately
as each frame is received and not keep the port association information.
To do this, we use the following command:
root@prxmx1:~# brctl setageing br0 0
This takes affect immediately, you can verify this by issuing:
root@prxmx1:~# brctl showstp br0
br0
bridge id 8000.000c297a82bc
designated root 8000.000c297a82bc
root port 0 path cost 0
max age 20.00 bridge max age 20.00
hello time 2.00 bridge hello time 2.00
forward delay 15.00 bridge forward delay 15.00
ageing time 0.00
hello timer 0.00 tcn timer 0.00
topology change timer 0.00 gc timer 0.00
...
root@prxmx1:~#
As you can see, the ageing time is now at zero and all ports will receive all traffic.
Keep in mind that the above configuration is in effect only until the system is rebooted. To make the configurstion permenent and effective after a reboot, edit your networking file as follows. I'm using debian Linux in this example, so use your Google-fu for the Linux distro you're using.
root@prxmx1:~# cat /etc/network/interfaces
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address x.x.x.x
netmask 255.255.255.0
network x.x.x.0
broadcast x.x.x.255
auto br0
iface br0 inet static
address x.x.x.x.x
netmask 255.0.0.0
network x.x.x.0
broadcast x.x.x.255
bridge_ports eth1 eth2
bridge_stp off
bridge_fd 0
bridge_ageing 0
bridge_maxwait 0
auto eth1
iface eth1 inet manual
auto eth2
iface eth2 inet manual
root@prxmx1:~#
Notice the bridge ports (eth1, eth2) are set to manual mode on boot. This way they can be added to the bridge without unnecessary and conflicting configurations.
Verification:
You can now verify that your bridge hub is working by running a tool called tcpdump. tcpdump captures network frames on an interface, shows them on the command line or records them to a file to view in tcpdump or Wireshark later. Wireshark is a GUI application that allows you to graphically analyze network packets (a very cool and recommended tool! Look it up).
To see if a port is receiving all network traffic, run tcpdump on the interface attached to our IDS system, recording to a packet capture file (.pcap format).
root@prxmx1:~# tcpdump -i eth1 -w traffic-file.pcap
10456 packets captured
10456 packets received by filter
0 packets dropped by kernel
root@ubuntu-2004-1-texting:~# ^C
Command explanation:
- tcpdump - base command
- -i eth1 - identifies the interface to capture traffic from
- -w traffic-file.pcap - tells tcpdump to write the captured packets to a file
- ^C [ctrl-c] - tells tcpdump to quite capturing traffic
Now, when we look at the traffic file tcpdump created, we see traffic from all the ports. When looking at the layer-3 information, we should see traffic to and from IP addresses not assigned to the port being captured on.
root@prxmx1:~# tcpdump -r dumpfile.pcap
reading from file dumpfile.pcap, link-type EN10MB (Ethernet)
19:33:37.432852 IP 192.168.209.100.ssh > 192.168.209.1.51296: Flags [P.], seq 1748148483:1748148607, ack 4192579883, win 501, options [nop,nop,TS val 3185763333 ecr 608909605], length 124
19:33:37.432967 IP 192.168.209.1.51296 > 192.168.209.100.ssh: Flags [.], ack 124, win 2046, options [nop,nop,TS val 608909660 ecr 3185763333], length 0...
root@prxmx1:~#
Command explanation:
- tcpdump - base command
- -r dumpfile.pcap - reads the .pcap file and shows the network traffic to the screen
Now, your IDS can have full view of all traffic that transverses the bridge hub and is looking for suspect and malicious communications between the virtual machines and the outside networks. This is great for virtualized environment and especially when doing hacking / security scenarios in a testing or home lab.
When labbing up a scenario up for testing or learning, run an IDS, such as Security Onion, attached the bridge hub to see what your attacks look like on the network. Look at your IDS tools and see if the attack traffic has fired off alerts and if not, learn to write signatures that will do so. This is an awesome purple team exercise to see what attacks and breaches look like from both sides of the security table!