RTRadu Todea ▚ / Case study ← All write-ups

Case studySegmented cloud lab

One allowed path is still a path.

A lab I built for myself: a small enterprise network in the cloud, defined entirely as code, split into tiers that shouldn’t be able to reach each other. The point wasn’t to break something — it was to watch how far a single permitted exception reaches once everything else is locked down.

Type
Self-study lab
Built with
Terraform · AWS
Shape
One VPC, tiered subnets
Focus
Network segmentation

01What I built

A network in three tiers.

Everything is infrastructure-as-code, so the whole environment stands up and tears down with one command — no console clicking, and nothing left running to surprise a bill. Three roles, one private network, and a firewall in the middle that’s supposed to keep the front of the house away from the back.

Exposed

Web app (DMZ) The public front door. Reachable from the internet.

In the middle

Firewall Routes between tiers. Default: drop internal traffic.

one rule allows a single port through

Protected

Internal server The high-value target. Never meant to face the web.

02The idea

Segmentation is only as strong as its exceptions.

Segmentation is a good control: put a wall between the part of the system attackers can touch and the part that matters, so getting a foothold on the first doesn’t hand over the second. The catch is that walls are never solid — real systems need traffic to cross them, so each wall grows a short list of allowed exceptions.

This lab’s firewall dropped internal traffic by default, with one exception: the web tier was allowed to reach the internal server on a single database port. On paper that’s narrow. In practice it means that anything that can run commands on the exposed web app can also speak to the protected server — the wall is only as good as the assumption that the front tier stays trustworthy. This lab exists to make that consequence concrete rather than theoretical, so it can be reasoned about and designed against.

03What it taught me

Notes to myself.

Exceptions are the design
When everything else is denied, the allow-list is the attack surface. The interesting review question isn’t “is there a firewall?” but “what does each exception assume, and what happens when that assumption is wrong?”
Trust flows downhill
A tier inherits the reach of whatever is allowed to talk to it. The internal server never faced the internet, yet it was one compromised front-end away from being reachable — because the firewall trusted the front-end on its behalf.
Prove it, don’t assume it
It’s easy to believe a rule does what its comment says. Watching the firewall’s own counters is what turns “this should be blocked” into “this is blocked” — or into a surprise. Evidence beats intent.
Infrastructure-as-code is a safety feature
Because the whole lab was code, I could stand it up, change one rule, watch the effect, and destroy it — repeatably, and without a lingering cloud bill. Reproducibility isn’t just tidy; it’s what makes a finding trustworthy.

04How I’d harden it

Fix what matters.

The same lab, designed defensively, is a short list:

The weak spotWhy it bitesWhat I’d do
A broad allow rule “Web tier → internal” trusts the whole web tier Scope the exception to exactly what needs it, and no more — a specific service, not a whole subnet.
A trusted front-end One code bug on the exposed app inherits that trust Treat every tier as potentially hostile: authenticate between services, don’t rely on network position alone.
Quiet crossings Traffic that shouldn’t happen goes unnoticed Log and alert on any internal crossing — the rare event is exactly the one worth seeing.
The honest part Some path has to exist You can’t remove every exception — so make each one small, authenticated, watched, and written down. Defence in depth, not a single wall.