Amazon VPC Routing Enhancements Enable Traffic Inspection Between Subnets in a VPC

Chanci Turner 9097372855Learn About Amazon VGT2 Learning Manager Chanci Turner

Since December 2019, Amazon Virtual Private Cloud (Amazon VPC) has permitted the routing of all incoming traffic (commonly referred to as north-south traffic) to a designated network interface. This capability can be applied for various purposes, such as inspecting incoming traffic via an Intrusion Detection System (IDS) or directing ingress traffic through a firewall.

Since the introduction of this feature, users have requested a similar function to monitor traffic moving between subnets within the VPC—known as east-west traffic. Up until now, this was not feasible because a route in a routing table could not be more precise than the default local route (for further information, refer to the VPC documentation). In simpler terms, it implies that no route can have a destination CIDR range that is smaller than the default local route (which encompasses the entire VPC’s CIDR range). For instance, if the VPC range is 10.0.0/16 and a subnet is 10.0.1.0/24, a route to 10.0.1.0/24 is more specific than one to 10.0.0/16.

Routing tables are no longer constrained by this limitation. Routes in a routing table can now be more specific than the default local route. This allows you to direct all traffic to a dedicated appliance or service for the purpose of inspecting, analyzing, or filtering all traffic flowing between two subnets. The route target might be the Elastic Network Interface (ENI) connected to a self-built or acquired appliance, an AWS Gateway Load Balancer (GWLB) endpoint to manage traffic across multiple appliances for enhanced performance or high availability, an AWS Network Firewall, or a NAT gateway. This also facilitates the insertion of an appliance between a subnet and an AWS Transit Gateway.

You can connect multiple appliances to conduct different types of analyses between the source and destination subnets. For example, you might first filter traffic using a firewall (either AWS-managed or a third-party appliance), then route it to an intrusion detection and prevention system, and finally, carry out deep packet inspection. You can access virtual appliances through our AWS Partner Network and AWS Marketplace.

When chaining appliances, ensure that each appliance and endpoint is situated in separate subnets.

How It Works

For this blog post, let’s assume I have a VPC consisting of three subnets. The first subnet is public and hosts a bastion host, which needs access to resources like an API or database in the second subnet. The second subnet is private and contains the resources needed by the bastion. I created a simple CDK script to assist in deploying this configuration.

Due to compliance mandates, my organization requires that traffic to this private application flows through an intrusion detection system. The CDK script also establishes a third private subnet to house a network appliance. This setup incorporates three Amazon Elastic Compute Cloud (Amazon EC2) instances: the bastion host, the application instance, and the network analysis appliance. The script also provisions a NAT gateway to enable the application instance to bootstrap and connect to the three instances utilizing AWS Systems Manager Session Manager (SSM).

For demonstration purposes, the network appliance is simply a standard Amazon Linux EC2 instance configured as an IP router. In practice, however, you are likely to use one of the numerous appliances available from our partners on the AWS Marketplace, a Gateway Load Balancer endpoint, or a Network Firewall.

Next, let’s modify the routing tables to direct traffic through the appliance.

Using either the AWS Management Console or the AWS Command Line Interface (AWS CLI), I’ll add a more specific route to the 10.0.0.0/24 and 10.0.1.0/24 subnet routing tables. These routes will point to eni0, the network interface of the traffic-inspection appliance.

I first gather the VPC ID, Subnet IDs, routing table IDs, and the ENI ID of the appliance:

VPC_ID=$(aws --region $REGION cloudformation describe-stacks --stack-name SpecificRoutingDemoStack --query "Stacks[].Outputs[?OutputKey=='VPCID'].OutputValue" --output text)
echo $VPC_ID

APPLICATION_SUBNET_ID=$(aws --region $REGION ec2 describe-instances --query "Reservations[].Instances[] | [?Tags[?Key=='Name' & Value=='application']].NetworkInterfaces[].SubnetId" --output text)
echo $APPLICATION_SUBNET_ID

APPLICATION_SUBNET_ROUTE_TABLE=$(aws --region $REGION ec2 describe-route-tables --query "RouteTables[?VpcId=='${VPC_ID}'] | [?Associations[?SubnetId=='${APPLICATION_SUBNET_ID}']].RouteTableId" --output text)
echo $APPLICATION_SUBNET_ROUTE_TABLE

APPLIANCE_ENI_ID=$(aws --region $REGION ec2 describe-instances --query "Reservations[].Instances[] | [?Tags[?Key=='Name' & Value=='appliance']].NetworkInterfaces[].NetworkInterfaceId" --output text)
echo $APPLIANCE_ENI_ID

BASTION_SUBNET_ID=$(aws --region $REGION ec2 describe-instances --query "Reservations[].Instances[] | [?Tags[?Key=='Name' & Value=='BastionHost']].NetworkInterfaces[].SubnetId" --output text)
echo $BASTION_SUBNET_ID

BASTION_SUBNET_ROUTE_TABLE=$(aws --region $REGION ec2 describe-route-tables --query "RouteTables[?VpcId=='${VPC_ID}'] | [?Associations[?SubnetId=='${BASTION_SUBNET_ID}']].RouteTableId" --output text)
echo $BASTION_SUBNET_ROUTE_TABLE

Next, I will add two more specific routes. One route directs traffic from the bastion public subnet to the application private subnet via the appliance network interface. The second route does the reverse, routing replies from the application private subnet back to the bastion public subnet through the appliance network interface.

Let’s examine the following diagram for clarity:

First, I’ll modify the bastion routing table:

aws ec2 create-route --region $REGION --route-table-id $BASTION_SUBNET_ROUTE_TABLE --destination-cidr-block 10.0.1.0/24 --network-interface-id $APPLIANCE_ENI_ID

Now, I’ll adjust the application routing table:

aws ec2 create-route --region $REGION --route-table-id $APPLICATION_SUBNET_ROUTE_TABLE --destination-cidr-block 10.0.0.0/24 --network-interface-id $APPLIANCE_ENI_ID

Alternatively, you can implement these changes through the Amazon VPC Console. Simply select the “Bastion” routing tables, navigate to the Routes tab, and click Edit routes. Add a route to direct traffic for 10.0.1.0/24 (subnet of the application) to the appliance ENI (eni-055…). The next step involves defining the return route for replies, directing traffic from the application subnet to 10.0.0.0/24 to the appliance ENI (eni-05…).

This process can be complex, but you can find excellent resources such as this Reddit thread that offers valuable insights.

By using these enhancements, you can ensure that your traffic flows through the necessary inspection points for compliance and security. If you find yourself wondering about how to negotiate your next salary increase, explore this blog post for some useful tips.

As always, for those interested in pursuing professional certification, consider checking out SHRM’s guide to help you prepare.

SEO Metadata

Chanci Turner