UTMStack

Articles, updated 11 min read

AWS Security Groups: How They Work, Security Group vs NACL

By UTMStack Team

How do AWS Security Groups work?

Security groups are the firewall you use most in AWS, and also the one most often left too open. One rule that allows SSH from anywhere, or one database port exposed to the internet, is enough to turn a private server into a public target. Getting them right is mostly about understanding a few behaviors that are not obvious from the console.

This guide explains how AWS security groups work, their default rules and limits, how referencing other groups works, how they differ from network access control lists (network ACLs), and how to watch for risky changes. Every behavior and number here comes from the AWS documentation.

The short answer: an AWS security group is a stateful virtual firewall attached to a resource’s network interface, such as an EC2 instance. It has allow rules only. AWS evaluates all of its rules (and those of every other group on the same interface) before deciding, and return traffic for an allowed connection is let through automatically. A new security group allows no inbound traffic and all outbound traffic. A network ACL is different: it works at the subnet level, is stateless, supports allow and deny rules, and processes rules in number order. AWS recommends security groups as the primary control and network ACLs as a second layer.

What is an AWS security group?

A security group controls which traffic can reach, and leave, the resources it is associated with. You attach it to EC2 instances and to many other resources that live in a Virtual Private Cloud (VPC), such as load balancers, interface VPC endpoints and Amazon RDS databases. Each VPC comes with a default security group, and you can create as many more as your quota allows. There is no charge for using security groups.

Each rule lists:

  • Protocol: most often TCP (6), UDP (17) or ICMP (1), or all protocols.
  • Port range: a single port such as 22, or a range such as 7000-8000. For ICMP, a type and code.
  • Source (inbound) or destination (outbound): an IPv4 or IPv6 address or range in CIDR notation, a managed prefix list, or the ID of another security group.
  • Description: optional, up to 255 characters. Use it; it is the only record of why a rule exists.

How security groups work

Six behaviors explain almost everything you will see in practice.

  1. They only allow. You cannot write a deny rule. Anything not allowed is dropped.
  2. They are stateful. If an inbound rule lets a request in, the response goes out regardless of outbound rules, and the reverse is also true.
  3. All rules are evaluated together. There is no rule order. If any rule allows the traffic, it is allowed.
  4. Multiple groups add up. A network interface can have several security groups, and their rules are combined into one set. Adding a group can only open more access, never less.
  5. Changes apply right away to every resource using the group. Existing connections are a special case, explained under connection tracking below.
  6. Some traffic is never filtered. Security groups do not filter traffic to and from the Route 53 Resolver (Amazon DNS), DHCP, the instance metadata service, Amazon Time Sync and Windows license activation. To filter DNS queries, AWS points you to Route 53 Resolver DNS Firewall.

The path inbound traffic takes to an EC2 instance

Two filters in a row: the subnet's network ACL, then the instance's security groups

  1. Internet gatewayTraffic enters the VPC
  2. Route tableSends it to the right subnet
  3. Network ACLSubnet level. Stateless. Allow and deny rules, checked in number order.
  4. Security groupNetwork interface level. Stateful. Allow rules only, all checked together.
  5. EC2 instanceReceives only traffic both filters allowed
Traffic between instances in the same subnet does not pass through the network ACL, because network ACLs are evaluated only when traffic enters or leaves a subnet. Source: Amazon VPC User Guide.

Default rules: what you get before you change anything

InboundOutbound
Default security group (one per VPC, named “default”)All traffic from resources in the same groupAll IPv4 traffic, plus all IPv6 if the VPC has an IPv6 range
New security group you createNothingAll traffic
Default network ACLAll traffic (rule 100), with a final deny ruleAll traffic (rule 100), with a final deny rule
New custom network ACLOnly the final deny rule, so nothingOnly the final deny rule, so nothing

Three practical consequences:

  • Anything launched without a security group gets the default one. If you launch an EC2 instance and do not choose a group, AWS attaches the VPC’s default group. You cannot delete the default group, but you can change its rules. AWS recommends creating groups for specific resources instead of using the default, and AWS Security Hub control EC2.2 checks that default security groups allow no inbound or outbound traffic.
  • New groups are closed inbound and open outbound. That outbound “allow all” rule is convenient, and it is also what lets malware call home. For sensitive workloads, replace it with the destinations the workload actually needs.
  • A new custom network ACL blocks everything until you add rules, including the return traffic on ephemeral ports. That surprise causes many outages.

Referencing other security groups

Instead of an IP range, a rule can name another security group as its source or destination. The rule then covers every resource associated with that group, by its private IP address, and keeps working as instances are added, removed or replaced. This is the cleanest way to build tiers.

A three-tier application built from security group references

Only the load balancer accepts traffic from the internet. Each tier accepts traffic only from the tier in front of it.

InternetAny address: 0.0.0.0/0 and ::/0
sg-albLoad balancer security groupInbound: HTTP and HTTPS from anywhere
sg-webWeb server security groupInbound: web traffic only from the load balancer group
sg-dbDatabase security groupInbound: database requests only from the web server group
Based on the example in the Amazon VPC User Guide. A rule that references a group counts as one rule, however many instances the group has.

What referencing does and does not do:

  • It does not copy rules. No rules from the referenced group are added to the group that references it.
  • It works across VPCs only in some cases. Inbound rules can reference a group in the same VPC, a peered VPC or a VPC connected through a transit gateway. Outbound rules can reference a group in the same VPC or a peered VPC.
  • Stale rules can linger. If a referenced group in a peer or shared VPC is deleted, or the peering connection is removed, the rule is marked stale. Clean these up.
  • Middlebox routing breaks it. If traffic between two instances is routed through a firewall appliance, reference IP addresses or subnet ranges instead, because a group reference will not allow the traffic.

Two newer options reduce duplication across VPCs: the Security Group VPC Associations feature lets you associate one security group with several VPCs in the same Region, and you can share security groups with accounts in your AWS Organizations organization.

Connection tracking: why removing a rule may not cut a connection

Security groups are stateful because they track connections. That has a side effect people often miss: when you remove or change a rule, tracked connections are not interrupted. They continue until they time out. For established TCP connections, the default idle timeout is 432,000 seconds (five days) on most instance types, and 350 seconds on Nitro v6 instance types.

There is an exception. If a rule allows TCP or UDP from everywhere (0.0.0.0/0 or ::/0) and a matching rule allows all response traffic in the other direction, that flow is not tracked, and removing the rule drops it immediately. ICMP is always tracked.

The practical lesson: if you are responding to an intrusion and need to cut an attacker’s existing session now, a network ACL deny rule does it, because network ACLs are stateless and break existing connections.

Security group quotas

Quota (per Region unless noted)DefaultCan you raise it?
Security groups per Region2,500Yes
Inbound rules per security group60Yes
Outbound rules per security group60Yes, same quota as inbound
Security groups per network interface5Yes, up to 16
Rules per group multiplied by groups per interface1,000 maximumNo
Network ACLs per VPC200Yes
Rules per network ACL, each direction20Yes, up to 40

How rules are counted matters. The 60-rule quota applies separately to IPv4 and IPv6 rules. A rule that references another security group counts as one. A rule that references a customer-managed prefix list counts as the list’s maximum size, so a prefix list with a maximum of 20 entries uses 20 rules.

Security group vs network ACL

Security groupNetwork ACL
Works atInstance (network interface) levelSubnet level
Applies toResources associated with the groupEverything in the associated subnets
Rule typesAllow onlyAllow and deny
EvaluationAll rules, before decidingIn order from the lowest rule number, first match wins
Return trafficAllowed automatically (stateful)Must be allowed explicitly (stateless)
How manyUp to 5 per interface by defaultExactly one per subnet

AWS’s own guidance is to use security groups as the primary control, because they are stateful and can reference other groups. Use network ACLs when you need what security groups cannot do:

  • Deny something specific, such as a known malicious address range, across a whole subnet.
  • Set guardrails that still apply if someone launches an instance with the wrong security group.
  • Cut existing connections immediately during an incident.

When you write network ACL rules, number them in steps of 10 or 100 so you can insert rules later, and remember the ephemeral port range for return traffic. AWS suggests opening 1024-65535 for public-facing subnets, with any deny rules placed before that allow rule.

Best practices

  • Never open SSH (22) or RDP (3389) to 0.0.0.0/0. AWS’s guidance is to allow only specific address ranges. Better still, use AWS Systems Manager Session Manager, which lets you manage instances with no inbound ports, bastion hosts or SSH keys.
  • Lock down the default security group and do not use it for workloads.
  • Use one group per role (load balancer, web, database) and reference groups instead of IP ranges inside the VPC.
  • Avoid large port ranges. Open only the ports each tier uses.
  • Restrict outbound traffic for sensitive workloads instead of keeping the default allow-all rule.
  • Limit who can change security groups to specific IAM principals, and require a description on every rule.
  • Check continuously. AWS Security Hub controls EC2.13 and EC2.14 flag SSH and RDP open to the internet, EC2.18 flags unrestricted access on unauthorized ports and EC2.19 flags high-risk ports. Reachability Analyzer shows which component blocks or allows a path.

How to monitor security group changes

Security groups change all the time, and a single bad change can expose a database. Two AWS logs together tell you what changed and what it allowed.

AWS CloudTrail records who changed what. Every change is an API call: CreateSecurityGroup, DeleteSecurityGroup, AuthorizeSecurityGroupIngress, AuthorizeSecurityGroupEgress, RevokeSecurityGroupIngress, RevokeSecurityGroupEgress and ModifySecurityGroupRules. CloudTrail is on by default, but its event history keeps only 90 days of management events in each Region. Create a trail or event data store to keep records longer.

VPC Flow Logs record what traffic was accepted or rejected. Each record has an action field: ACCEPT, or REJECT when the traffic was not allowed by the security groups or network ACLs. A burst of accepted connections to port 22 from unknown addresses right after a rule change is exactly the story you want to catch. Our guide to VPC Flow Logs explains every field and how to turn them on.

What to alert on:

  • A rule that opens any port to 0.0.0.0/0 or ::/0, especially 22, 3389 or database ports.
  • Changes to security groups made outside your normal deployment pipeline or by an unusual identity.
  • Deleted flow logs, or CloudTrail logging stopped or deleted, which attackers do to hide.
  • Rejected traffic that suddenly becomes accepted from the same source.

For the wider picture across accounts and providers, see cloud security monitoring.

How UTMStack fits

UTMStack, an open source security information and event management (SIEM) platform, ingests AWS CloudTrail through CloudWatch alongside logs from your endpoints, firewalls and other clouds. It ships detection rules for exactly the changes above: a security group change that opens access to 0.0.0.0/0 or ::/0 or to all protocols, deletion of VPC flow logs, and CloudTrail logging being stopped or deleted. Each rule is checked as the event arrives, and the alert shows who made the change and from where, so you can tell a deployment from an attacker. See the integrations page for supported sources, or try the live demo.

Frequently asked questions

Are AWS security groups stateful? Yes. Return traffic for an allowed connection is allowed automatically, whatever the rules in the other direction say. Network ACLs are stateless.

Can a security group deny traffic? No. Security groups have allow rules only. To deny specific traffic, use a network ACL or AWS Network Firewall.

How many security groups can an EC2 instance have? Five per network interface by default, which you can raise to 16. Rules per group multiplied by groups per interface cannot exceed 1,000.

Which is evaluated first, the network ACL or the security group? For inbound traffic from outside the subnet, the network ACL is checked when traffic enters the subnet, then the security group at the instance. Both must allow it.

Do security group changes take effect immediately? Yes for new connections. Existing tracked connections continue until they time out, unless the flow was untracked.

Do security groups cost anything? No. There is no additional charge for security groups or network ACLs.

Sources