Glossary

    Security Group

    Network Security

    A Security Group acts as a virtual firewall for AWS resources (EC2 instances, RDS databases, Lambda functions in VPCs, ELBs). It controls which traffic is allowed to reach and leave the resource.

    Key Characteristics

    • Stateful: if you allow inbound traffic, the response is automatically allowed outbound (and vice versa)
    • Allow-only: you can only create allow rules; there are no deny rules. Traffic not explicitly allowed is denied.
    • Instance-level: attached to ENIs (network interfaces), not subnets
    • Default outbound: new security groups allow all outbound traffic by default (important for quarantine scenarios)

    How It Goes Wrong in Practice

    The single most common misconfiguration in AWS network security is the 0.0.0.0/0 inbound rule on a sensitive port. It usually starts innocently: a developer cannot reach a database from home, opens port 3306 or 5432 to the world "just for today", and the ticket that was supposed to remove it never gets actioned. Internet-wide scanners probe the entire IPv4 space continuously, so an exposed SSH, RDP, or database port will be found and brute-forced, not hypothetically but as a matter of routine. The same applies to management interfaces on port 22 and 3389: if they must be reachable at all, restrict them to known CIDR ranges, or better, remove the inbound path entirely and use AWS Systems Manager Session Manager.

    The second pattern is security group sprawl. One shared group gets attached to dozens of unrelated resources, rules accumulate over years, and nobody dares remove anything because nobody knows what depends on what. At that point the group is no longer a security control, it is an outage risk. Prefer small, purpose-built groups per tier (one for the load balancer, one for the application, one for the database) and reference groups instead of CIDRs: allowing the database group to accept traffic only from the application group expresses intent and survives IP changes.

    Third, remember the egress side. New security groups allow all outbound traffic, so a compromised instance can freely reach command-and-control servers or exfiltrate data. For sensitive workloads, restrict outbound rules to the specific destinations the workload needs.

    A Practical Check

    Find security groups that allow SSH from anywhere, straight from the AWS CLI reference example:

    aws ec2 describe-security-groups --filters Name=ip-permission.from-port,Values=22 Name=ip-permission.to-port,Values=22 Name=ip-permission.cidr,Values='0.0.0.0/0' --query "SecurityGroups[*].[GroupId,GroupName]" --output text

    Swap the port values for 3389 (RDP), 3306 (MySQL), 5432 (PostgreSQL), or 6379 (Redis) and rerun. Anything this returns should either have a documented reason to exist or be fixed today. Do not forget IPv6: the equivalent filter is ip-permission.ipv6-cidr with a value of ::/0, because a rule open to the entire IPv6 internet is exactly as exposed as its IPv4 twin. The ip-permission.cidr filter matches inbound rules; related filters such as ip-permission.group-id let you audit which groups reference which.

    Frequently Asked Questions

    Can I write a deny rule in a security group? No. Security groups are allow-only: any traffic not matched by an allow rule is implicitly denied. If you need explicit deny semantics, for example to block a specific malicious IP range at the subnet edge, use a network ACL, which supports numbered allow and deny rules and evaluates them in order.

    What does stateful actually mean here? The security group tracks connections. If an inbound rule allows a client to reach your web server on port 443, the response packets flow back out automatically, even if no outbound rule matches them. The reverse is also true for connections your instance initiates. This is the key operational difference from NACLs, which are stateless and need both directions written explicitly.

    Is a security group enough on its own? It is the primary instance-level control, but it is one layer. Defense in depth pairs it with private subnets and routing (so databases have no internet path at all), NACLs for subnet-level blocking, and application-layer controls like AWS WAF for HTTP traffic. A perfect security group does not help if the resource also has a public IP it does not need.

    How should I audit changes over time? Security group modifications are API calls, so they land in CloudTrail (AuthorizeSecurityGroupIngress, RevokeSecurityGroupEgress, and friends). Pair that with AWS Config rules that flag groups allowing unrestricted access to sensitive ports, and you move from periodic manual audits to continuous detection.

    Related AWS Services

    Toc Consulting: AWS Security & Cloud Architecture

    Securing your AWS estate?

    Our team helps engineering teams secure and architect AWS the right way: assessment in week one, a prioritized action plan in week two.