2

I have a KVM virtualization server which serves up a br0 bridge, mapped to eth0. I want to add eth2 as a bridge to br2 for a IDS virtual machine I'm testing, but the guest OS doesn't see either br2 or eth2 as a valid interface. I ran tcpdump on eth2 and can verify it's seeing packets, so I know I have a valid source and that interface has the PROMISC option using ifconfig eth2 promisc up. Here's my /etc/network/interfaces file:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual

auto br0
iface br0 inet static
    address 1.2.3.4
    netmask 255.255.255.0
    gateway 1.2.3.1
    bridge_ports eth0
    bridge_fd 9
    bridge_hello 2
    bridge_maxage 12
    bridge_stp off

auto eth2
iface eth2 inet manual

auto br2
iface br2 inet static
    up ifconfig br2 promisc up
    down ifconfig br2 promisc down
    bridge_ports eth2
    bridge_fd 9
    bridge_hello 2
    bridge_maxage 12
    bridge_stp off

What am I missing?

1

The Linux bridge is a basic layer 2 switch. In order for it to send traffic to an interface connected to it, the traffic must be appropriate for that interface (i.e. the destination MAC address is reachable via that port).

While layer 2 switches often have a port mirroring feature which forwards all traffic crossing the switch to a designated port, the Linux bridge has no such functionality.

However, you can fake it with Linux's traffic control (tc). I do this to forward traffic to a KVM virtual machine running suricata. The limitation of this method is that you can only mirror traffic on a single physical port.

In this script, the MONITOR_PORT is the port to be monitored, which must be a physical port, and MIRROR_PORT is the interface to which the traffic will be sent (which can be a virtual port or a bridge). The monitored port does not need to be in promiscuous mode with this method. And the mirror port does not need to be bridged to the monitored port.

In my case, the host has a bridge br0, bridged to eno1 and to which all the virtual machines have a virtual NIC. I have created a host-only virtual network (as virbr2) for this VM and added a second NIC in the suricata VM on this network in addition to its regular NIC, and directed the traffic to it.

[error@hypervisor ~]$ cat /etc/rc.d/rc.local
#!/bin/bash

# Mirror all packets from one port to another (for suricata)

MONITOR_PORT=eno1
MIRROR_PORT=virbr2

# Ingress
tc qdisc add dev $MONITOR_PORT ingress
tc filter add dev $MONITOR_PORT parent ffff: protocol all u32 match u8 0 0 action mirred egress mirror dev $MIRROR_PORT
# Egress
tc qdisc add dev $MONITOR_PORT handle 1: root prio
tc filter add dev $MONITOR_PORT parent 1: protocol all u32 match u8 0 0 action mirred egress mirror dev $MIRROR_PORT

Note that I didn't create this myself; I shamelessly ripped it off from Port mirroring with Linux bridges, which has a detailed explanation of how it works and an alternative using Open vSwitch which is a lot more flexible (and a lot more complex).

  • Wonderful, thank you! Is it possible to mirror a single port to multiple destination interfaces in case I want to test multiple VM's looking at traffic coming across the mirror port? – batflaps Aug 31 '16 at 4:57
  • I was able to get it to work using brctl like – batflaps Sep 9 '16 at 21:39
1

Thanks, I was able to get it to work using a (possibly) simpler method with brctl like:

auto eth1
iface eth1 inet manual

#Alienvault OSIM Interface
auto br1
    iface br1 inet manual
    address 0.0.0.0
    bridge_ports eth1
    bridge_stp off 

then

ifup eth1

then see if it's capturing packets like:

tcpdump -i br1

you should get a ton of stuff like:

14:46:53.507328 IP 192.168.20.130.53866 > ipv4_1.cxl0.c154.sea001.ix.nflxvideo.net.https: Flags [.], ack 2897, win 5611, options [nop,nop,TS val 3160018074 ecr 2918482309,nop,nop,sack 1 {28961:46337}], length 0
 14:46:53.507402 IP ipv4_1.cxl0.c154.sea001.ix.nflxvideo.net.https > 192.168.20.130.53866: Flags [.], seq 56473:57921, ack 0, win 2050, options [nop,nop,TS val 2918482612 ecr 3160018052], length 1448

like pages and pages flowing past very quickly, this is good. Now add your bridge like:

brctl setageing br1 0
brctl setfd br1 0

Now fire up your VM and add a second NIC of > Specify shared device name > br1. You'll probably have to reboot the VM, but then login to the VM and you should see a second NIC of eth1, which is bridged to your mirror interface and can start looking at packets. I still haven't figured out how to get vswitch to copy mirror packets to multiple interfaces, in case you want to have multiple sensors look at the same data, so that's my next issue. To make your brctl config persist a reboot, do:

cd /etc/network/if-up.d
touch br1-mirror
chmod +x br1-mirror
vi br1-mirror
  #!/bin/bash
  if [ "$IFACE" = br1 ]; then
  brctl setageing br1 0
  brctl setfd br3 0
fi

Mad props to the help here and also also this guy, very helpful all http://www.ryanhallman.com/kvm-configure-mirrored-ports-traffic-to-be-visible-in-guest-snort/ hope this all helps someone else, tough to figure out how to bolt all the pieces together.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.