- Knowledge Base
- Amazon Web Services
- Enable Flow Logs for VPC Subnets
Ensure that flow logs are enabled for your Amazon VPC subnets. Flow Logs is a feature that enables you to capture information about the IP traffic going to and from the network interfaces associated with your subnets. Once you create a flow log for a VPC subnet, each network interface within that subnet is monitored and the flow logs data is sent to Amazon CloudWatch Logs. This conformity rule demonstrates how to enable the Flow Logs feature for individual or multiple subnets. To enable flow logs at the VPC level, where all the VPC's subnets and ENIs inherit the feature configuration, see this conformity rule.
The Flow Logs feature can be used as a security tool to monitor the traffic that is reaching your Amazon EC2 instances. Once enabled, the feature will start collecting IP traffic data to and from your VPC subnets, data that can be useful to detect and troubleshoot security issues such as overly restrictive security group rules (when specific traffic is not reaching an instance) or overly permissive rules (when an instance is publicly accessible through a specific port).
Audit
To determine if your VPC subnets have the Flow Logs feature enabled, perform the following actions:
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to AWS VPC dashboard at https://console.aws.amazon.com/vpc/.
03 In the left navigation panel, under Virtual Private Cloud, click Subnets.
04 Select the subnet that you want to examine.
05 Select the Flow Logs tab from the bottom panel and search for any flow log entries available for the selected VPC subnet. If there are no flow logs created, instead the following message is displayed: "No Flow Logs found", i.e. https://goo.gl/HxVZJ7, the Flow Logs feature is not enabled for the selected VPC subnet.
06 Repeat step no. 4 and 5 to determine the Flow Logs feature status for other AWS VPC subnets available in the current region.
07 Change the AWS region from the navigation bar and repeat the audit process for other regions.
Using AWS CLI
01 Run describe-subnets command (OSX/Linux/UNIX) using custom query filters to list the IDs of all the subnets provisioned in the selected AWS VPC:
aws ec2 describe-subnets --region us-east-1 --filters Name=vpc-id,Values=vpc-12345678 --output table --query 'Subnets[*].SubnetId'
02 The command output should return a table with the requested subnet IDs:
--------------------- | DescribeSubnets | +-------------------+ | subnet-abcd1234 | | subnet-1234abcd | | subnet-aaaa1234 | | subnet-1234bbbb | | subnet-cccc1234 | | subnet-1234dddd | +-------------------+
03 Run describe-flow-logs command (OSX/Linux/UNIX) using the ID of the subnet that you want to examine as identifier to determine if the selected VPC subnet has the Flow Logs feature enabled:
aws ec2 describe-flow-logs --region us-east-1 --filter Name=resource-id,Values=subnet-abcd1234
04 The command output should return the Flow Logs feature configuration metadata:
{ "FlowLogs": [] }
If the FlowLogs attribute value, returned as command output, is set to an empty array (i.e. []), as shown in the example above, the Flow Logs feature is not enabled for the selected AWS VPC subnet.
05 Repeat step no. 3 and 4 to determine the Flow Logs feature status for other Amazon VPC subnets available in the current region.
06 Change the AWS region by updating the --region command parameter value and repeat steps no. 1 - 5 to perform the entire audit process for other regions.
Remediation / Resolution
To enable flow logs for your Amazon VPC subnets, perform the following actions:
Using AWS CloudFormation
01 CloudFormation template (JSON):
{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "VPCNetwork": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": "10.0.0.0/16", "InstanceTenancy": "default" } }, "VPCSubnet": { "Type": "AWS::EC2::Subnet", "Properties": { "VpcId": { "Ref": "VPCNetwork" }, "CidrBlock": "10.0.1.0/24", "AvailabilityZone": "us-east-1a" } }, "SubnetFlowLog": { "Type": "AWS::EC2::FlowLog", "Properties": { "ResourceId": { "Ref": "VPCSubnet" }, "ResourceType": "Subnet", "TrafficType": "REJECT", "LogDestinationType": "cloud-watch-logs", "MaxAggregationInterval": 60, "LogGroupName": { "Ref": "LogGroup" }, "DeliverLogsPermissionArn": { "Fn::GetAtt": [ "FlowLogRole", "Arn" ] }, "LogFormat": "${version} ${vpc-id} ${subnet-id} ${instance-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${tcp-flags} ${type} ${pkt-srcaddr} ${pkt-dstaddr}" } } } }
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09' Resources: VPCNetwork: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 InstanceTenancy: default VPCSubnet: Type: AWS::EC2::Subnet Properties: VpcId: !Ref 'VPCNetwork' CidrBlock: 10.0.1.0/24 AvailabilityZone: us-east-1a SubnetFlowLog: Type: AWS::EC2::FlowLog Properties: ResourceId: !Ref 'VPCSubnet' ResourceType: Subnet TrafficType: REJECT LogDestinationType: cloud-watch-logs MaxAggregationInterval: 60 LogGroupName: !Ref 'LogGroup' DeliverLogsPermissionArn: !GetAtt 'FlowLogRole.Arn' LogFormat: ${version} ${vpc-id} ${subnet-id} ${instance-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${tcp-flags} ${type} ${pkt-srcaddr} ${pkt-dstaddr}
Using Terraform (AWS Provider)
01 Terraform configuration file (.tf):
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } } required_version = ">= 0.14.9" } provider "aws" { profile = "default" region = "us-east-1" } resource "aws_vpc" "vpc-network" { cidr_block = "10.0.0.0/16" instance_tenancy = "default" } resource "aws_subnet" "vpc-subnet" { vpc_id = aws_vpc.vpc-network.id cidr_block = "10.0.1.0/24" } resource "aws_cloudwatch_log_group" "log-group" { name = "cc-flow-log-group" } data "aws_iam_policy_document" "assume_role" { statement { effect = "Allow" principals { type = "Service" identifiers = ["vpc-flow-logs.amazonaws.com"] } actions = ["sts:AssumeRole"] } } resource "aws_iam_role" "flow-log-role" { name = "cc-flow-log-role" assume_role_policy = data.aws_iam_policy_document.assume_role.json } data "aws_iam_policy_document" "iam-policy" { statement { effect = "Allow" actions = [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "logs:DescribeLogGroups", "logs:DescribeLogStreams", ] resources = ["*"] } } resource "aws_iam_role_policy" "role-policy" { name = "iam-role-policy" role = aws_iam_role.flow-log-role.id policy = data.aws_iam_policy_document.iam-policy.json } resource "aws_flow_log" "subnet-flow-log" { subnet_id = aws_subnet.vpc-subnet.id traffic_type = "REJECT" log_destination_type = "cloud-watch-logs" log_destination = aws_cloudwatch_log_group.log-group.arn iam_role_arn = data.aws_iam_role.flow-log-role.arn }
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon CloudWatch console at https://console.aws.amazon.com/cloudwatch/.
03 In the navigation panel, under Logs, select Log groups, and choose Create log group.
04 On the Create log group setup page, in the Log group name box, provide a unique name for the necessary log group, then choose Create to confirm your action. This will be the AWS CloudWatch Logs log group to which the new flow log will be published.
05 Navigate to AWS VPC dashboard at https://console.aws.amazon.com/vpc/.
06 In the left navigation panel, under Virtual Private Cloud, click Subnets.
07 Select the subnet that you want to reconfigure (see Audit section part I to identify the right VPC resource).
08 Click the Subnet Actions dropdown button from the dashboard top menu and select Create Flow Log.
09 Within Create Flow Logdialog box, provide the following information:
- FromFilter dropdown list, select the filter that describes the type of traffic to be logged – accepted, rejected, or all.
- In theRole box, enter the name of the IAM role that will allow permissions to publish to the CloudWatch Logs log group created earlier. If you have not setup IAM permissions for the destination log group, click Set Up Permissions to create the necessary IAM role. On the VPC Flow Logs is requesting permission to use resources in your account page, click Allow button, without changing the default settings for the IAM role. Once created, go back to the Role box and select the name of the new IAM role, i.e. flowlogsRole.
- FromDestination Log Group, select the name of the newly created AWS CloudWatch Logs log group.
- Click Create Flow Log to enable the feature for the selected VPC subnet and create the necessary flow log.
10 Repeat steps no. 8 – 10 to enable flow logs for other Amazon VPC subnets, available in the selected region.
11 Change the AWS region from the navigation bar and repeat the process for other regions.
Using AWS CLI
01 First, define the trust relationship policy for the IAM role that will allow to publish to the CloudWatch Logs log group. To create the required trust relationship policy, paste the following information into a new policy document named iam-role-trust-policy.json:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "vpc-flow-logs.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
02 Run create-role command (OSX/Linux/UNIX) to create the necessary AWS IAM role using the trust relationship policy defined at the previous step (i.e. iam-role-trust-policy.json):
aws iam create-role --role-name cc-flow-logs-role --assume-role-policy-document file://iam-role-trust-policy.json
03 The command output should return the new IAM role metadata (including the role ARN):
{ "Role": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "vpc-flow-logs.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "RoleId": "AAAABBBBCCCCDDDDEEEEFFFF", "CreateDate": "2018-01-05T09:06:39.840Z", "RoleName": "cc-flow-logs-role", "Path": "/", "Arn": "arn:aws:iam::123456789012:role/cc-flow-logs-role" } }
04 Now define the permissions to publish flow logs to the specified log group in AWS CloudWatch Logs. To create the required IAM role policy, paste the following information into a new policy document named iam-role-publish-policy.json:
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "logs:DescribeLogGroups", "logs:DescribeLogStreams" ], "Effect": "Allow", "Resource": "*" } ] }
05 Run put-role-policy command (OSX/Linux/UNIX) to attach the inline policy defined at the previous step to the newly created IAM role (the command does not produce an output):
aws iam put-role-policy --role-name cc-flow-logs-role --policy-name flow-logs-publish-policy --policy-document file://iam-role-publish-policy.json
06 Run create-log-group command (OSX/Linux/UNIX) to create the necessary AWS CloudWatch Logs log group in the selected region (the command does not produce an output):
aws logs create-log-group --region us-east-1 --log-group-name cc-flow-logs-group
07 Run create-flow-logs command (OSX/Linux/UNIX) to enable Flow Logs feature for the selected VPC subnet (see Audit section part II to identify the right resource) by creating a new flow log. The following command example creates a flow log that captures all rejected traffic for a VPC subnet, identified by the ID "subnet-abcd1234". The flow logs are delivered to a log group in CloudWatch Logs named "cc-flow-logs-group", using an IAM role identified by the ARN "arn:aws:iam::123456789012:role/cc-flow-logs-role":
aws ec2 create-flow-logs --region us-east-1 --resource-type Subnet --resource-ids subnet-abcd1234 --log-group-name cc-flow-logs-group --deliver-logs-permission-arn arn:aws:iam::123456789012:role/cc-flow-logs-role --traffic-type REJECT
08 The command output should return the new flow log metadata:
{ "Unsuccessful": [], "FlowLogIds": [ "fl-abcd1234" ], "ClientToken": "/AAAABBBBCCCC/AAAA/AAAABBBBCCCCDDDDEEEE" }
09 Repeat step no. 7 and 8 to enable flow logs for other Amazon VPC subnets, available within the selected region.
10 Change the AWS region by updating the --region command parameter value and repeat steps no. 1 – 9 to perform the entire process for other regions.
References
- AWS Documentation
- Amazon VPC FAQs
- VPC Flow Logs
- Creating IAM Roles
- Creating a Role to Delegate Permissions to an AWS Service
- IAM Policies
- What is Amazon CloudWatch Logs?
- Working with Log Groups and Log Streams
- AWS Command Line Interface (CLI) Documentation
- ec2
- describe-subnets
- describe-flow-logs
- create-flow-logs
- iam
- create-role
- put-role-policy
- logs
- create-log-group