Monday, December 26, 2005

Taps and Hubs Never, Ever Mix

I've written about not using taps with hubs in January 2004 and again in a prereview of Snort Cookbook. The diagram below shows why it's a bad idea to try to "combine" outputs from a traditional tap into a hub.



The diagram shows a traditional two-output tap connecting to a hub. Why would someone do this? This unfortunate idea tries to give a sensor with a single sniffing interface the ability to see traffic from both tap outputs simultaneously. The proper way to address the issue is shown below.



A method to bond interfaces with FreeBSD is listed here. We could avoid the interface bonding issue if we replace the dual output tap with a so-called port aggregator tap, like the one pictured at left. As long as the total aggregate bandwidth of the monitored link does not exceed 100 Mbps (for a 100 Mbps tap), then we can use it as shown below.



What do we do if we have more than one sensor platform? In other words, we may have an IDS and some other device that needs to inspect traffic provided by the port aggregator tap. We might be tempted to do the following, which shows putting the single output from the port aggregator tap into a hub, then plugging the two sensors into the hub.



This is a bad idea. The interface provided by the single port aggregator tap output is full duplex. It will not work properly when connected to the inherently half duplex interface on the hub. When each sensor interface is plugged into the hub, they will auto-negotiate at half duplex as well. Subtle problems will appear when they try to monitor traffic sent from the tap. Consider the following ICMP traffic sniffed using a scenario like that shown above. Host 69.243.40.166 used the -s 256 option for ping to send larger than normal ICMP packets.

16:20:15.930505 IP 69.243.40.166 > 216.109.117.107: icmp 264: echo request seq 0
16:20:15.942576 IP 216.109.117.107 > 69.243.40.166: icmp 264: echo reply seq 0
16:20:16.934919 IP 69.243.40.166 > 216.109.117.107: icmp 264: echo request seq 1
16:20:16.947981 IP 216.109.117.107 > 69.243.40.166: icmp 264: echo reply seq 1
16:20:17.956721 IP 216.109.117.107 > 69.243.40.166: icmp 264: echo reply seq 2
...edited...
16:20:25.010988 IP 69.243.40.166 > 216.109.117.107: icmp 264: echo request seq 9
16:20:25.022211 IP 216.109.117.107 > 69.243.40.166: icmp 264: echo reply seq 9
16:20:27.030011 IP 69.243.40.166 > 216.109.117.107: icmp 264: echo request seq 11
16:20:27.042325 IP 216.109.117.107 > 69.243.40.166: icmp 264: echo reply seq 11
16:20:28.039553 IP 69.243.40.166 > 216.109.117.107: icmp 264: echo request seq 12
16:20:28.050413 IP 216.109.117.107 > 69.243.40.166: icmp 264: echo reply seq 12
16:20:29.048828 IP truncated-ip - 248 bytes missing!
69.243.40.166 > 216.109.117.107: icmp 264: echo request seq 13
16:20:29.060525 IP 216.109.117.107 > 69.243.40.166: icmp 264: echo reply seq 13
...edited...
16:20:40.153733 IP 69.243.40.166 > 216.109.117.107: icmp 264: echo request seq 24
16:20:41.163216 IP 69.243.40.166 > 216.109.117.107: icmp 264: echo request seq 25
16:20:41.175272 IP 216.109.117.107 > 69.243.40.166: icmp 264: echo reply seq 25
16:20:42.172485 IP truncated-ip - 248 bytes missing!
69.243.40.166 > 216.109.117.107: icmp 264: echo request seq 26
16:20:42.185592 IP 216.109.117.107 > 69.243.40.166: icmp 264: echo reply seq 26

The first four packets look ok. Echo request seq 0 is matched by echo reply seq 0; and echo 1 for reply 1. The same doesn't hold for seq 2, which is missing its echo request. Later seq 9 appears, after no problems with ICMP seq 3-8. Suddenly there is no mention of seq 10. Seq 12 is ok, but the echo request for seq 13 is abnormally truncated! Later we see the echo request for seq 24, but no reply. We see the echo request and reply for seq 25, only to be followed by an abnormally truncated eqo request for seq 26. This is definitely troublesome. From the perspective of the host sending the ICMP traffic, no packets were dropped or received abnormally.

The proper way to address this problem, if port aggregation is desired, is to use a dual port aggregator tap, as shown below.



That solution provides a single tap output interface to each sensor. If one does not want to use port aggregation, and one can have the sensor bond interfaces, something like the Regeneration Tap shown at left can be used. In this case, two outputs are provided for each sensor, and they bond them together to see a single full duplex traffic stream.

Notice that in no circumstances can one combine a tap and a hub. Therefore, taps and hubs never, ever, mix. Remember that this holiday season!

Update: Ok, that is not entirely accurate. It is accurate for the scenarios depicted here, but some creative thinking and a very helpful comment by Joshua resulted in this follow-on post!

7 comments:

Martin said...

Richard,

Thanks for this article. I've been tempted to use a hub and tap in exactly this situation a couple of times in the past, now I remember why I decide not to. You've explained it in a lot more detail than I ever could.

Martin

Shirkdog said...

For OpenBSD (and NetBSD), brconfig for bridging interfaces:

http://www.openbsd.org/faq/faq6.html#Bridge

Joshua said...

While taps and hub may not mix for the very reasons you've identified, a tap and two hubs can be useful. One tap output into each hub, then one or more sensors plugged into each hub. Standard bonding on the sensors, and voila, a cheap multi-port copper Ethernet tap.

Once we obtained multi-port copper taps (thank you NetOptics!), this went away very quickly. But it served well for a few years. The only tricky part was finding a source to buy actual hubs and not multi-port bridges...

Richard Bejtlich said...

Joshua,

Thanks for your very interesting comment. I just updated this post and wrote a second depicting your idea.

Anonymous said...
This comment has been removed by a blog administrator.
new laptop battery said...
This comment has been removed by a blog administrator.
dghnfgj said...
This comment has been removed by a blog administrator.