Have you ever wondered how your AWS resources are distinguished from those that belong to other users? AWS networks are logically isolated through something called a Virtual Private Cloud (VPC). If you have launched an instance within AWS in the past, then you’ve already used a VPC. Every AWS account comes with a default VPC for each region and these default VPCs are used when a subnet-ID is not specified.
Why care about VPCs?
VPCs and its components offer you control over your networks. A common reason to create your own non-default VPC is to meet compliance requirements. Perhaps your network needs to be in a specific region or that it should not be accessible by the internet. We will explore how these requirements can be implemented in VPCs and its components.
What is a VPC?
A VPC is denoted by specifying a range of IP addresses in the form of a Classless Inter-Domain Routing (CIDR) block. For example: 10.0.0.0/16. The first part (10.0.0.0) is the starting IP address. The second part (16) is the mask bits, this denotes the size of the block in terms of how many bits are in the address. The actual value can be expressed as 2^(32-x). In our example, x is 16 so the range is 65,536. In simple terms, the CIDR notation tells us where the network is and how big it is.
You can then add one or more subnets in the VPC. A VPC resides in one AWS region and spans all of its Availability Zones, while each subnet resides in one availability zone. A subnet is a range of IP addresses in the VPC and are defined using the CIDR block too.
Now you can launch AWS resources like EC2 instances in a specific subnet. The diagram above is a common VPC configuration with a public and private subnet. This configuration allows instances launched on the public subnet to be accessible by the internet, while the private subnet would block access from the internet. For example, you may want such a configuration so that your web servers can be accessed from the internet whilst your databases are only to be accessed by other subnets within your VPC.
Let’s have a high-level look at some of the networking components in VPCs that we could use to allow or deny traffic.
Networking components in VPCs
A VPC can have an Internet Gateway, this device is what allows traffic from the internet to flow in and out of the network.
A Network Access Control List (NACL) acts as a firewall to allow or deny inbound/outbound traffic of a subnet.
The default NACL allows all traffic to flow in and out of subnets. In practice, it would be wise to make the NACL as specific as possible, though the default NACL would work for our public subnet.
For those that wish to know what each column represents:
|Rule Number||Rules are prioritised by its number from lowest-first. Traffic that matches the lowest rule will be applied regardless of any higher-numbered rule that might contradict it.|
|Type||The type of traffic (SSH, HTTP, etc). You may specify to match ALL types of traffic.|
|Protocol||Any protocol that has a standard protocol number. (ICMP, TCP, etc). You may specify ALL for any protocol.|
|Port Range||Port range of the traffic being matched.|
|Source / Destination||Source of the traffic for inbound rules or destination of the traffic for outbound rules.|
|Allow/Deny||Let pass or block matching traffic.|
The default state of a newly created custom NACL will act as a whitelist and deny all traffic. We can create one for the private subnet and add rules to allow communication with the public subnet by providing its CIDR block for the destination IP.
The AWS documentation recommends these rules when using a public and private subnet configuration where the private subnet can still access the internet through the public subnet.
A NACL is assigned to a subnet to specify access rules shared between instances on a subnet level. If you want more granular control, you can define a security group and assign it to individual instances.
|Security Group||Network ACL|
|Applied on an instance level||Applied on a subnet level|
|Allow rules only||Allow or Deny rules|
|Stateful: return traffic is automatically allowed.||Stateless: return traffic must be allowed.|
|All rules are evaluated when deciding to allow traffic.||Lowest rule number is applied when deciding to allow traffic.|
It is possible to allow our private subnet access using a Network Address Translation (NAT) gateway and redirecting traffic with a route table. A NAT gateway communicates with the internet as a proxy, hiding the IP address of the resources in the private subnet. We can create a NAT gateway in the public network and the private subnet’s associated route table will send all outbound traffic to the NAT gateway.
The private subnet route table would look like this:
The first entry in the route table is the default entry that allows instances in the subnet to communicate with each other. The second entry sends all traffic that goes outside of this subnet to the NAT gateway.
The public subnet’s route table would have all non-local traffic be routed to the internet gateway instead.
The NAT gateway will then flow through the internet gateway. This allows the private subnet to connect to the internet for software updates, but the internet still cannot establish a connection with instances inside the private subnet.
As we can see, VPCs are essential in the AWS ecosystem as an extremely important tool for security and compliance. We have only covered the very basics and one could delve much deeper into the topic (I would suggest starting with the AWS documentation for those that are interested). I hope you found this post useful in understanding what VPCs are and how you can prevent unwarranted traffic from entering or leaving your AWS network.