Middlebox - UofG-netlab/BPFabric GitHub Wiki

Overview

You can use BPFabric as a tool to enable other, more computationally expensive or complicated functions to be installed in your network.

In this example we will set up SNORT as both a Intrusion Detection System (IDS) that monitor the traffic and raises alarms when intrusions are detected and as an Intrusion Detection and Prevention System (IDPS) where the offending traffic is dropped.

For both examples we will be using a TAP interface to collocate the BPFabric switch and the middlebox function. The examples provided here can be easily converted to use a middlebox in a different machine simply by using physical network interfaces instead of TAP interfaces.

Setup

You need SNORT 3 installed to run the following examples. Most distributions at the time of writing only ship SNORT 2 by default in the package manager so you need to compile it from source.

Follow the guide at https://www.zenarmor.com/docs/linux-tutorials/how-to-install-and-configure-snort-on-ubuntu-linux to download and compile SNORT.

SNORT as IDS

In this mode of operation SNORT operates passively and only listen and analyze incoming traffic. In this mode intrusion can be detected but not prevented. This allows the traffic to be analyzed without having directly interacting with the flow of traffic.

A BPFabric switch is started with 3 interfaces, the interface 0 is a TAP interface to the middle and interfaces 1 and 2 are the nodes in the network.

Two functions are inserted in the switch:

  1. The first function is a specific IDS function that is responsible for:
    • Dropping any incoming traffic from the TAP interface 0 as this should only be outgoing traffic and not incoming traffic.
    • mirror all other traffic to port 0
  2. The second function is a classic learning switch

Start BPFabric with a TAP interface, here called tap1. We can see tap1 is mapped to port 0, and eno3 and eno4 to port 1 and 2.

sudo ./softswitch --tap="tap1" -d 1 -v -p eno3 eno4

adding tap interface tap1
Setting up 3 interfaces
tap1 failed to set SIOCETHTOOL ioctl: Operation not supported
Interface tap1, index 0, fd 4
Interface eno3, index 1, fd 5
Interface eno4, index 2, fd 6

Install the functions on the switch. Using the controller CLI send the FunctionAddRequest to install the ids and learning switch functions in stage 0 and 1 of the pipeline.

1 add 0 ids ../examples/ids.o
1 add 1 learningswitch ../examples/learningswitch.o

For this experiment we create a rule in SNORT to alert when ICMP packets are received. Create a new file local.rules and add the following line in it:

alert icmp any any -> any any ( msg:"ICMP Traffic Detected"; sid:10000001; metadata:policy security-ips alert; )

Now start SNORT with the rules you have created. Here SNORT is started in passive mode, listening on the traffic from tap1 that was created by the switch. For debugging we set the alert mode to alert_fast and set the daq batch size to 1 to have instant logging of the alerts.

sudo snort -c /usr/local/snort/etc/snort/snort.lua -R ./local.rules -i tap1 -A alert_fast --daq-batch-size 1

Now if you ping from one node to the other you will see alerts in SNORT.

There is no problems pinging from one host to the other

ping 192.168.58.1

PING 192.168.58.1 (192.168.58.1) 56(84) bytes of data.
64 bytes from 192.168.58.1: icmp_seq=1 ttl=64 time=0.723 ms

And we can see the alert in SNORT

02/15-08:10:47.027884 [**] [1:10000001:0] "ICMP Traffic Detected" [**] [Priority: 0] {ICMP} 192.168.58.2 -> 192.168.58.1
02/15-08:10:47.028144 [**] [1:10000001:0] "ICMP Traffic Detected" [**] [Priority: 0] {ICMP} 192.168.58.1 -> 192.168.58.2

SNORT as IDPS

In this mode of operation SNORT operates actively actively listening from incoming traffic on one interface and forwarding any traffic that is legitimate to the other interface. In this mode the traffic is actively filtered and intrusions can be prevented.

A BPFabric switch is started with 4 interfaces, the interface 0 and 1 are the ingress and egress of the SNORT inline mode and interfaces 3 and 4 are the nodes in the network.

For this experiment two veth pairs are created to create virtual links between the switch and SNORT. This is necessary for this experiment as it looks like SNORT cannot operate in inline mode over TAP interfaces. We use veth pairs instead to act as "patch cables" between the BPFabric switch and the middlebox.

The pair veth1-veth2 is for the ingress traffic and veth3-veth4 for the egress traffic. veth1 and veth3 are attached to the switch and veth2 and veth4 are attached to SNORT.

sudo ip link add veth1 type veth peer name veth2
sudo ip link add veth3 type veth peer name veth4

sudo ip link set dev veth2 up
sudo ip link set dev veth4 up
sudo ip link set dev veth1 up
sudo ip link set dev veth3 up

Start the switch with veth1 and veth3 as ingress and egress to the middlebox on port 0 and 1 respectively. eno3 and eno4 are the ports for the nodes.

sudo ./softswitch -d 1 -v -p veth1 veth3 eno3 eno4

Setting up 4 interfaces
Interface veth1, index 0, fd 3
Interface veth3, index 1, fd 4
Interface eno3, index 2, fd 5
Interface eno4, index 3, fd 6

Similarly to the IDS example we need to create a rule for SNORT. It is the same as before but the rule is changed to drop traffic instead of sending alerts. Create or modify local.rules with the following:

drop icmp any any -> any any ( msg:"ICMP Traffic Detected"; sid:10000001; metadata:policy security-ips alert; )

Start SNORT, this time in inline mode using -Q using veth2 as the ingress and veth4 as the egress.

sudo snort -v -c /usr/local/snort/etc/snort/snort.lua -R ./local.rules -Q -i veth2:veth4 -A alert_fast --daq afpacket --daq-batch-size 1

On the controller install only the learning switch function to start with. At this point the traffic will be routed as normal.

1 add 1 learningswitch ../examples/learningswitch.o

In this case the ping between the nodes is successfull and SNORT doesn't log anything as no traffic has been routed through it.

ping 192.168.58.1
PING 192.168.58.1 (192.168.58.1) 56(84) bytes of data.
64 bytes from 192.168.58.1: icmp_seq=5 ttl=64 time=0.822 ms

Now install the IDPS function. The IDPS functions is responsible for forwarding the traffic from the nodes to the ingress of the IDPS and sending the traffic from the egress to the other functions.

1 add 0 idps ../examples/idps.o

Now test a ping between the nodes and you shouldn't receive any reply

ping 192.168.58.1

PING 192.168.58.1 (192.168.58.1) 56(84) bytes of data.
--- 192.168.58.1 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1025ms

If you check SNORT logs you will see that ICMP traffic was detected and dropped following the rule.

02/15-08:48:10.697116 [drop] [**] [1:10000001:0] "ICMP Traffic Detected" [**] [Priority: 0] {ICMP} 192.168.58.2 -> 192.168.58.1
02/15-08:48:11.699112 [drop] [**] [1:10000001:0] "ICMP Traffic Detected" [**] [Priority: 0] {ICMP} 192.168.58.2 -> 192.168.58.1

However, if you instead try a TCP transfer between the nodes using for instance iperf the traffic will flow as expected through the middlebox without any alert generated by SNORT.

iperf -c 192.168.58.1
------------------------------------------------------------
Client connecting to 192.168.58.1, TCP port 5001
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[  1] local 192.168.58.2 port 59242 connected with 192.168.58.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  1] 0.0000-10.0274 sec  1.08 GBytes   922 Mbits/sec