AWS Security Groups (and Network ACLs and VPCs) are some of the fundamental building blocks of security in your cloud environment.
They are similar to firewalls but are not the same thing. You have to understand this topic very well before you begin building in the cloud, because there are some subtle differences in how they are used, and you need to follow best practices.
You should know your public cloud provider is contractually bound to honor its side of a shared responsibility model. But Security Groups are your responsibility. By default, when you launch an EC2 instance, the only default rule is port 22 for SSH access for Linux instances.
You’re going to need more. For example, you might be creating a web server that listens on both port 80 for HTTP and port 443 for HTTPS. And you want to make your web server available to the entire Internet, or 0.0.0.0/0 as we like to call it. Without Security Groups allowing traffic from 0.0.0.0/0 to port 80 and port 443, this traffic will be denied and your web service will be isolated.
So not only do you need Security Groups for security, but you also need to configure these correctly just to get basic traffic working.
In this blog post, you will learn the information and best practices you need for configuring and securing your network in your AWS cloud.
What are Security Groups in AWS?
In AWS, a Security Group is a collection of rules that control inbound and outbound traffic for your instances. When you launch an instance, you can specify one or more Security Groups.
NOTE: We can’t talk about Security Groups without mentioning Amazon Virtual Private Cloud (VPC). Amazon VPC is a virtual network that resembles a traditional network. Like a traditional network, your VPC has IP addresses, subnets, route tables, Internet gateways, and more. And of course, your VPC also needs some kind of firewall filtering which leads us to Security Groups.
If you don’t specify a Security Group, Amazon EC2 uses the default Security Group. For example, after you associate a Security Group with an EC2 instance, inbound and outbound traffic for that instance will follow the rules of the Security Group. Security Groups apply to just instances, not the whole subnet.
Security Groups are stateful, ingress equals egress. Traffic that matches a rule for one direction will also be allowed automatically in the opposite direction.
Security Groups are found under the EC2 Service in the AWS Console:
And as you might expect, Security Groups are also found under the EC2 Service in the AWS CLI. Here we can see how we create a Security Group:
aws ec2 create-security-group --group-name web-pci-sg --description "allow SSL traffic" --vpc-id vpc-555666777
And here we use the AWS CLI to add a rule to our Security Group:
aws ec2 authorize-security-group-ingress \ --group-name web-pci-sg \ --protocol https \ --port 443 \ --cidr <IP Subnet/Netmask>
Here is an example of AWS Security Groups associated with an instance:
Note that you can’t create deny rules for Security Groups – you can only create allow rules. Deny is by default. Below, notice you can only create “allow” rules and anything not permitted is denied.This can be confusing for beginners:
Why do you need Security Groups?
You need Layer 3 and Layer 4 filtering in the cloud, just as you would in the physical world. And traditional firewalls might work, but a virtual firewall that is not cloud-native might add administrative overhead and cost.
Security groups have several advantages. An obvious advantage is they are free, you can use as many of them as you like They can be applied on top of different services, you can create them beforehand, and they are reusable. Create Security Groups like you would categories, then apply them to groups of instances that need a common filtering strategy.
Contrast this to configuring local firewalling such as iptables on individual instances. You would have to try to do it through scripting, userdata injection, or some other method, and Security Groups start to look like a better approach.
Which services need Security Groups?
Although most commonly used with EC2 compute instances, many AWS services rely on Security Groups.
Of these services, Amazon EC2 is one of the most widely used. You should look further into this if you are wondering how to secure Amazon EC2 in general, especially if you want to fully understand securing SSH on Amazon EC2.
But more than just Amazon EC2, all the following AWS services rely on Security Groups in some way:
- Amazon EC2 instances
- AWS Lambda
- AWS Elastic load balancing
- Databases (Amazon RDS, Amazon Redshift)
- Other (ElastiCache, CloudSearch, Elastic Beanstalk, Elastic MapReduce)
- Container and Kubernetes services (ECS and EKS)
What are Network Access Lists?
In AWS, Network access control lists (NACLs) are a collection of rules that control inbound and outbound traffic for subnets. NACLs rules are similar to Security Groups, but they apply to the whole subnet, not individual instances.
NACLs are stateless, ingress does not equal egress. Traffic that matches a rule for one direction will not be automatically allowed in the opposite direction. You would have to add an outbound rule.
Like Security Groups, NACLs are part of the EC2 service as shown here in the AWS CLI:
Using the AWS CLI we create a NACL:
aws ec2 create-network-acl --vpc-id vpc-a01106c2
And here we create a rule for our nacl:
aws ec2 create-network-acl-entry --network-acl-id acl-5fb85d36 --ingress --rule-number 100 --protocol udp --port-range From=53,To=53 --cidr-block 0.0.0.0/0 --rule-action allow
However, and this is not obvious: in the AWS Console, you won’t find NACLs in the EC2 service, instead you find them under the VPC Service:
Here is an example of some NACLs and as you can see, they are associated with subnets, not with instances:
Remember that unlike Security Groups which only have allow rules, NACLs have both allow and deny rules:
So as shown here you can add both Allow and Deny rules because this is a NACL, not a Security Group.
How do AWS Security Groups and Network ACLs work together?
AWS Security Groups and AWS NACLs can be used to secure your network—on their own and together. When following best practices, NACLs and Security Groups provide very effective protection at Layers 3 and 4. Just remember, they do not protect against volumetric DDOS or any sophisticated attacks. For this type of protection at Layers 3 and 4 you could consider options such as AWS Shield. For layer 7 protection you need a Web Application Firewall. AWS Security Groups and Network ACLs will not help at layer 7.
How are these two filtering services similar, and how are they different? There are several key areas to look at:
Area | AWS Security Group | AWS Network ACL |
Scope | Operates at the instance level | Operates at the subnet level |
Association | Applies to an instance only if it is associated with the instance | Applies to all instances deployed in the associated subnet (providing an additional layer of defense if Security Group rules are too permissive) |
Quantity Limits | Instance can have multiple Security groups. The initial quota is 2500 per VPC with 60 rules per group. | Subnet can have only one NACL. The initial quota is 200 per VPC. |
Destination | Destination can be a CIDR subnet, specific IP address, or another Security group | Destination can only be a CIDR subnet, |
Implicit Deny | Implicit Deny. You can only add “allow” rules. | Implicit Allow. You can add “allow” rules and “deny” rules |
Evaluation Order and Logic | All rules are evaluated to decide to allow or deny traffic. The most permissive rule is applied. | Rules in the NACL are evaluated in order, starting with the lowest numbered rule. If traffic matches a rule, the rule is applied and no further rules are evaluated. |
Stateful vs Stateless | Stateful: Ingress == Egress. Response traffic is allowed by default. | Stateless: Ingress != Egress. Return traffic must be explicitly allowed by rules |
It can be helpful to visualize the stateful nature of AWS Security Groups vs the stateless nature of network ACLs.
Here we see that without any outbound rules on the network ACL, traffic is blocked outbound, but with the outbound rule added, traffic flows correctly.
Whereas with the Security Group, because it is stateful, traffic is permitted outbound automatically once the inbound connection is established.
AWS CIS Benchmarks
Once you have understood and deployed your Security Groups, you should consider checking them against one or more benchmarks. particularly if you have a large cloud, it is going to be very difficult to keep track of which Security Groups are configured correctly.
Industry benchmarks specify requirements for AWS Security Groups. Here we will look at two benchmarks: The CIS AWS Foundations Benchmark and PCI-DSS Standard.
Security Groups in the CIS AWS Foundations Benchmark 1.5
This CIS AWS Guidelines and Benchmarks 1.5 includes the following controls for Security Groups and network ACLs. To obtain the latest version of this guide, including steps on how to configure these recommendations, please visit https://benchmarks.cisecurity.org and you can check that page for updates.
CIS AWS Recommendation | Description |
2.3.3 Ensure that public access is not given to RDS Instance (Automated) | To restrict access to any publicly accessible RDS database instance, you must disable the database Publicly Accessible flag and update the VPC Security Group associated with the instance. |
4.10 Ensure a log metric filter and alarm exist for Security Group changes (Automated) | Monitoring changes to Security Groups will help ensure that resources and services are not unintentionally exposed. |
5.1 Ensure no Network ACLs allow ingress from 0.0.0.0/0 to remote server administration ports (Automated) | It is recommended that no NACL allows unrestricted ingress access to remote server administration ports, such as SSH to port 22 and RDP to port 3389. |
5.2 Ensure no Security Groups allow ingress from 0.0.0.0/0 to remote server administration ports (Automated) | It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port 22 and RDP to port 3389. |
5.3 Ensure no Security Groups allow ingress from ::/0 to remote server administration ports (Automated) | This is the IPv6 version of the above. It is recommended that no security group allows unrestricted ingress access to remote server administration ports, such as SSH to port 22 and RDP to port 3389. |
5.4 Ensure the default security group of every VPC restricts all traffic (Automated) | A VPC comes with a default security group whose initial settings deny all inbound traffic, allow all outbound traffic, and allow all traffic between instances assigned to the security group. |
AWS Security Groups in the PCI-DSS Standard
Another important standard if you are taking payment cards on your website is the PCI Standard. This standard was created by the payment card brands. Validation of compliance is performed annually or quarterly. The full PCI standard is available at https://www.pcisecuritystandards.org/
AWS describes the following PCI controls for security group rules on its’ page and more details can be found there on how to configure the controls. You can keep an eye on that page for updates.
PCI DSS Requirement | Description |
PCI DSS 1.2.1: Restrict inbound and outbound traffic to that which is necessary for the cardholder data environment (CDE), and specifically deny all other traffic. | If a service that is in scope for PCI DSS is associated with the default security group, the default rules for the security group will allow all outbound traffic. The rules also allow all inbound traffic from network interfaces (and their associated instances) that are assigned to the same security group. |
PCI DSS 1.3.4: Do not allow unauthorized outbound traffic from the cardholder data environment to the internet. | Same as above |
PCI DSS 2.1: Always change vendor-supplied defaults and remove or disable unnecessary default accounts before installing a system on the network. | Same as above |
PCI.EC2.5 Security groups should not allow ingress from 0.0.0.0/0 to port 22 | This control checks whether Security Groups in use disallow unrestricted incoming SSH traffic. |
PCI.RDS.2 Amazon RDS DB Instances should prohibit public access, determined by PubliclyAccessible configuration | You should also ensure VPC subnet routing does not allow public access, and that the security group inbound rule associated with the RDS instance does not allow unrestricted access (0.0.0.0/0). |
AWS Security Groups best practices
The following best practices are general guidelines. These are not a comprehensive deployment guide, and may not cover all use cases but are a great starting point.
- Security group rules should not have large port ranges. Doing so makes your attack surface much larger.
- VPC flow logs should be, at a minimum, enabled on inter-VPC flows and internet flows. Logging traffic within the same VPC can be useful for debugging. For more information, see Publish flow logs to CloudWatch Logs.
- Remove unused Security Groups. Large numbers of unused or unattached Security Groups create confusion and invite misconfiguration. Remove any unused Security Groups.
- Limit modification to authorized roles only. Not every user or IAM role should be able to modify Security Groups.
- Monitor the modification of Security Groups. It is important to know when a security group is created or deleted or changed, as this has security implications.
- Don’t ignore the outbound or egress rules Limit outbound access to just the subnets that are needed. For example, in a three-tier web application, the app layer likely shouldn’t have unrestricted access to the internet, so configure the security group to allow access to only those hosts or subnets needed for the application to function correctly.
If you want to dig deeper, take a look at AWS security best practices.
Managing AWS Security Groups
You need constant monitoring and visibility of your Security Groups to keep them correctly configured.
If you have more than a few Security Groups, you will need to use the AWS CLI or AWS API as these are much easier than using the AWS console, which can be very tedious and error-prone.
You also have the option of enabling and deploying AWS Firewall Manager which in some ways addresses this pain. But it comes with an additional cost and conditions such as requiring AWS Organizations. But if you can handle it, AWS Firewall Manager will allow you to audit existing Security Groups for your Amazon EC2, Application Load Balancer (ALB) and ENI resource types and configure new Security Groups.
Verifying AWS Security Groups
You may have a small or large cloud, but no matter the size, it can be very painful to try to manually confirm you have Security Groups configured safely. Instead, consider using Cloud Security Posture Management (CSPM) tools to help you understand if your Security Groups are correctly configured.
Even basic CSPM is helpful, but you should also be aware of advanced policy tools that allow you to create custom policies. And no mention of CSPM is complete without also mentioning continuous scanning. Continuous scanning catches the risky changes made to your cloud between CSPM scans.
AWS CloudTrail by default does a great job of logging all changes, and continuous cloud threat detection can be built on top of this. If you would like to learn more, you should read our AWS Threat Detection blog post.
Conclusions
Knowing how Security Groups and NACLs work together is extremely important for controlling network traffic to your instances and subnets. If you do not understand this, you will run into difficulties and potentially risk exposure.
Once you deploy your Security Groups the right way, you need to validate your deployment and check for threats and drift. One good approach is by using CSPM tools that run daily scans combined with continuous scanning of AWS CloudTrail logs to alert when Security Groups are added, deleted, or changed.
AWS Security Groups and NACLs are not hard to use once you understand them.
Follow the AWS Security Groups best practices listed in this article and get your Security Groups under control.