Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lab 12: Network Isolation as an Access Control

Isolation verified on real AWS, and the verifier proven able to fail

tests

IAM answers "is this principal allowed to call this API." It does not answer "can this host even reach that endpoint." This builds the second layer, then proves it from the live VPC instead of trusting the Terraform.

Domains AWS networking, PAM
Built on AWS VPC primitives. No modules, the point is knowing the primitives
Cost $0 verified. Free resources only, no NAT gateway, no interface endpoints, no EC2
Status Deployed and verified on real AWS. Caught a real finding on first run; negative control run live (findings/real-aws-run.txt)

Situation

Access control has two layers that fail independently. A perfect IAM policy on a host that sits in a subnet with an internet route is still one stolen credential away from exfiltration. The two layers are checked by completely different tools, which is exactly why the gap between them goes unnoticed.

Task

Build the network layer properly, then prove the isolation actually holds rather than assuming it because a subnet is named "private."

Action

A private subnet with no path off the network. Not a blocked route, not a null route. There is no 0.0.0.0/0 entry in that route table at all, so nothing in the subnet can initiate a connection off the VPC.

A gateway endpoint so isolation does not mean uselessness. S3 traffic routes directly over the AWS network, so the subnet keeps working while having zero internet route. It also carries its own policy, so network isolation and IAM are both doing work.

Security groups that reference each other, not CIDR ranges. A CIDR rule grants access to whatever lands in that range later. A group reference follows identity, so only something explicitly placed in the app tier can reach the database, whatever its IP.

A verifier that reads the deployed VPC (scripts/prove_isolation.py), because a subnet is not private because Terraform says so. AWS has no private flag. It is private only because the route table has no path out, and that is a property of the live graph.

Result

Deployed to real AWS, and the verifier caught a finding in a group I never wrote. Every security group in my Terraform was correct. It still failed:

1 isolation problem(s):
  - default: unrestricted egress to 0.0.0.0/0, a compromised host here
    can reach anything

AWS builds a default security group into every VPC. It cannot be deleted, anything launched without an explicit group lands in it, and it ships with wide open egress. So the failure mode is that someone forgets to specify a group, their host silently joins the one group nobody audits, and it has a clear path out. The Terraform looked perfect because the group is not in the Terraform. Locked it down with aws_default_security_group stripped of every rule.

Then I broke it on purpose to prove the verifier works. Added a real internet gateway route to the private table on the live VPC:

lab12-private: has a route off the network, 0.0.0.0/0 to igw-03550f...
exit 1

Removed the route, back to exit 0. A verifier that has never been seen failing is decoration.

15 offline tests cover the analyzer, including that a gateway endpoint is correctly not treated as an internet route (counting it would fail correct designs, which is how a checker gets switched off) and that an unassociated subnet falling back to the VPC main route table is reported on its own.

What I did not build

The AWS VPC primitives are AWS's. The isolation design, the verifier, the test suite, and the negative controls are mine. No networking module was used on purpose: the value here is knowing what a route table actually does, not wiring up someone else's abstraction over it.

Run it

terraform -chdir=terraform init
terraform -chdir=terraform apply
python scripts/prove_isolation.py --vpc-id $(terraform -chdir=terraform output -raw vpc_id)
terraform -chdir=terraform destroy

Needs Terraform 1.9+, Python 3, boto3.

Findings

findings/ holds the real AWS run, the default security group finding, and the live negative control. LAB-NOTES.md is the running log.

License

MIT. See LICENSE.

About

Network isolation as a second layer under IAM. Private subnet with no path off the network, security groups that reference identity not CIDR, and a verifier that proves it from the live VPC.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages