Future me: the thing to remember from this session isn't a command, it's a sentence. VLAN 20 was "isolated" for a long time, but only because the switch was a dumb Layer 2 device with no path to anywhere else. That wasn't a security decision, it was just the absence of a road. Once the switch started routing, the road existed, and nothing was stopping traffic from using it. Isolation had quietly gone from "true" to "assumed," and those are not the same thing.
So: VLANs are broadcast separation, not a security boundary. The boundary only exists once something enforces it. Write that down every time, because the switch will happily route between segments and never mention that whatever you thought was keeping them apart just stopped existing.
Before touching the CLI, I decided what the untrusted lab segment should be allowed to reach, and wrote the reasoning down before the syntax:
- the internet — allow, otherwise the segment is useless for actually testing anything
- the production VLAN — deny, a compromised lab box must never reach whatever real infrastructure lives there
- the switch's own management address — deny, never let the thing being contained talk to the thing doing the containing
- the rest of the main LAN — deny, same logic as production
That's the shape of a cloud security group on an untrusted subnet: outbound allowed, lateral movement denied. Worth keeping that separate in my head from the other cloud comparison that came up in the same session — these switch ACLs are stateless, the way a cloud network ACL is stateless, while a security group is stateful and remembers the outbound request. Two different lessons that happen to both reference the same cloud service; don't collapse them into one.
Syntax notes worth keeping: the mask the switch wants is the inverse of a subnet mask — zeros lock a bit down, ones set it free — and mixing the two up is one of the easiest ACL mistakes to make. I also needed an extended ACL, not a standard one, because standard only matches source address and this whole policy is about destination. And the rule has to say ip, not tcp — tcp would block web traffic but leave ping working, which is a policy that looks done and isn't. Last thing: two of the four rules technically overlap (the switch's management address is inside the main-LAN range already covered by another rule), and I kept both anyway. Reading this in six months, the redundant line is the one that tells me the management address was blocked on purpose, not as a side effect of other math.
The firmware had its own opinion. Applying the ACL at the VLAN interface — the documented way — got an unrecognized-command error. Old firmware, and not the first command it's disagreed with documentation on. Instead of guessing a second syntax, I asked the switch itself what a VLAN interface could even do, and the answer was: nothing ACL-related, at all. So I checked the physical port instead, and that's where the binding command actually lives. It makes sense once you see it — the access port is the only physical door into that VLAN, so filtering there catches exactly the same traffic filtering at the VLAN would have. The actual lesson is bigger than this one switch: on old or unfamiliar gear, the device's own help is more authoritative than any doc, because the doc describes whichever version its author had in front of them. Don't re-guess the syntax — enumerate what's actually there.
Verification: a test client on the lab port, Wi-Fi off so there was no second path lying about the result, pinged five destinations — its own gateway, production, switch management, main LAN, and a public resolver. The result was two distinct outcomes across those five: allow or deny, nothing in between, every single one matching the written policy. (My own session notes claimed three different outcomes there, which isn't what the table actually shows — just allow and deny, cleanly split. Correcting that here before I believe my own write-up later.) The denies were silent — no error, no rejection message, just packet loss, which is correct and deliberate: a switch ACL deny doesn't announce itself, unlike the ARP-failure "unreachable" I've seen elsewhere, which is a different failure at a different layer. Best proof of all was accidental: pinging the same switch management address from the main LAN instead of the lab port worked fine. Same target, different port, different outcome — the ACL is scoped to exactly where I put it, not leaking anywhere else.
Unrelated thread, closed in the same sitting: three apartment Ethernet jacks that had been dead for a while turned out to trace back to one unmanaged switch, in a media cabinet, that had simply lost power. Swapping which outlet it was plugged into brought it straight back — every jack, at once, because they'd all been riding on that one device. Wired came back noticeably faster than either Wi-Fi path, roughly a few milliseconds versus double digits. The scheduled technician visit for this got cancelled, since the fault was physical and local, not upstream. Good reminder for next time something "upstream" looks broken: check the dumb, boring, unmanaged box before assuming anything clever is wrong.
State at the end of this session: the segmentation work is done end to end — the ACL is written, applied, and verified by actual behavior rather than just by reading the config back. The wall jacks are a separate, solved problem. Queued next: move a VM host's network connection over to the switch now that there's a place for it, then re-source a router's WAN connection from the newly-working wall jack instead of the uplink a previous session found locked to a single device. Still open, lower priority: no clock sync configured on the switch, no reboot-durability test done on the current config, and the production VLAN still has no ACL of its own yet — it has nothing running on it to protect, but that won't stay true.