I have an Ubuntu EC2 instance running on AWS. I have always used the Network ACL to control access to port 22 instead of using Security Groups.
Question 1: For the use case of a single EC2 instance, are there any pros and cons between using a NACL vs SG for access control? (Besides stateful vs stateless and the other differences on the AWS VPC security doc.)
Question 2: How does a large environment handle this? Is there a best practice? (I know one larger company has their NACL totally open and controls everything with SGs.)
First thing I did to try and find an answer was reading AWS's VPC Security docs: https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Security.html
I see a couple methods for access control in my use case:
Option 1: Restrict the NACL ingress to ports 80, 443, and ephemeral ports to 0.0.0.0/0. Add port 22 access per IP address. Deny all other traffic. (This is what I have always done.) If I wanted a private subnet instance, I would then restrict down the Private Subnet via SG to the Public Subnet's internal CIDR.
Option 2: Open the NACL up to the world and use SG for access control to the EC2 instance.
Option 3: Be redundant and use both.
When I go to a new location (coffee shop) and want to SSH to my instance, I log into the AWS console and add a new NACL rule to allow the IP address port 22 access. Adding a rule to both an NACL and SG seem to be the same amount of mouse clicks and typing.
Regarding actual environment creation, I use terraform. Setting up a resource is pretty easy using either option, so I wouldn't consider that a pro or a con.
NACL resource:
ingress {
protocol = 6
rule_no = 300
action = "allow"
cidr_block = "0.0.0.0/0"
from_port = 80
to_port = 80
}
SG resource:
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
The only big advantage I see to the NACL is if there are multiple Public SGs, it's easier to blacklist IP addresses in an NACL if handled manually via the console.