Amazon Virtual Private Cloud (Amazon VPC) is an AWS service that enables you to launch AWS resources within your own virtual network. Because you can deploy VPCs in separate regions and other VPC components themselves are deployable across different Availability Zones, VPC-hosted environments tend to be highly available and more secure.
Additionally, with Amazon VPC you can use an isolated segment of AWS to control your networked resources’ internet access and shield them from bad actors. This capability is particularly important from a security point of view because it grants you granular control over the accessibility of your resources to prevent overexposure. But while overexposure to the internet can leave your network vulnerable to attacks, some of your networked resources—such as user-facing application components—will still need to be publicly accessible. Some resources may also need internet access to download web-hosted libraries and patches to keep your application up to date.
In this guide, we’ll take a look at a few best practices for how to configure your Amazon VPC to reduce your attack surface while ensuring your application is fully functional.
An Amazon VPC consists of the following key components, which each have their own configuration options:
How you configure these components can vary depending on your use case. For instance, a VPC that regularly receives requests from external customers over the internet will be configured very differently from a VPC that only communicates with other VPCs, even if they consist of similar components.
Classless Inter-Domain Routing (CIDR) Blocks are a method of specifying a range of IP addresses available within your virtual network. Each address in a CIDR block is assigned to one of the networked resources in your VPC. A CIDR block consists of an IP address prefix representing the smallest IP address value available in your network, followed by a suffix value between 0 and 32 which describes the total size of the network. The number of addresses available in a network is defined by the formula 232-n, where n is the suffix value of your CIDR block. For example, the CIDR block
10.0.0.0/24 describes a range of 256 IP addresses (232-24 =28 =256), between
|CIDR Block||IP Range|
|10.0.0.0/16||10.0.0.0 - 10.255.255.255|
|172.16.0.0/24||172.16.0.0 - 172.16.0.255|
From a security standpoint, CIDR blocks are important because they define how resources in your VPC are logically segmented. When choosing a CIDR block for a VPC, there are a few important things to consider to ensure that your VPC remains functional and secure. First, make sure that you choose a range that is large enough to support all of the networked resources you plan to include in your VPC. For instance, large companies hosting several hundred EC2 instances will need a CIDR block that offers more than the 256 addresses that are available with
The Internet Assigned Numbers Association (IANA) reserves ranges of IP addresses that can be used for private and local networks, including
192.168.0.0/16. You should use a CIDR block that falls within one of those reserved ranges to ensure your network isn’t publicly routable. Additionally, if you are using more than one VPC, you should make sure their CIDR blocks don’t overlap in order to avoid routing issues.
CIDR blocks can be partitioned into one or more ranges of IP addresses called subnets. Each subnet represents an isolated segment of your VPC where you can place networked resources such as Amazon EC2 and Amazon RDS instances. Subnets host most of your networked resources, which means subnet security is crucial to the overall security of your VPC.
One important decision you’ll need to make when configuring a subnet is whether to make it public or private. Whereas resources within a private subnet can’t be reached through the internet, resources placed in a public subnet can be and are therefore more vulnerable to attack. You can improve the security of a public subnet with virtual firewalls, which help control which traffic is permitted to enter and exit your VPC. For instance, if you are using one of AWS’s default VPCs which are pre-configured with a public subnet, consider adding traffic restrictions with an access control list.
If your VPC hosts resources that need to communicate with external clients and execute tasks such as downloading updates and resources from the web, it will need to connect to the public internet. There are two mechanisms you can use to enable traffic in your VPC. The first is an Internet gateway (IGW), which is used to facilitate two-way traffic between your VPC and the public internet. Only a single IGW needs to be attached to your VPC in order for you to direct inbound and outbound traffic to the rest of your networked resources.
The second mechanism for connecting to the internet is a Network Address Translation (NAT) gateway, which is used to enable outward-bound traffic only. NAT gateways are particularly useful in cases in which a resource within a private subnet needs to read from an internet-hosted resource like a GitHub repository, without the private subnet itself being accessible to the wider internet.
You should note that NAT gateways are not an alternative to IGWs; instead, they work with IGWs to provide internet access. As you can see in the diagram below, a private subnet must first make a request to a NAT gateway placed within a public subnet before it can reach the internet through your VPC’s IGW.
Route tables define where traffic throughout your VPC should be headed based on its target IP address. Each route in a table consists of a destination, which is defined as a CIDR block, and a target, which is typically a gateway or instance within your VPC. For instance, let’s say you have a route table with the following routes:
Any traffic sent to an IP address that falls within the CIDR block
10.0.0.0/24 will be sent to a
local target, meaning that traffic will stay within your VPC. Any other traffic will be sent to the internet gateway named
igw-09876, as illustrated in the diagram below.
Now that we’ve looked at the various components of a VPC, let’s talk about how you can protect them from potential attacks with virtual firewalls provided by AWS. Virtual firewalls contain a granular set of rules that enable you to fine-tune which traffic is allowed in and out of your subnets and the networked resources residing within them. As a best practice, you should try to create rules that allow traffic from only the sources that are necessary to your application’s functionality. In this post, we will discuss two main types of virtual firewalls:
Network access control lists (ACLs) are a group of rules that apply to inbound and outbound traffic at the subnet level. ACL rules specify what type of traffic is allowed and consist of a source, defining a range of IP addresses that can access a resource, as well as a protocol and port. The order in which you define these rules impacts which traffic is allowed; that is, the first rule that traffic matches will be the rule that’s applied. For example, the network ACL rules in the table below are configured to allow any incoming TCP traffic from port 443 and deny all other inbound traffic. If this order were reversed, however, all incoming traffic would be denied, regardless of any other rules.
|Inbound / Outbound||Type||Protocol||Port Range||Source||Allow / Deny|
In contrast to ACLs, which control traffic at the subnet level, security groups define which traffic is allowed in and out of specific resources in your VPC. In practice, you should use network ACLs to define broad traffic rules that you want to apply to every instance within a subnet, and then fine tune the internet accessibility of specific instances by applying security groups. Like ACLs, a security group consists of a source, a protocol, and a port. For example, the inbound security group below allows TCP traffic on port 443 (HTTPS) from any IP address within the CIDR block
10.0.0.0/24. You can associate this security group to a particular EC2 instance within one of your subnets to ensure it only receives traffic from port 443, which is more secure than port 80, the default HTTP port.
You can also create outbound security group rules to define what IP addresses can be reached by instances the security group is associated with. The outbound security group below allows TCP traffic over port 443 to any IP address.
When you create security groups, it’s important to ensure that they’re not overly permissive. Security groups with overly permissive traffic rules can leave your instances open to potential security threats like SSH brute force attacks, as they can unintentionally allow SSH access from unrecognized addresses. In the next part of this series, we’ll look at how you can use Datadog to detect overly permissive rules so you can then add further restrictions.
So far, we’ve looked at the different components of a VPC, as well as how you can configure them to ensure their security. We also discussed how virtual network firewalls can act as your first line of defense against potential attacks by limiting which traffic can reach your networked resources. But configuring your VPC to be secure doesn’t guarantee its security. You also need visibility into your VPC’s network activity to verify that your resources are properly protected. In the next part of this series, we’ll look at how Datadog’s AWS integration and Cloud SIEM platform can help you better understand network traffic and detect signs of attacks.
If you’re not already a Datadog customer, sign up for a 14-day free trial.