thim.dev/blog
AUG 2026 · 8 MIN READ

Eleven VLANs and what they cost to run

On a flat home network, the wine fridge and the hypervisor are neighbours. So is the robot vacuum, the TV that phones home more than it streams, and whatever firmware your smart plugs shipped with in 2019. They can all talk to each other, and to the box holding every photo you have ever taken.

Nothing has to go wrong for that to be a bad arrangement. It is just a design where the blast radius of any one device is the entire house.

My homelab runs eleven VLANs. This is what they are, why they are separate, and what segmentation actually costs to live with, which is the part nobody puts in the tutorials.

§ What the segments are

No addresses here, on purpose. The structure is real, and the structure is the part worth copying.

The rule I settled on: a segment exists when a group of devices has a different trust level or a different job, not when it would be tidy. Eleven sounds like a lot. Each one earns its place by answering "what would I regret letting this talk to".

mgmt trust iot media qrtn guest srv store work games spare default deny: everything stops here an explicit allow one named port, on one named box yes no everything else stops at the wall; silence is the default answer

Left to right: management gear, my own devices, smart-home things, speakers and TVs, the quarantine for anything untrusted, guest wifi, the hypervisors and NAS, a storage-only lane, the containers that do the work, the game servers, and a spare. Every one of them runs into the same wall, and the wall wins unless a rule says otherwise.

Most of those are self-explanatory. Three are worth explaining.

Storage is its own segment because bulk traffic and everything else should not share a broadcast domain. The NAS and the hypervisors talk over a dedicated VLAN carrying only NFS and NVMe-oF. It means storage traffic cannot be interfered with by a chatty device somewhere else, and it means I can reason about that link on its own terms. Nothing routes into it. There is nothing there to reach.

Games is deliberately untrusted. Game servers are the one place I accept raw traffic from the internet, straight to a port, with no proxy and no authentication in front, because that is how the protocols work. A host in that position should be treated as though it will eventually be compromised. So it lives in its own segment and cannot reach anything else I care about. If someone owns a game server, they get a game server.

Workloads and server are separate even though the workloads run on the servers. The hypervisor management interfaces and the NAS live on one segment; the containers and VMs they host live on another. A container being compromised should not be a step towards the hypervisor that runs it.

§ Default deny, and what actually follows from it

The firewall runs one internal zone containing every network, with a small number of explicit allow policies and a single blanket block underneath everything. Nothing talks to anything unless a rule says it can.

Two things follow from that, and the second one surprises people.

Reachability you did not expect is almost always a rule somebody added on purpose. When something can reach something it should not, the instinct is to look for a missing block. In a default-deny model there is no such thing as a missing block, because the block is the floor. The answer is always in the allow list. So when you audit, read what you permitted, not what you forgot to forbid. That reframing makes audits dramatically faster.

It applies within a segment too. Two hosts on the same VLAN are still subject to the same default-deny, so they still need an explicit rule to talk. This one caught me out, and I had it written down wrong in my own notes for a while. It is easy to assume same-subnet traffic is a free-for-all and that segmentation only governs what crosses a boundary. Worth testing rather than assuming, because "it works" and "it is allowed" have different causes and only one of them is visible in the config.

§ Name rules for intent, scope them for reality

A firewall policy has a name and it has a scope, and they are not the same thing. A rule called "workloads can reach the NAS web interface" tells you the intent. What it actually permits depends entirely on what you wrote in the destination field.

Write the destination as a whole subnet and the rule now means "workloads can reach that port on anything in that segment". If a management controller, a spare interface, or next year's appliance happens to live in the same segment and answer on the same port, the rule covers those too. It did not change. It never described what its name said it described.

So: scope destinations to hosts rather than subnets wherever you can, name rules after intent, and assume the two will drift apart as the network grows. The name is documentation and documentation rots. The scope is the actual behaviour.

The general version of this is worth internalising. A rule's name is a claim about intent; only its scope is a fact. Review the scope.

§ What it costs to run

This is the part I wish more homelab posts covered, because the design is the easy bit.

Cheap switches cannot tag. One of my switches does not support tagged VLANs on its downstream ports at all. Every port is access-only. That means each additional segment reaching a device behind that switch costs a physical port and a physical cable, not a configuration change. Segmentation stops being free the moment your hardware cannot trunk, and it is worth checking that before you design eleven of anything.

DHCP and name-based ingress fight each other. Almost everything in my workload segment gets its address by DHCP. My reverse proxy needs to know where to send traffic. Point it at an IP and you have built a silent dependency on a lease, which will break at the least convenient moment, and break in a way that looks like an application fault rather than an addressing one. The fix is to give the proxy internal DNS names instead of addresses, so a lease change is invisible to it.

Things cache DNS longer than you expect. After renumbering a batch of hosts, a pile of proxy health checks went unhealthy while every backend answered perfectly when tested directly. The tunnel client had cached the old resolutions and had no reason to look again. Restarting it fixed all of them at once. The lesson generalises: after changing any address, restart the things that resolved it, and do not trust a health check that disagrees with a direct request.

Config outlives the thing it was for. I decommissioned a monitoring stack a while back. The containers went immediately. The firewall policies and port groups it needed sat there for months afterwards, permitting traffic for services that no longer existed. Nothing was broken by that, but every stale allow is a rule someone has to understand later, and a default-deny model is only as good as the allow list is short. Decommissioning an application means decommissioning its network config in the same sitting.

§ One idea worth stealing

Every virtual machine and container gets an address whose last octet matches its hypervisor guest ID. Guest 104 is .104. Guest 118 is .118. All of them pinned with DHCP reservations, so the mapping is enforced rather than hoped for.

It sounds trivial. It is the single highest-value convention in the whole setup. An address stops being an arbitrary lease and becomes a fact about the guest: I can look at traffic, or a log line, or a firewall hit, and know which guest it is without looking anything up. Renumbering everything to match took an afternoon and I would do it again tomorrow.

Two things to know if you try it. Your DHCP server will likely refuse to create a reservation while another client holds an active lease on that address, so a renumbering has to be sequenced, and sometimes a host needs a restart before the next one can take the address it just released. And anything with a statically configured address, rather than a reservation, sits outside the scheme and needs documenting as an exception. I have two. Both are written down.

§ It is not a project you finish

Segments accumulate. Rules accumulate faster. Hardware limits what you can express, and DHCP quietly undermines anything that assumed an address was permanent.

The payoff is not a tidy diagram. It is that when I think about any device in the house, I can answer "what can this reach" from memory, and I can answer "what would it mean if this were compromised" without opening the firewall UI. That is the entire point of the exercise, and it is worth eleven VLANs and a few extra cables to get there.