使用VPC Traffic Mirror功能进行流量审计

一、背景

1、使用Traffic Mirror的场景

对于简单的网络流量采集需求,可以使用VPC Flowlog功能,之前这篇博客介绍了VPC Flowlog的使用。不过VPC Flowlog也有局限,主要是仅记录OSI模型的第四层的日志信息,也就是所谓的“五元组”,即源地址、源端口、目标地址、目标端口、协议这五要素,很多时候不能满足日志需求。

如果需求进一步增加要求如下日志能力:

  • 7层流量采集,记录域名、HTTP header等
  • 旁路方式,不影响流量
  • 相对低成本
  • 不希望使用复杂的Network Firewall或者第三方NGFW+Gateway Load Balancer方案

以上需求场景,适合使用VPC Traffic Mirror实现。

2、采集方式

Traffic Mirror是通过ENI网卡进行旁路采集,因此如果要对本VPC内多机进行采集,需要在配置采集会话时候绑定多个ENI网卡。目前,单个采集会话可绑定的ENI网卡数量不限。

为了定向采集特定流量,减少采集系统的负载,可以通过Filter过滤器的功能,筛选特定的IP CIDR的流量,实现只监控特定流量的例子。例如,可以只采集EC2和外部互联网通信的流量,也可以只采集EC和 可通过Filter规则筛选IP范围,实现只监控特定流量。

VPC Traffic Mirror不支持对NAT Gateway的ENI进行采集。此外,Traffic Mirror是依赖EC2底层Nitro虚拟化基础实现,因此目前对可用机型有一定范围的限制。支持的机型清单在不断增加中。具体支持的机型参考这里

3、数据封装

VPC Traffic Mirror采集到的流量并非直接在OSI模型二层的进行镜像,而是将被监听的网络流量封装到VXLAN协议中,然后通过流式的方式,由UDP 4789端口交付到接受流量的对象。VXLAN是常见的网络封装协议,有着许多厂家、开源社区的广泛支持,并且在AWS之外的其他云上也广泛使用VXLAN作为流量采集的封装协议。

这里举个例子:假设被监听对象使用10.1.2.3和Google DNS 8.8.8.8通信,收集镜像流量的软件部署在另一个子网的EC2上,而接受流量的环境使用192.168.1.100的IP地址。那么,直接将原始流量发给采集软件,两边的IP地址段不一致,请求的源地址和目标地址完全无关,这将造成采集软件所在的EC2无法接受到这个流量。而借助VXLAN封装的报头,是在将10.1.2.3和Google DNS 8.8.8.8通信的所有流量作为Payload也就是“载荷”,然后外边套上一个本地通信的192.168.1.100网段的源地址和目标地址的报头,这样就可以在监听子网内进行任意的转发和通信。位于192.168.1.100的机器接受到流量后,拆掉外层VXLAN报头,里边的载荷就是原始流量。由此实现了不改动原始传输内容的情况下,对被监听的流量按需转发。

许多商用的网络分析软件支持解析VXLAN协议,许多开源软件也支持拆分VXLAN解析。例如ZeekSuricata。本文后续演示使用Suricata的开源版进行解码。

4、采集流量交付

VPC Traffic Mirror支持将流量转发都单个EC2上,或者是一组EC2上。根据接受流量的环境所在的位置不同,一般有如下方案:

  • EC2单机:本VPC的单台EC2接受采集到的流量
  • NLB后的一组EC2:本VPC或跨VPC接受采集到的流量
  • GWLB后的一组EC2:跨VPC或者跨账户接受采集到的流量

在运行流量分析软件的EC2机型选择方面,由于采集到的多机流量加在一起重量可能较高,建议选择拥有高网络带宽的机型。在生产环境中,可使用网络优化型,例如c6in等尾号带n的机型,以获得更高的网络吞吐能力。具体的机型清单可以参考这里

5、本文Demo架构

本文以配置一个最简单的EC2-to-EC2的流量监控为例,演示VXLAN和HTTP协议解包。架构如下图。

本文使用的Suricata是具备完整IDS能力的,但本文仅做最基本的Demo,只是解析HTTP请求头,但不含传输内容(payload)的分析,通俗的说,不记录一个http请求返回的本体。如果希望检测内容等能力,请参考Suricata相关文档。

二、EC2环境配置

本文的演示环境,被采集流量的EC2和分析流量的EC2在同一个VPC。

1、源EC2配置

创建一个m5.large机型,作为被采集流量的对象。操作系统可以任意选择。创建完毕后,从EC2信息的网络标签页中,确认要采集流量的ENI的ID,保存下来接下来要使用。如下截图。

2、目标EC2配置

创建一个m5.large机型,作为接受流量的分析软件运行环境。操作系统这里选择Ubuntu Server 24.04LTS。创建完毕后,从EC2信息的网络标签页中,确认要采集流量的ENI的ID,采集方法如上一个步骤的截图所示。将ENI的ID保存下来接下来要使用。

创建本EC2时候,请注意在它的安全组上,放行UDP 4789端口,这个端口将接收VPC Traffic Mirror发来被VXLAN封装的流量。

另外此处还需要注意,当EC2作为路由器使用时候,需要关闭名为源地址/目标地址检查的功能。但是使用Traffic Mirror是不需要关闭此选项的。本选项位置如下截图。

当EC2作为路由器使用时候,需要关闭名为源地址/目标地址检查的功能的原因是,去往下一跳路由的数据包会将本EC2作为网关到达本机,因此如果不关闭这个功能,转发其他流量的包就会被丢弃。而使用Traffic Mirror是不受这个影响的,因为Traffic Mirror的VXLAN封装将原始流量封装到了UDP数据流内,外层的报头就是发给本EC2的,所以EC2可以在4789端口正常接收。因此,请保持这个选项的默认状态,不要去EC2的这个网络参数,即可开始使用Traffic Mirror。

三、配置VPC Traffic Mirror

1、配置Filter规则过滤器

首先配置过滤器。进入VPC服务界面,将左侧菜单移动到最下方,可看到Traffic Mirroring的菜单,点击其中的Mirror filters,然后点击右侧的创建按钮。如下截图。

录入如下的规则:

  • 名称:InternetTraffic
  • 描述:For Internet Traffic
  • 入栈
    • 规则编号10,行为Reject,协议ALL,源端口范围不需要填写,目标端口范围不需要填写,源地址范围172.31.0.0/16(替换为本VPCIP),目标地址范围0.0.0.0/0,描述信息Reject non-Internet traffic
    • 规则编号20,行为Accept,协议ALL,源端口范围不需要填写,目标端口范围不需要填写,源地址范围0.0.0.0/0,目标地址范围0.0.0.0/0,描述信息Allow all Internet traffic
  • 出栈:
    • 规则编号10,行为Reject,协议ALL,源端口范围不需要填写,目标端口范围不需要填写,源地址范围0.0.0.0/0,目标地址范围172.31.0.0/16(替换为本VPCIP),描述信息Reject non-Internet traffic
    • 规则编号20,行为Accept,协议ALL,源端口范围不需要填写,目标端口范围不需要填写,源地址范围0.0.0.0/0,目标地址范围0.0.0.0/0,描述信息Allow all Internet traffic

配置完毕,保存。如下截图。

创建完成。

2、配置Target

接下来配置接收流量的节点。进去VPC服务界面,在左下角找到Mirror Target,点击创建。如下截图。

在创建Target界面,输入名称,然后在Target类型位置选择Network Interface表示流量会交付给EC2的网卡,然后在Target下拉框中输入 创建EC2步骤获得的作为Target的EC2的ENI。然后点击创建。如下截图。

创建完成。

3、配置Session

接下来配置接收流量的节点。进去VPC服务界面,在左下角找到Mirror Session,点击创建。如下截图。

在创建Session界面,输入名称,在Mirror Source位置输入要被采集的EC2对应的ENI网卡ID,在Mirror Target位置从下拉框选取上一个步骤创建的EC2 Target。在Session Number位置输入1,然后继续向下滚动屏幕。如下截图。

在下方Filter位置,从下拉框中选择刚才创建的过滤器规则,最后点击创建。如下截图。

创建完成。现在EC2已经可以收到Mirror转发过来的流量。

四、在采集用EC2上部署Suricata记录流量

1、安装

登陆到用于采集流量的EC2上,如果是Amazon Linux,使用如下命令部署:

sudo -s
yum update -y
amazon-linux-extras install -y epel
yum install -y suricata
mkdir /var/lib/suricata/rules

如果是Ubuntu,使用如下命令部署:

apt update
apt upgrade -y
apt install suricata

这样就完成了安装。

2、修改配置

首先加入采集规则到配置文件。

echo 'udp any any -> any 4789 (msg:"VXLAN traffic detected"; content:"|0x01|"; depth:1; sid:1000001; rev:1;)' > /etc/suricata/rules/VXLAN.rules

然后开启解析HTTP数据包的开关。编辑配置文件/etc/suricata/suricata.yaml

找到如下2段,把其中的http-log和tls-log的enable设置为yes

 # a line based log of HTTP requests (no alerts)
  - http-log:
      enabled: yes
      filename: http.log
      append: yes
      extended: yes     # enable this for extended logging information
      custom: yes       # enable the custom logging format (defined by customformat)
      customformat: "%{%D-%H:%M:%S}t.%z %{X-Forwarded-For}i %H %m %h %u %s %B %a:%p -> %A:%P"
      #filetype: regular # 'regular', 'unix_stream' or 'unix_dgram'

  # a line based log of TLS handshake parameters (no alerts)
  - tls-log:
      enabled: yes  # Log TLS connections.
      filename: tls.log # File to store TLS logs.
      append: yes
      #extended: yes     # Log extended information like fingerprint
      #custom: yes       # enabled the custom logging format (defined by customformat)
      #customformat: "%{%D-%H:%M:%S}t.%z %a:%p -> %A:%P %v %n %d %D"
      #filetype: regular # 'regular', 'unix_stream' or 'unix_dgram'
      # output TLS transaction where the session is resumed using a
      # session id
      #session-resumption: no

再打开http记录body的日志:

  # Log HTTP body data after normalization, de-chunking and unzipping.
  # Two types: file or dir.
  #     - file logs into a single logfile.
  #     - dir creates 2 files per HTTP session and stores the
  #           normalized data into them.
  # Use 'both' to enable both file and dir modes.
  #
  # Note: limited by the body limit settings
  - http-body-data:
      enabled: yes
      type: file
      filename: http-data.log

在output字段中,确保以下选项打开:

utputs:
  # a line based alerts log similar to Snort's fast.log
  - fast:
      enabled: yes
      filename: fast.log
      append: yes
      #filetype: regular # 'regular', 'unix_stream' or 'unix_dgram'

  # Extensible Event Format (nicknamed EVE) event log in JSON format
  - eve-log:
      enabled: yes
      filetype: regular #regular|syslog|unix_dgram|unix_stream|redis
      filename: eve.json

保存退出。

3、启动服务

执行如下命令。注意里边的ens5是EC2的网卡的名称,使用ifconfig命令或者ip a命令可以查看名称。

suricata -c /etc/suricata/suricata.yaml -i ens5 -D

执行后返回信息如下:

i: suricata: This is Suricata version 7.0.3 RELEASE running in SYSTEM mode

进入后台运行状态。如果要停止一个正在运行的Suricata,可以执行ps awuxf | grep suricata,找到正在运行的Suricata进程,然后kill这个进程即可停止服务。

五、测试流量

1、发起流量

在被采集的节点上,执行命令进行http访问。

curl www.amazon.com

返回结果是HTTP 301跳转。

<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>Server</center>
</body>
</html>

2、查看采集到的流量

登陆到部署有Suricata的EC2,现在可以查看日志文件。通常Suricata解析流量的延迟在秒级,即可看到有关信息被追加到日志文件。现在进入目录/var/log/suricata中会有几个对应的日志文件。

日志文件http.log是记录的7层的请求协议头,执行tail -f http.log追踪输出,可看到日志如下:

3/09/2025-05:56:05.861354 amazon.com[**]/[**]curl/8.5.0[**]172.31.60.236:50176 -> 52.94.236.248:80

日志文件http-data.log是记录的7层的Body信息,也就是传输的文件本体,是二进制格式(十六进制)。如果需要做进一步深度安全扫描,可使用个日志文件进行扫描。内容类似如下格式。这可以看到返回结果

72.31.60.236_50176-52.94.236.248_80-tc:
 0000  3C 68 74 6D 6C 3E 0D 0A  3C 68 65 61 64 3E 3C 74   <html>.. <head><t
 0010  69 74 6C 65 3E 33 30 31  20 4D 6F 76 65 64 20 50   itle>301  Moved P
 0020  65 72 6D 61 6E 65 6E 74  6C 79 3C 2F 74 69 74 6C   ermanent ly</titl
 0030  65 3E 3C 2F 68 65 61 64  3E 0D 0A 3C 62 6F 64 79   e></head >..<body
 0040  3E 0D 0A 3C 63 65 6E 74  65 72 3E 3C 68 31 3E 33   >..<cent er><h1>3
 0050  30 31 20 4D 6F 76 65 64  20 50 65 72 6D 61 6E 65   01 Moved  Permane
 0060  6E 74 6C 79 3C 2F 68 31  3E 3C 2F 63 65 6E 74 65   ntly</h1 ></cente
 0070  72 3E 0D 0A 3C 68 72 3E  3C 63 65 6E 74 65 72 3E   r>..<hr> <center>
 0080  53 65 72 76 65 72 3C 2F  63 65 6E 74 65 72 3E 0D   Server</ center>.
 0090  0A 3C 2F 62 6F 64 79 3E  0D 0A 3C 2F 68 74 6D 6C   .</body> ..</html
 00A0  3E 0D 0A                                           >..

至此配置成功。

如果有进一步对日志处理的需求,还可以使用Kinesis将日志文件从EC2输出到S3,便于长期归档。

六、参考文档

How Traffic Mirroring works

https://docs.aws.amazon.com/zh_cn/vpc/latest/mirroring/what-is-traffic-mirroring.html

Suricata User Guide

https://docs.suricata.io/en/latest

EC2 Nitro Version and Instance Type

https://docs.aws.amazon.com/ec2/latest/instancetypes/ec2-nitro-instances.html

EC2不同机型的网络吞吐能力

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-network-bandwidth.html

借助suricata+Kinesis+ELK构建网络入侵检测系统

https://aws.amazon.com/cn/blogs/china/using-vpc-traffic-mirroring-to-construct-network-intrusion-detection-system-update

基于 Gateway Load Balancer 的一种 VPC 边界流量镜像方案与实现

https://aws.amazon.com/cn/blogs/china/a-vpc-boundary-traffic-mirroring-solution-and-implementation-based-on-gateway-load-balancer