AWS Security Groups Explained: Rules, Examples, and Security Groups vs NACLs
AWS security groups are stateful virtual firewalls you attach to EC2 instances, RDS databases, load balancers, Lambda functions running in a VPC, and most other AWS resources. They control which traffic reaches your resources and which leaves them. By the end of this page you will understand how rules work, how to chain security groups for internal traffic, when to reach for a Network ACL instead, and how to avoid the mistakes that leave workloads exposed.
Simple explanation
Picture a bouncer standing outside a specific room, not the whole building. The bouncer has a guest list of who is allowed in. Anyone not on the list is turned away. When a guest inside wants to leave, the bouncer waves them through automatically without checking the list again. That is what “stateful” means: once traffic is allowed in, the return journey is handled automatically. You only write the entry rules.
Each AWS resource needs at least one security group. You cannot launch an EC2 instance without one. If you do not pick a group, AWS assigns the default security group for the VPC.
What security groups are in AWS
A security group is a resource-level virtual firewall. It attaches to individual resources, not to subnets. Two EC2 instances in the same subnet can have completely different security group rules, and neither can bypass the other’s rules because of their shared location.
Four characteristics define how they work:
- Stateful. Inbound connections automatically get a return path. You never write “allow established connections” rules.
- Allow rules only. There is no explicit deny. You allow what you want; everything else is silently dropped. To block a specific IP you need a Network ACL.
- Attached to resources, not subnets. One security group can be attached to many resources. One resource can have up to 5 security groups on EC2 by default.
- Can reference other security groups. Instead of using IP ranges for internal traffic, you reference another security group as the source or destination. This scales automatically and removes the need to track IP addresses.
How security groups work
Each rule specifies a direction (inbound or outbound), protocol (TCP, UDP, ICMP, or all), port range, and a source or destination: either a CIDR block or another security group ID. An optional description helps you remember what each rule is for.
Rule evaluation: AWS evaluates all rules in a security group simultaneously. There is no rule numbering or priority. If any rule permits the traffic, it is allowed. When a resource has multiple security groups attached, AWS merges all rules from every group into one effective allow list with the same logic.
Stateful return traffic: Because security groups track connection state, you only write rules for traffic you want to accept or initiate. If an EC2 instance accepts an inbound HTTP request on port 80, AWS automatically allows the response to leave, even if your outbound rules are empty. The reverse is also true: if an instance initiates an outbound HTTPS request, the response is automatically allowed back in with no inbound rule needed for that port.
Rule changes are immediate. When you modify a rule, it takes effect instantly across all resources with the group attached. No restarts needed.
You can reference a security group from a same-region peered VPC as a rule source. Cross-region VPC peering does not support security group references. Use IP CIDR ranges instead for cross-region flows.
Default behavior
When you create a new security group:
- All inbound traffic is denied. The group has no inbound rules, so nothing can reach the resource until you add one.
- All outbound traffic is allowed. A default outbound rule permits all traffic to any destination. Most teams leave this as-is and only restrict outbound if compliance requirements demand it.
The default security group is different from any group you create yourself. Every VPC has one, and AWS assigns it automatically to any resource launched without a specified group. It allows all traffic between resources sharing that group and all outbound traffic.
Do not rely on the default security group for real workloads. Its inbound rules are broader than most resources need, and it is harder to audit than named, purpose-built groups. Create an explicit security group for every resource type in production.
Common real-world patterns
The most important pattern is the three-tier chain: load balancer, application tier, database tier. Each layer only accepts traffic from the layer directly above it.
sg-alb → accepts port 443 from 0.0.0.0/0 (internet)
sg-app → accepts port 8080 from sg-alb only
sg-db → accepts port 5432 from sg-app onlyThe Application Load Balancer is the only resource that faces the internet. App servers are reachable only from the load balancer, not directly from the internet. The database is reachable only from app servers. No internal resource needs a public IP address.
When your app tier scales to 50 EC2 instances in an Auto Scaling Group, the database security group rule does not change. One reference to sg-app covers all instances automatically, regardless of their private IPs.
A CIDR-based rule like 10.0.11.0/24 permits every current and future resource in that subnet, including ones you did not intend to allow. A security group reference permits only resources that have that specific group attached. It is more precise, easier to audit, and does not break when instances get new IPs.
Admin access
Avoid opening SSH (port 22) or RDP (port 3389) from 0.0.0.0/0. If you need terminal access, restrict the port to a known static IP, or use AWS Systems Manager Session Manager, which gives you a shell with no open inbound rules at all.
Port 22 or 3389 open to 0.0.0.0/0 is one of the most-scanned configurations on the internet. Automated tools probe every public IP address for these ports constantly. If you see this in a security group, close it now. Use Session Manager or restrict to a specific IP range.
Lambda connecting to RDS
When a Lambda function runs inside a VPC (see Lambda VPC access), it needs its own security group. Create a dedicated sg-lambda, then allow the DB port from sg-lambda in the RDS security group. This is tighter than allowing the entire subnet CIDR.
# Allow Lambda's security group to reach RDS on PostgreSQL port
aws ec2 authorize-security-group-ingress \
--group-id sg-rds-0123456789abcdef0 \
--protocol tcp \
--port 5432 \
--source-group sg-lambda-0123456789abcdef0How to use security groups safely
- Least privilege. Open only the ports actually needed. Remove rules when a service changes or is decommissioned. Unused open ports are attack surface.
- Use security group references for internal traffic. A CIDR-based rule allows every resource in a subnet, including future ones. A security group reference allows only the specific resources you chose.
- Keep rules narrow by port and source. A rule allowing all ports (0-65535) from a broad CIDR is almost never correct. If you find yourself writing one, reconsider the design.
- Be careful if you restrict outbound rules. Deleting the default allow-all outbound rule is valid, but you must add back rules for DNS (UDP 53), HTTPS (TCP 443), and any AWS API endpoints the resource calls, or expect silent breakage in unexpected places.
- Never open admin ports to the internet. Restrict port 22 and 3389 to a known IP range, or eliminate open inbound rules entirely with Session Manager.
For the full layering model combining security groups with NACLs, VPC Flow Logs, and IAM, see network security best practices.
When to use security groups
Security groups apply to almost every resource in a VPC. You will configure them for:
- EC2 instances. Required. AWS will not launch an instance without one.
- RDS databases. Control which app servers or Lambda functions can connect on the DB port.
- Application Load Balancers and internal load balancers. Control which clients can reach the ALB, and which targets the ALB can forward to.
- Lambda functions in a VPC. Needed when Lambda must reach private resources like RDS or ElastiCache.
- East-west service traffic inside a VPC. Microservices calling each other on private IPs all benefit from tight security group chains.
Security groups vs Network ACLs
Security groups and Network ACLs are both AWS firewall tools, but they operate at different layers with different capabilities.
| Feature | Security Group | Network ACL |
|---|---|---|
| Scope | Individual resources (EC2, RDS, ALB, etc.) | Entire subnets |
| Stateful? | Yes. Return traffic automatically allowed. | No. Must allow both directions explicitly. |
| Explicit deny? | No. Allow rules only. | Yes. Can block specific IPs or CIDRs. |
| Rule evaluation | All rules evaluated together; any match allows | Rules evaluated by ascending number; first match wins |
| Default on new resource | Deny all inbound, allow all outbound | Default NACL allows all; custom NACL denies all |
| Security group references | Yes. Reference another SG as source or destination. | No. IP ranges only. |
| Best use case | Day-to-day access control for every resource | Blocking specific IPs, compliance-required subnet segmentation |
Configure security groups carefully for every resource. Add a custom Network ACL only when you need to explicitly block a specific IP address at the subnet level. That is the one thing security groups cannot do.
Common mistakes
- Opening SSH or RDP to 0.0.0.0/0. Port 22 or 3389 open to the internet is one of the most-scanned configurations in AWS. Restrict these to a known IP range or use AWS Systems Manager Session Manager so no inbound rules are needed at all.
- Using subnet CIDRs for app-to-database rules. Allowing
10.0.11.0/24in your database security group means every resource in that subnet can connect, not just your app servers. Reference the app server’s security group instead. - Assuming security groups are the only control needed. Security groups enforce network access at the resource boundary. Once a connection is established, they play no further role. Layer them with IAM policies, encryption in transit, and application-level authentication for proper defense in depth.
- Relying on the default security group for production. The default security group allows all traffic between members that share it. This is broader than most resources need and harder to audit than named, purpose-built groups.
- Listing many CIDR ranges instead of grouping by security group. If you have ten CIDR rules where a security group reference would do, the rule count grows as IPs change and the intent becomes unclear. One reference rule is more accurate and maintainable than twenty IP ranges.
How to troubleshoot security group problems
Many “security group problems” turn out to be NACL rules, routing gaps, or application issues. Work through this checklist before assuming the security group is the cause. For a full walkthrough of common AWS connectivity failures, see troubleshooting network issues in AWS.
- Is the rule on the right resource? Security groups protect the resource receiving traffic. Check the destination’s inbound rules, not the sender’s.
- Is the port and protocol correct? TCP and UDP are different. Double-check the port number: PostgreSQL is 5432, MySQL 3306, Redis 6379, HTTPS 443.
- Is the source correct? If the rule references a security group, verify the source resource actually has that group attached. If it uses a CIDR, confirm the source IP falls within it.
- Is a NACL blocking it? Even if the security group permits traffic, a Network ACL on the source or destination subnet can drop it. NACLs are stateless, so check both inbound and outbound NACL rules including ephemeral port ranges.
- Is there a routing issue? A packet that cannot be routed to the destination never reaches the security group. Check that route tables have the correct entries and the appropriate gateway exists. See route tables in AWS.
- Is DNS resolving to the right IP? If you are connecting by hostname, verify DNS resolves to the expected private IP inside the VPC rather than a public address or stale record.
- Is the application actually listening on that port? The most common source of confusion: the app is not running, or it is bound to
127.0.0.1instead of0.0.0.0. The security group is fine; the app is not reachable. - Is the resource in a supported association pattern? Security group references only work within the same VPC or same-region peered VPCs. For cross-VPC traffic, verify that VPC peering or a PrivateLink connection is fully configured.
Summary
- Security groups are stateful virtual firewalls attached to individual AWS resources, not subnets.
- Stateful means return traffic for allowed inbound connections is automatically permitted. No explicit return rules needed.
- Default behavior: all inbound denied, all outbound allowed.
- Rules can reference another security group as source or destination for internal traffic. More precise and scalable than IP ranges.
- Chain security groups in a tier pattern (ALB to app to DB) to control traffic flow without exposing internal resources to the internet.
- Security groups cannot deny traffic explicitly. Use Network ACLs when you need to block a specific IP at the subnet level.
- Rule changes take effect immediately across all attached resources.
- Never open SSH or RDP to 0.0.0.0/0. Use Session Manager or restrict to a known IP range.
Frequently asked questions
Can a security group reference itself?
Yes. A self-referencing rule allows all traffic between resources that share the same security group. This is useful for clusters where every member needs to communicate with every other member, such as ECS tasks in a service or nodes in an ElastiCache cluster. Attach the same security group to all members and add an inbound rule that references that group as the source.
What happens if multiple security groups are attached to one instance?
AWS combines the rules from all attached security groups into a single effective allow list. If any rule across any group permits the traffic, it is allowed. There is no ordering or priority between groups. All rules are evaluated together. By default, an EC2 instance can have up to 5 security groups attached.
What is the default security group in AWS?
Every VPC has a default security group that AWS automatically assigns to resources you launch without specifying a group. It allows all traffic between members of the same default security group and all outbound traffic. For real workloads, create purpose-built security groups with specific rules rather than relying on the default.
Do security group rule changes take effect immediately?
Yes. Rule changes apply immediately to all resources that have the security group attached. You do not need to restart instances or reattach the security group.
When should I use a Network ACL instead of a security group?
Use a Network ACL when you need to explicitly block a specific IP address or CIDR range at the subnet level. Security groups can only allow traffic, not deny it. For all other access control, security groups are the right tool. Most teams rarely configure custom NACLs.