Post

AWS VPC traffic mirroring to IDS. Deep dive with Wireshark.

Abstract

Traffic mirroring refers to the process of copying network traffic from one network port or interface to another for analysis, monitoring, or security purposes. There are multiple options for traffic mirroring depending on what hardware/virtual setup is in use. The most popular modes of interaction with the system during traffic inspection are:

  • IDS (Intrusion Detection System) - This system detects suspicious network behavior and generates alerts or notifications if any rules are violated, such as unexpected source/port/protocol. The rules are declared in predefined format (we will check the popular Suricata-based format of rules).
  • IPS (Intrusion Prevention System) - This system goes a step further than IDS and not only detects and alerts about suspicious behavior, but also has the capability to influence the traffic, such as dropping packets or changing values.

AWS offers multiple options to achieve these and probably the top is a managed AWS Network Firewall service that operates as an IPS allowing for traffic inspection and application of different rules. This solution is built on the open-source Suricata system. Also, there is option with Transient Gateway and Centralized Egress Appliance VPC but here you should be careful in setup not to have asymmetric traffic drops. Since 2020 newly introduced AWS Gateway Load Balancer can cover IPS scenario.

Here, we will take a look at option with VPC traffic mirroring to check how it works and what happens with packets.

Network setup for traffic mirroring

In current setup we will configure VPC traffic mirroring and will use Suricata to inspect packets. You can use any other IDS/IPS - personally I more like Snort, but for this setup Suricata will be used.

To make it easy compared captured packets we will apply filter on top of traffic mirroring session to mirror only incoming and outgoing IMCP ping packets.

To start traffic flow on the source origin instance, we will run ping command to one of Google’s public IPs.

1
ping 142.251.42.79

img.png

Configuring VPC traffic mirroring

If you are from Cisco world, the setup process is very similar to configuring port span on equipment. We need to follow step of mapping the target - this can be ENI, NLB or Gateway LB endpoint:

img.png

We have control over Inbound and Outbound Rules in traffic filter. If you are interested in specific data traffic that can be classified by source/destinatio CIDRs and ports, by applying them in these filters you will mirror only traffic that is compatible with filter.

img.png

And do not forget to start mirror session. Here we specify the traffic source - the ENI of our application instance, target (previously created) and VNI. If VNI is not specified it will be randomly generated. But here we will explicitly define it with value 333, so later in captured traffic we will track this value.

img.png

img.png

Suricata installation

Next, lets login into appliance instance, install and configure Suricata. Here we are configuring Suricata rules:

  • will alert for ICMP from/to any src/dst with message “ICMP traffic detected”

Later we will check why UDP and 4789 port are used.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sudo -s
# Install epel-release
amazon-linux-extras install -y epel
# Install suricata
yum install -y suricata
# Create the default suricata rules directory
mkdir /var/lib/suricata/rules
# Add a rule to match all UDP traffic
echo 'alert icmp any any -> any any (msg:"ICMP traffic detected"; sid:200001; rev:1;)' > /var/lib/suricata/rules/suricata.rules
# Start suricata listening on eth0 in daemon mode
suricata -c /etc/suricata/suricata.yaml -k none -i eth0 -D
# Capture logs can be found in /var/log/suricata/fast.log
yum install -y jq
tail -f /var/log/suricata/eve.json  | jq 'select(.event_type=="alert")'

Let’s disable Jumbo-frames for this setup:

1
sudo ip link set dev eth0 mtu 1500

NW interfaces on application server

1
2
3
4
5
6
7
8
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.31.9.144  netmask 255.255.240.0  broadcast 172.31.15.255
        inet6 fe80::8d3:93ff:fee4:27b2  prefixlen 64  scopeid 0x20<link>
        ether 0a:d3:93:e4:27:b2  txqueuelen 1000  (Ethernet)
        RX packets 67739  bytes 91125253 (86.9 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8329  bytes 777401 (759.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

NW interfaces Suricata appliance

1
2
3
4
5
6
7
8
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.31.4.131  netmask 255.255.240.0  broadcast 172.31.15.255
        inet6 fe80::836:d2ff:fefc:942e  prefixlen 64  scopeid 0x20<link>
        ether 0a:36:d2:fc:94:2e  txqueuelen 1000  (Ethernet)
        RX packets 147218  bytes 194694578 (185.6 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 22560  bytes 2819722 (2.6 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Running a ping from application server

First lets monitor Suricata logs:

1
[root@ip-172-31-4-131 ec2-user]# tail -f /var/log/suricata/fast.log

Running ping from application server to public IP - there are no new records in Suricata log.

But when are trying to directly ping Suricata appliance from Application server we see new entries:

1
2
3
[root@ip-172-31-4-131 ec2-user]# tail -f /var/log/suricata/fast.log
02/08/2023-XX:19:07.005845  [**] [1:200001:1] ICMP traffic detected [**] [Classification: (null)] [Priority: 3] {ICMP} 172.31.9.144:3 -> 172.31.4.131:3
02/08/2023-XX:19:07.006011  [**] [1:200001:1] ICMP traffic detected [**] [Classification: (null)] [Priority: 3] {ICMP} 172.31.4.131:3 -> 172.31.9.144:3

Buy the way, Suricata also supports logging in JSON format, very useful to query using JQ utility, we can see same entries but with more details:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
tail -f /var/log/suricata/eve.json  | jq 'select(.event_type=="alert")'
{
  "timestamp": "2023-02-08TXX:56:10.323036+0000",
  "flow_id": 1671295421574620,
  "in_iface": "eth0",
  "event_type": "alert",
  "src_ip": "172.31.9.144",
  "dest_ip": "172.31.4.131",
  "proto": "ICMP",
  "icmp_type": 8,
  "icmp_code": 0,
  "alert": {
    "action": "allowed",
    "gid": 1,
    "signature_id": 200001,
    "rev": 1,
    "signature": "ICMP traffic detected",
    "category": "",
    "severity": 3
  },
  "flow": {
    "pkts_toserver": 1,
    "pkts_toclient": 0,
    "bytes_toserver": 98,
    "bytes_toclient": 0,
    "start": "2023-02-08TXX:56:10.323036+0000"
  }
}
{
  "timestamp": "2023-02-08TXX:56:10.323195+0000",
  "flow_id": 1671295421574620,
  "in_iface": "eth0",
  "event_type": "alert",
  "src_ip": "172.31.4.131",
  "dest_ip": "172.31.9.144",
  "proto": "ICMP",
  "icmp_type": 0,
  "icmp_code": 0,
  "alert": {
    "action": "allowed",
    "gid": 1,
    "signature_id": 200001,
    "rev": 1,
    "signature": "ICMP traffic detected",
    "category": "",
    "severity": 3
  },
  "flow": {
    "pkts_toserver": 1,
    "pkts_toclient": 1,
    "bytes_toserver": 98,
    "bytes_toclient": 98,
    "start": "2023-02-08TXX:56:10.323036+0000"
  }
}

Capture and inspect traffic with Wireshark

Now lets capture ENIs of both application and appliance instances and compare them.

img.png

This is a capture of ping response from 142.251.42.79 to our 172.31.9.144 Application server.

img.png

As we can observe, the packets are different. Left side of the screen is a capture of Application server, right - Appliance instance. The initial source ICMP packet is wrapped by VPC traffic mirroring session by UDP packet with additional headers. Here we have capture same ICMP packet sequence number - you can see there is no difference in the inner encapsulated payload.

The outer packet has source of ENI that we are capturing and destination of ENI on target appliance. Also, this is UDP packet sent to 4789 port. That is why initially we did not see any records in log in ICMP ping commands. Also take a look at header VXLAN Network Identifier (VNI) it has value 333 that we have configured previously in session mirror setup.

img.png

On the right bottom section of the screen you can see how packet encapsulation is applied in a binary form.

UDP traffic mirroring logging:

If we update Suricata with new rule:

1
RULE: alert udp any any -> any 4789 (msg:"UDP Mirror traffic detected"; sid:200001; rev:1;)

Now we can see all mirrored UDP packet incoming into Appliance instance. But with one remark, that these are encapsulated UDP packets and the src/dst are not the same as in origin packet. So it is just for observation, but we can not create and apply any rule for them. We will fix it in a while.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
tail -f /var/log/suricata/eve.json  | jq 'select(.event_type=="alert")'
{
  "timestamp": "2023-01-27T13:10:48.181155+0000",
  "flow_id": 1642158420968355,
  "in_iface": "eth0",
  "event_type": "alert",
  "src_ip": "172.31.9.144",
  "src_port": 65511,
  "dest_ip": "172.31.4.131",
  "dest_port": 4789,
  "proto": "UDP",
  "alert": {
    "action": "allowed",
    "gid": 1,
    "signature_id": 200001,
    "rev": 1,
    "signature": "UDP Mirror traffic detected",
    "category": "",
    "severity": 3
  },
  "app_proto": "failed",
  "flow": {
    "pkts_toserver": 1,
    "pkts_toclient": 0,
    "bytes_toserver": 148,
    "bytes_toclient": 0,
    "start": "2023-01-27T13:10:48.181155+0000"
  }
}

This is actually how VXLan works

VXLAN (Virtual Extensible LAN) is a network virtualization technology that uses a VLAN-like encapsulation technique to encapsulate MAC-based OSI Layer 2 Ethernet frames within Layer 3 IP packets. This allows communication between virtualized network segments, providing network isolation and enables the creation of multiple virtual LANs on a single physical infrastructure.

vxlan_encapsulation.svg

Here’s a summary of how VXLAN works:

  • Endpoints (VMs or physical hosts) communicate with each other as if they were on the same LAN, despite being located in different physical locations.
  • The VXLAN encapsulation process adds a VXLAN header to the original Ethernet frame, including a 24-bit VXLAN Network Identifier (VNI), which acts as a segment ID for the virtual network.
  • The encapsulated frame is then sent as a standard IP packet to the destination endpoint.
  • The destination endpoint removes the VXLAN header and processes the original Ethernet frame as if it had never left the local network.

Adding vxlan interface

Usually appliance instance can operate with vxlan traffic and extract encapsulated inner packages. To achieve this - we can add virtual interface on top of eth0 that will perform these actions.

1
2
3
sudo ip link add vxlan100 type vxlan id 333 dstport 4789 local 172.31.4.131 dev eth0
sudo ip link set vxlan100 up

Suricata appliance is now showing second interface:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.31.4.131  netmask 255.255.240.0  broadcast 172.31.15.255
        inet6 fe80::836:d2ff:fefc:942e  prefixlen 64  scopeid 0x20<link>
        ether 0a:36:d2:fc:94:2e  txqueuelen 1000  (Ethernet)
        RX packets 147579  bytes 194728353 (185.7 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 22902  bytes 2910203 (2.7 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

vxlan100: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet6 fe80::ecb1:f6ff:fe9a:c044  prefixlen 64  scopeid 0x20<link>
        ether ee:b1:f6:9a:c0:44  txqueuelen 1000  (Ethernet)
        RX packets 2  bytes 168 (168.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 5 overruns 0  carrier 0  collisions 0

And now if capture Suricata to vxlan100 port - we will see original packet data, src/dst/proto to which we can apply proper rules:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
[root@ip-172-31-4-131 ec2-user]# suricata -c /etc/suricata/suricata.yaml -k none -i vxlan100: -D
[root@ip-172-31-4-131 ec2-user]# tail -f /var/log/suricata/eve.json  | jq 'select(.event_type=="alert")'
{
  "timestamp": "2023-02-08TXX:59:54.986033+0000",
  "flow_id": 650854156340145,
  "in_iface": "vxlan100:",
  "event_type": "alert",
  "src_ip": "172.31.9.144",
  "dest_ip": "142.251.42.79",
  "proto": "ICMP",
  "icmp_type": 8,
  "icmp_code": 0,
  "alert": {
    "action": "allowed",
    "gid": 1,
    "signature_id": 200001,
    "rev": 1,
    "signature": "ICMP traffic detected",
    "category": "",
    "severity": 3
  },
  "flow": {
    "pkts_toserver": 1,
    "pkts_toclient": 0,
    "bytes_toserver": 98,
    "bytes_toclient": 0,
    "start": "2023-02-08TXX:59:54.986033+0000"
  }
}
{
  "timestamp": "2023-02-08TXX:59:54.987442+0000",
  "flow_id": 650854156340145,
  "in_iface": "vxlan100:",
  "event_type": "alert",
  "src_ip": "142.251.42.79",
  "dest_ip": "172.31.9.144",
  "proto": "ICMP",
  "icmp_type": 0,
  "icmp_code": 0,
  "alert": {
    "action": "allowed",
    "gid": 1,
    "signature_id": 200001,
    "rev": 1,
    "signature": "ICMP traffic detected",
    "category": "",
    "severity": 3
  },
  "flow": {
    "pkts_toserver": 1,
    "pkts_toclient": 1,
    "bytes_toserver": 98,
    "bytes_toclient": 98,
    "start": "2023-02-08TXX:59:54.986033+0000"
  }
}

Wireshark capture on vxlan100

Let’s capture traffic again on both instances, but this time on appliance instace we will use vxlan port.

img.png

vxlan interface capture (filtered ICMP packets only): img.png

Compare both captures - the data is the same (now there is no encapsulation with UDP, and we can see native raw packets as on the origin). img.png

Conclusions

AWS VPC traffic mirroring is a powerful tool that can help improve the security of a network by allowing network administrators to monitor and inspect all incoming and outgoing traffic in real-time. This feature can be particularly useful when used in conjunction with an Intrusion Detection System (IDS) as it provides valuable insights into network activity that can be used to detect and prevent malicious activity.

This post is licensed under CC BY 4.0 by the author.