AWS Security Groups’ Best Practices
AWS Security Groups #
Security groups are the main firewall of the resources of a VPC. A few simple rules keep them understandable and secure.
Create a small number of groups that can be combined #
Create a small number of security groups that can be combined to build the desired security configuration. We recommend having a generic group for each type of resource with all the common rules, and a specific group for each individual resource (or application) with its particularities.
- A generic default group for each resource type: it holds the rules that apply to every resource of that type, for example the SSH access to EC2 instances from a fixed administration IP address, or the access to the database port for administration.
- A specific group for each resource or application: named with part of the resource name, with a prefix for the cloud and the resource type.
- ditwl-sg-rds-mariadb-pro-pub-01: security group of the production MariaDB RDS instance.
- ditwl-sg-ec2-pro-pub-01: security group of the production web servers.
Use groups as sources, not IP addresses #
Avoid creating too many groups, and do not use a CIDR block as a source, except for the Internet. It is better to use another security group as the source: an element gets access to other resources by being a member of a group, not by having a specific IP address that can change. This is the pattern used in the AWS RDS tutorial, where only the back-end security group can reach the database port.
Apply the principle of least privilege #
- Open only the ports that are needed, and to the smallest possible source.
- Do not open SSH (22) or RDP (3389) to
0.0.0.0/0. Use a fixed administration address, a VPN, or better AWS Systems Manager Session Manager, which needs no inbound rules. - Databases and back-end servers belong in private subnets and never accept traffic from the Internet.
- Restrict the outbound rules of sensitive resources (for example, to the ports and groups that they need) instead of allowing all outbound traffic.
- Review the groups regularly and delete the ones that are not used.
Describe and tag every rule #
Write a description for every rule that explains why it exists, and use tags (Name, owner, environment) to identify the group. It makes audits and reviews much easier.
Manage them with code #
Define the security groups with Terraform or OpenTofu and use a scanner such as Trivy or Checkov (see Terraform Tools) to detect open rules before they are deployed. Use aws_vpc_security_group_ingress_rule and aws_vpc_security_group_egress_rule for the rules, and do not mix them with in-line rules in the same group.
Do not rely only on security groups #
For defense in depth, combine them with Network ACLs for coarse subnet-level rules, AWS WAF for web applications and CloudTrail to audit the changes.