Use Case — A single public subnet, multiple private subnets in AWS

Access to all private subnet instances is via instances in the public subnet. Say you have a bastion host in the public subnet that you need to SSH into. From that bastion host, you can SSH onto other private EC2s in the private subnets.

NACLs that allow all and deny all

Default NACLs allow all inbound and outbound traffic.

Custom NACLs DENY all inbound and outbound traffic.

Two NACLs you should custom built

  1. A Public NACL and
  2. A Private NACL

The Public NACL should be configured  to

  1. Allow inbound HTTP and HTTPS traffic from any IP address, deny all other inbound traffic, and
  2. Allow all outbound traffic.
  3. Allow inbound SSH access (port 22) from one IP address (your own IP) and
  4. Allow outbound access on any port to the same IP address.
  5. Lastly - Traffic from other subnets within the same VPC should be allowed. So 10.0.0.0/16 CIDR block should have an ALLOW rule for all traffic

The Private NACL is a lot simplerIt only needs to allow traffic (ALL Traffic) from within the VPC (the same as Item 5 above).

Public and Private Subnets

Now, simply associate the Private NACL with all the private subnets  and the public NACL with all the public subnets.

Should you have ONE or BOTH? Intentional versus Default Application

SGs are required, while NACLs are optional.  However, SGs are applied to an instance INTENTIONALLY, whereas default NACLs (with the subnets in the VPC) are automatically applied to all instances in a subnet.

A particular security group only applies to an instance if a user intentionally associates it with the instance.

A NACL, on the other hand, automatically applies to all instances in the subnet it is associated with.  This hardens the network when using in conjunction with security groups.

  1. Network Access control lists are applicable at the subnet level, so any instance in the subnet with an associated NACL will follow rules of NACL. That's not the case with security groups, security groups has to be assigned explicitly to the instance.
  2. By default your default vpc, will have a default Network Access Control List which would allow all traffic , both inbound and outbound. If you want to restrict access at subnet level it's a good practice to create a custom NACL and edit it with the rules of your choice and while editing you could also edit subnet associations , where you associate a subnet with this custom NACL, now any instance in this subnet will start following NACL rules
  3. Security groups are stateful ,if you add an inbound rule say for port 80, it is automatically allowed out, meaning outbound rule for that particular port need not be explicitly added.
  4. NACLs are stateless unlike security groups
  5. Everything is DENIED by default in a SG. One CANNOT DENY traffic from a particular instance (this is important - because only a NACL will let you accomplish this). By default everything is denied. You can set rules only to ALLOW.  With NACLs, you can set rules both to deny and allow. NACLs let you get more granular due to their DENY capabilities. Security Groups can get granular on ALLOWS, but not on DENYs.
  6. Security groups evaluate all the rules in them before allowing a traffic . NACLs do it in the number order, top to bottom. If rule 100 says allow all SSH traffic and your rule #200 says don't allow SSH traffic (from an ip Range) , traffic will be ALLOWED, because rule #100 has already allowed it in. So, a possible way to arrange your rules is to place DENY rules first in NACL and followed by allow rules.( AWS best practice is to number your rules in increment of 100s in NACL).

Summary  - Use them Both

If a user accidentally assigns / creates an overly permissive security group, the instance can still be protected by the default NACLs (which should look like the list above). NACLs let you get more granular due to their DENY capabilities.

Test Your Understanding

  1. If you had to DENY traffic from a CIDR block, which would you use? (NACL)
  2. What should be the order of ALLOW DENY NACLs (DENY on top and ALLOWs below)?
  3. If you had to apply the same rules to all instances in a subnet , which would you use (NACLs - automatically apply to instances in a subnet)
  4. If you had to ALLOW a CIDR block in (e.g. SSH allow), which would you use? (Either SGs or NACLs can allow CIDR ranges).