Uncover hidden risks

Watch how the Wiz platform can expose unseen risks in your cloud environment without drowning your team in alerts.

AWS security groups best practices

AWS security groups (SGs) are virtual firewalls for your EC2 instances that control both inbound and outbound traffic.

7 min read

AWS security groups: A refresher

AWS security groups (SGs) are virtual firewalls for your EC2 instances that control both inbound and outbound traffic. Security groups play a fundamental role in AWS best practices. Each security group consists of rules that filter traffic, allowing or denying requests based on parameters like IP protocol, port number, and source/destination IP address or CIDR block.

When you create an instance, it can be linked to one or more security group(s). AWS automatically supplies a security group for each VPC by default. Still, to adhere to AWS default security group best practices, customize and create security groups tailored to your application needs.

Figure 1: AWS security group overview (Source: AWS Docs)

The differences between security groups and network ACLs

Both AWS security groups and network access control lists (NACLs) control inbound and outbound traffic, but they operate at different layers and have distinct characteristics:

  • Scope: Security groups are associated with EC2 instances, while NACLs are associated with subnets.

  • Statefulness: Security groups operate in a stateful manner. This means that when an incoming request from an IP is permitted, its response is automatically authorized, irrespective of the outbound rules. On the other hand, NACLs are stateless, so inbound and outbound traffic rules are treated separately.

  • Rule evaluation: In AWS security groups, rules are evaluated based on the principle that the most specific rule wins. For NACLs, rules are assessed sequentially, beginning with the rule that has the lowest number.

  • Rule types: Security groups accommodate only ALLOW rules, while NACLs accommodate both ALLOW and DENY rules.

Understanding these differences is a crucial part of designing a robust and secure AWS infrastructure. By harnessing the unique features of both security groups and NACLs, organizations can achieve a more layered and effective defense strategy.

Best practices and recommendations

Leverage the least-privilege principle

The principle of least privilege ensures that resources are accessible only to those entities that absolutely need it. Follow these three tips to implement the least-privilege principle effectively:

Best practice: Start with a “deny-all” rule

Starting with a ”deny-all” rule blocks unintended traffic. This is a foundational step in AWS best practices for security groups. By denying all traffic by default, you create a secure baseline and then explicitly allow only the necessary traffic. Use this code to create a security group with a "deny-all" default setting:

aws ec2 create-security-group --group-name MySecurityGroup --description "My security group with deny-all default"

Best practice: Allow specific IPs or CIDR blocks

Opening up your resources to the entire internet (0.0.0.0/0) is a significant security risk. We always recommend being as selective about access as possible when defining your security group rules. This minimizes your potential attack surface.

When specifying rules, consider the principle of granularity. For instance, if only one IP address needs access to a resource, don't allow an entire CIDR block. Use this code to grant access to a specific CIDR block for SSH (port 22) on your security group:

aws ec2 authorize-security-group-ingress --group-name MySecurityGroup --protocol tcp --port 22 --cidr 201.0.100.0/24

Best practice: Design SG rules based on user roles

By categorizing your EC2 instances based on their roles, you can design security groups tailored to each role's specific needs. Role-based access ensures that each instance type has only the necessary ports open, reducing potential vulnerabilities.

For instance, a database server might only need its database port (e.g., 3306 for MySQL) open, while a web server might require ports 80 and 443:

aws ec2 authorize-security-group-ingress --group-name WebServerSG --protocol tcp --port 80 --cidr 0.0.0.0/0 aws ec2 authorize-security-group-ingress --group-name WebServerSG --protocol tcp --port 443 --cidr 0.0.0.0/0

Consider the stateful nature of SGs

Best practice: Know that two-way traffic is allowed

Due to the stateful nature of AWS security groups, if an inbound rule allows traffic from a specific IP, the return traffic is automatically allowed, even if there's no corresponding outbound rule. For instance, the following security group will allow two-way traffic over port 80 for the CIDR range:

aws ec2 authorize-security-group-ingress --group-name MySecurityGroup --protocol tcp --port 80 --cidr 201.0.100.0/24

Avoid overly permissive rules

Overly permissive rules can expose your resources to unnecessary risks. It's essential to strike a balance between accessibility and security. Follow these two best practices to strike that balance:

Best practice: Mitigate the risks of 0.0.0.0/0

Allowing traffic from all IPs with 0.0.0.0/0 CIDR range can expose your resources to various threats, from brute force attacks to potential data breaches. Sensitive ports like SSH (22) or RDP (3389) should not be made public. (That said, remember to restrict access to only those IPs or CIDR blocks that genuinely need it.) For instance, the following can expose your instances to potential brute force attacks from all over the world:

aws ec2 authorize-security-group-ingress --group-name MySecurityGroup --protocol tcp --port 22 --cidr 0.0.0.0/0

Best practice: Advocate for adding trusted IPs to your allowlist

Instead of focusing on what to block, focus on what to allow. Adopting an allowlist approach ensures that only known and trusted entities can access your resources. For instance, if you have an API server, allow only traffic on ports 80 and 443 that comes from trusted sources:

aws ec2 authorize-security-group-ingress --group-name MySecurityGroup --protocol tcp --port 22 --cidr 180.170.1.0/24

Carry out regular audits

As your infrastructure grows and changes, it's crucial to regularly audit your security groups to ensure they still align with best practices and your organization's requirements.

Best practice: Use automation tools

Using tools to automate the audit process can save time and streamline your processes. AWS offers various services, like AWS Config, that can monitor changes in your security groups and ensure they comply with best practices. This proactive approach gives you peace of mind that potential issues are identified and rectified promptly. The following code snippet sets up an AWS Config rule named "restricted-ssh" that checks if security groups allow unrestricted SSH traffic and ensures only the specified CIDR block (201.0.111.0/24) has access to port 22:

aws configservice put-config-rule --config-rule '{
  "ConfigRuleName": "restricted-ssh",
  "Description": "Checks whether security groups allow unrestricted SSH traffic",
  "Scope": {
    "ComplianceResourceTypes": ["AWS::EC2::SecurityGroup"]
  },
  "Source": {
    "Owner": "AWS",
    "SourceIdentifier": "RESTRICTED_INCOMING_TRAFFIC"
  },
  "InputParameters": "{\"blockedPort1\":\"22\",\"allowedCidr\":\"201.0.111.0/24\"}"
}'

Name and describe

Properly naming and describing your security groups can simplify management, especially as your infrastructure grows.

Best practice: Use standardized naming conventions

Adopting a consistent naming convention can help quickly identify a security group's purpose, particularly when you’re dealing with multiple security groups across different environments and projects. For instance, using a format like <ProjectName>-<Environment>-<Role> can provide clarity at a glance. A security group named "MyApp-Prod-WebServer" instantly conveys its purpose.

aws ec2 create-security-group --group-name MyApp-Prod-WebServer --description "Production WebServer for MyApp"

Restrict outbound traffic

While a lot of emphasis is placed on controlling inbound traffic, managing outbound traffic from your EC2 instances is equally crucial.

Best practice: Prevent data exfiltration

Unrestricted outbound traffic can lead to potential data breaches, where malicious entities might exfiltrate sensitive data from your instances. For example, it could be helpful to restrict outbound traffic to allow only HTTPS (port 443) traffic:

aws ec2 authorize-security-group-egress --group-id sg-0123456789abcdef0 --protocol tcp --port 443 --cidr 0.0.0.0/0

Best practice: Customize access for third-party integrations

Ensure that your instances communicate exclusively with trusted external services. Unrestricted access can expose your resources to vulnerabilities in third-party services. If you need to integrate third-party services, allow outbound traffic only on a specific external service IP:

aws ec2 authorize-security-group-egress --group-id sg-0123456789abcdef0 --protocol tcp --port 443 --cidr <Third-Party-Service-IP>/32

Integrate with AWS flow logs

Flow logs provide a deep look into your VPC traffic, aiding in monitoring and troubleshooting.

Best practice: Maintain visibility 

By analyzing flow logs, you can understand traffic patterns, detect anomalies, and troubleshoot connectivity issues. Enabling flow logs for a VPC is straightforward:

aws ec2 create-flow-logs --resource-type VPC --resource-ids vpc-0123456789abcdef0 --traffic-type ALL --log-destination-type cloud-watch-logs --log-group-name MyFlowLogs

Best practice: Implement a retention policy

Set up policies for how long to retain your logs, balancing between storage costs and historical data needs. For instance, you can set a retention policy of 30 days for a CloudWatch Logs group:

aws logs put-retention-policy --log-group-name MyFlowLogs --retention-in-days 30

Create backup and recovery protocols

Ensuring that your security group configurations are backed up and can be quickly restored is crucial for business continuity.

Best practice: Back up your SG rules

Regularly back up your security group rules to ensure you can quickly recover from misconfigurations or failures. It’s easy to get a security group description and save it as a JSON file:

aws ec2 describe-security-groups --group-names MyWebSG > MyWebSG-backup.json

Best practice: Plan for disaster recovery

In case of emergencies or failures, have a plan in place to restore your security groups from backups. This plan should detail the steps to follow and the personnel responsible for each action. Regularly review and test this plan to ensure its effectiveness.

By following these best practices and regularly reviewing and updating your configurations, you can ensure that your AWS resources remain secure and resilient against potential threats.

Going beyond the basics

As you become more familiar with AWS security groups and start to master foundational best practices, it's essential to explore advanced tools and integrations that can further enhance your security posture. This section delves into these advanced topics, helping you keep your AWS infrastructure not only secure but also efficient and optimized.

Enhanced AWS tools for security groups

AWS offers a range of tools that can complement and enhance the capabilities of security groups, including VPC Traffic Mirroring, Shield, and WAF. Let’s take a look at each:

AWS VPC Traffic Mirroring

This feature allows you to capture and inspect network traffic on your VPC. By mirroring your traffic, you can identify anomalies or suspicious activities that traditional security tools might miss.

Figure 2: AWS VPC Traffic Mirroring overview (Source: AWS Docs)

AWS Shield

As its name suggests, this is a comprehensive service designed to shield AWS-based applications from distributed denial-of-service (DDoS) attacks. Integrating AWS Shield with your security groups can provide an additional layer of protection against DDoS attacks.

Figure 3: AWS Shield overview (Source: AWS Shield)

AWS WAF (web application firewall)

While security groups act at the instance level, AWS WAF operates at the application layer. It inspects web requests and can block common web-based attacks like SQL injections and cross-site scripting (XSS).

aws wafv2 create-web-acl --name "MyWebACL" --scope REGIONAL --default-action Allow={} --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=WebAclExample
Figure 4: AWS WAF Overview (Source: AWS WAF)

As we’ve seen, there’s a lot to consider when it comes to AWS security groups. To make sure you always have AWS security group best practices at your fingertips, download our comprehensive cheat sheet. This quick reference guide will help you follow the best practices described in this article—whether you're a beginner or an AWS expert.

And to enhance your AWS security posture further, schedule a demo of Wiz. Our industry-leading cloud security platform offers a holistic view of risks across your entire AWS environment. Trust Wiz to secure everything you build and run in the cloud.

Agentless full stack coverage of your AWS Workloads in minutes

Learn why CISOs at the fastest growing companies choose Wiz to help secure their AWS environments.

Get a demo

Other security best practices you might be interested in:

Continue reading

Credential Stuffing Explained

Wiz Experts Team

Credential stuffing is a type of cyberattack where automated tools are used to repeatedly inject stolen username/password combinations into various services to gain access to legitimate users’ accounts in addition to those that were originally breached.

Container Orchestration

Container orchestration involves organizing groups of containers that make up an application, managing their deployment, scaling, networking, and their availability to ensure they're running optimally.

Native Azure Security Tools

Wiz Experts Team

This blog explores the significance of security in Azure environments and provides an overview of native as well as third-party security tools available to improve an organization’s Azure security stance.

Cross-site scripting

Wiz Experts Team

Cross-site scripting (XSS) is a vulnerability where hackers insert malicious scripts inside web applications with the aim of executing them in a user’s browser.