AWS VPC ACL for private subnets

access-control-listamazon-vpcamazon-web-services

I created a VPC using the VPC wizard with two subnets (public and private), and a NAT in front of the private subnet.

Looking at the ACL for the the subnets, there was a rule to allow all INBOUND traffic for 0.0.0.0/0. I'd like to disallow any inbound traffic that's not coming from the NAT (with IP 10.0.0.8) so I change the ACL to be similar to the ones in Scenario 2 in http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Appendix_NACLs.html.

That is, ALLOW ALL PROTOCOLS on ALL PORTS from 10.0.0.0/16, with a disallow for 0.0.0.0/0.

This doesn't seem to work correctly as my instance don't have internet access. Is there something else I need to setup/change to get it working?

Best Answer

Publicly-routable IP addresses don't get rewritten when they pass through the NAT instance.

You'll need to leave the entire public Internet address space as permissible on the private subnet in the network ACLs. If the private subnet lacks an Internet gateway and its default route points to the NAT instance, public Internet addresses will only arrive indirectly via the NAT instance.

VPC network ACLs are useful to limit access between instances inside a VPC, but their stateless nature makes them cumbersome for the type of configuration you describe: it doesn't keep track of a connection that matched an allowed outbound rule to permit the corresponding inbound traffic, so you're forced to approximate by allowing ephemeral port ranges for inbound traffic.

A more flexible approach is to use a combination of VPC routing, the absence of an Internet gateway on the private subnet, and a good iptables configuration in the NAT instance to control traffic to and from publicly routable IP space, while leaving the network ACL for private subnet instances permissive-by-default with respect to publicly routable IP space. In such an environment, placement in the private subnet is sufficient to protect instances from any outside traffic the NAT instance does not pass.