一、背景
VPC Flowlog是用于采集VPC内四层网络流量的工具。其采集对象包括EC2、NLB、RDS等之间和外部网络之间的流量。VPC Flowlog是OSI模型第四层采集工具,会记录源地址、源端口、目标地址、目标端口、协议、传输数据量等信息,但不会记录OSI模型第七层定义的域名、网址等属于应用层定义的日志,也不会记录发送的数据本体。VPC Flowlog常用于排查EC2相关网络错误。
本文介绍如何开启VPC Flowlog并输出到CloudWatch用于查看VPC内流量。
根据官网文档,如下网络流量不被记录:
- 实例与 Amazon DNS 服务器联系时生成的流量。如果您使用自己的 DNS 服务器,则将记录到该 DNS 服务器的所有流量。
- Windows 实例为 Amazon Windows 许可证激活而生成的流量。
- 实例元数据传入和传出 169.254.169.254 的流量。
- Amazon Time Sync Service 的传入和传出 169.254.169.123 的流量。
- DHCP 流量。
- 镜像流量。
- 到默认 VPC 路由器的预留 IP 地址的流量。
- 在终端节点网络接口和 Network Load Balancer 网络接口之间的流量。
VPC Flowlog记录的字段信息,是遵循Flowlog的版本2、版本3、版本4、版本5等版本规范。在本文末尾的参考文档提供高了各版本记录的不同字段的说明。
下面开始配置。
二、配置
1、配置IAM Policy
进入IAM服务,点击左侧菜单Policy策略,点击右侧的创建按钮,然后选择自定义,点击JSON按钮。如下截图。
输入如下IAM Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams"
],
"Resource": "*"
}
]
}
以上Policy命名为flowlog
即可。
2、配置IAM Role
进入IAM服务,点击左侧菜单Role角色,点击右侧创建角色按钮。
点击页面中央的Custom trust policy
自定义信任策略按钮。然后在下方输入如下策略。如下截图。
策略如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "vpc-flow-logs.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
输入信任策略后点击向导下一步。
在选择关联的策略位置,选择上一步创建的flowlog
策略。如下截图。
最后设置IAM Role角色的名称是vpcflowlog
。完成IAM Role创建。
3、配置CloudWatch Log Groups作为Flowlog的投递目标
进入CloudWatch服务,点击左侧的Log Grous日志组菜单,点击新建。如下截图。
在创建界面输入名称,然后选择数据保留时间为7天。因为当VPC内EC2较多的时候,Flowlog数据量大,如果原则长期保留会占用较大空间导致存储成本上升,因此这里选择较短的保留时间。
配置CloudWatch完成。
4、生成VPC Flowlog
进入VPC服务界面。有两个位置可以创建Flowlog,分别在选中VPC后的操作菜单,和下方的标签页。如下截图。
输入Flowlog的名字,例如my-flowlog
。继续向下滚动页面。如下截图。
在时间聚合维度的位置,选择1分钟。在目标位置,选择上一步创建的CloudWatch Log Groups的名字。继续向下滚动页面。如下截图。
在IAM Role位置,选择上一步生成的IAM Role角色的名字。在日志格式位置,选择AWS默认格式。注意默认格式是所谓的版本2规范,如果需要版本3规范,请使用自定义格式。最后点击右下角创建按钮。如下截图。
创建完成,界面上可以看到日志已经输出到CloudWatch的日志组。
三、在CloudWatch上查看Flowlog
1、查看原始日志
进入CloudWatch服务。点击左侧的Log groups日志组按钮,搜索上一步创建的日志组的名称,例如输入关键字vpc,即可搜索出来。点击进入。如下截图。
在日志组中过,可以看到许多单条的Log stream,每一个日志流对应着一个ENI网卡,也就是EC2/RDS等服务的网卡。点击进入。如下截图。
进入单个日志流,即可看到本ENI网卡的4层的flowlog日志。如下截图。
这里简述以上字段分别是:日志规范版本,AWS账号,ENA网卡编号,源地址,目标地址,源端口,目标端口,协议,Package包数,传输字节数,起始时间戳(Unix日期),结束时间戳(Unix日期),放行还是通过,日志写入状态。
关于AWS默认的Flowlog的格式和字段说明,请参考本文末尾的官方文档。
2、使用Log Insight查询
由于原始日志格式不便于阅读,且原始日志是分成单个ENI网卡的,对于很多EC2的网络环境不便于查看。因此可使用Log Insight功能来查询。
进入Log Insight服务。
首先搜索Log groups,搜索出来上一步的名字,然后点击choose a sample query
查看查询代码例子。如下截图。
在右侧弹出的对话框内,可以看到许多例子。这里选择VPC Flow Logs菜单下,找到Top 10 byte transfers by source and destination IP addresses
也就是传输量最大的前十名排行的查询语句,点击下方的Apply
按钮。这个查询语句就会自动复制到左侧的查询框内。然后点击Run query
按钮运行查询。如下截图。
查询结果已经返回,这是在1小时时间段内,按传输流量排行的TOP10的IP。注意这个数据中间有一段没有查询出来,这是因为这个截图的测试期间,停止了VPC Flowlog功能,有一段时间没有生成日志。如下截图。
3、优化查询
以下查询字段基于VPC Flowlog的版本2规范来查询。如果您需要更多字段,那么请在上文的配置中,使用输入日志版本3规范自定义字段的方式来选择要打印到日志中的字段。具体字段定义参考本文末尾的文档。
(1) 修改查询时间范围
现在优化查询范围。将右上角的时间范围从1小时选择到1天。将图中的查询语句,查出来的传输字节数结果从Byte除以1000再除以1000,这样单位变成MB更直观。如下截图。
修改后的查询代码如下:
stats sum(bytes)/1000/1000 as MBTransferred by srcAddr, dstAddr
| sort bytesTransferred desc
| limit 10
再次查询即可获得一天内传输流量最高的源和目标地址。查询结果如下。
以上查询结果可看到,VPC与互联网IP通信(出站和入站)也会被记录。记录下来的互联网流量的原始地址和目标地址,主要看网络流量是经过Elastic IP直接去外网、还是经负载均衡的,此外负载均衡的网络和target group目标组的模式也不一样,由此记录下来的源地址访问也各不相同。
(2) 根据源地址/目标地址范围进行查询
如果希望查询本VPC与其他VPC,或者本VPC与IDC通过专线/VPN互联时候另一侧的流量,可以添加IP地址范围条件。
fields @timestamp, srcAddr, srcPort, dstAddr, dstPort, protocol, action
| stats sum(bytes)/1000/1000 as MBtransferred by srcAddr, srcPort, dstAddr, dstPort, protocol, action, bin(1m)
| filter srcAddr like "172.16."
| filter dstAddr like "172.31."
| sort MBtransferred desc
| limit 100
这个查询结果将返回在特定时间窗口内的特定来源地址和VPC之间传输的流量(单位是MB)的TOP10排行。查询信息将显示目标地址和源地址的端口号,并显示协议(1代表ICMP,6代表TCP,17代表UDP)。如下截图。
注意:具体协议代号的说明,请参考本文末尾IANA的官方定义。
另外需要注意,图中的纵轴是表示命中的日志条目数,不是流量例如。例如9:00-9:01的一分钟内,flowlog记录了2条符合这个查询结果的日志,这里就是显示2。如果记录了200条,这里就显示200个Record。
(3) 查询某时间段一分钟内流量最高的来源
首先查询近一段时间流量最高的时间是哪一分钟(具体到一分钟颗粒度),查询条件限定了地址范围,这样可用于特定方向流量的筛选。
fields @timestamp, srcAddr, srcPort, dstAddr, dstPort, protocol, action
| stats sum(bytes)/1000/1000 as MBtransferred by bin(1m)
| filter srcAddr like "172.16."
| filter dstAddr like "172.31."
| sort MBtransferred desc
| limit 100
由此可看到16:22这一分钟流量最高。如下截图。
那么去查询这一分钟内,谁的传输字节数最高。此时可以调整右上角的时间筛选范围,然后执行如下语句:
fields @timestamp, srcAddr, srcPort, dstAddr, dstPort, protocol, action
| stats sum(bytes)/1000/1000 as MBtransferred by srcAddr, srcPort, dstAddr, dstPort, protocol, action, bin(1m)
| filter srcAddr like "172.16."
| filter dstAddr like "172.31."
| sort MBtransferred desc
| limit 100
此时可以看到查询结果的数据是只显示这一分钟内的所有传输,即可看到谁占用带宽最高。如下截图。
由此就定位到了一分钟时间段内传输流量最高的IP地址。
(4) 查询向外流量最多的IP(定位通过NAT Gateway的流量)
如果本VPC内产生了大量的通过NAT Gateway的流量,那么可以用关键字来查询目标地址不是本VPC的流量。
fields @timestamp, srcAddr, srcPort, dstAddr, dstPort, protocol, action
| stats sum(bytes)/1000/1000 as MBtransferred by srcAddr, srcPort, dstAddr, dstPort, protocol, action, bin(1m)
| filter srcAddr like "172.31."
| filter dstAddr not like "172.31."
| sort MBtransferred desc
| limit 100
将其中的IP地址修改为本VPC的CIDR,即可看到去往本VPC之外的流量。
四、参考文档
如何将 CloudWatch Logs Insights 查询用于我的 VPC 流日志?
https://repost.aws/zh-Hans/knowledge-center/vpc-flow-logs-and-cloudwatch-logs-insights
VPC Flowlog 流日志记录的格式和字段说明
https://docs.aws.amazon.com/zh_cn/vpc/latest/userguide/flow-logs.html#flow-log-records
CloudWatch Logs Insights 支持的日志和发现的字段
在VPC Flowlog中Protocol字段的定义
http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
CloudWatch Log Insight查询语法