A routine task that wasn’t
This was supposed to be a boring afternoon. The plan was some overdue housekeeping: carve out a proper guest VLAN so visitors’ devices land on their own isolated network instead of sharing a broadcast domain with everything I actually care about. Textbook segmentation. The kind of change you make, verify, and forget about.
I never got to the guest VLAN that day. While I was poking around the router’s config to plan the change, I noticed something that stopped me cold: there were no firewall rulesets on the box. None. Not a permissive one, not a misconfigured one. There was simply nothing there.
That mattered a lot more than it would on most people’s networks, and it took me an embarrassingly long minute to understand why.
Router-on-a-stick, with a catch
My network is a router-on-a-stick design. A single router handles inter-VLAN routing, and all of my traffic filtering, every “this network can’t talk to that network” rule I thought I had, was supposed to live on that one device. That’s the whole point of the topology: the router is the chokepoint, so the router is where policy gets enforced.
Which is fine, right up until the router has no policy. With no rulesets in place, “the router enforces everything” quietly becomes “the router enforces nothing.” Every VLAN boundary I believed in existed only in my mental model, not in the config.
And then I looked at the WAN side.
What was actually listening
The router had been handed a public IP by my ISP, which is normal. What was not normal is what that public IP was exposing. From outside my network, with nothing but that address, you could reach:
- SSH on the router, sitting open to the entire internet.
- The admin GUI, same story, login page served straight to the WAN.
- An open DNS resolver, the router answering recursive DNS queries for anyone who asked.
I confirmed it the honest way, by scanning my own public IP from a machine that wasn’t on my network (a cheap cloud VM, though a phone on cellular data works just as well). The ports answered. Everything I’d assumed was tucked safely behind the router was, in fact, the router itself, standing in the open doorway.
Checking the router’s uptime and logs told me the rest of the story: this had been the state of things for roughly 55 days. Nearly two months of an internet-facing management plane and an open resolver, with no firewall in front of either.
For the record, everything described here is fixed, and has been since that afternoon. I’m writing about a hole that’s closed. But 55 days is 55 days.
Why this happens: the “traffic flows, so it’s fine” trap
Here’s the uncomfortable part. Nothing was broken. Every device on my network worked. Streaming worked, DNS resolved, remote access worked, the family never noticed a thing. By every observable signal I use day to day, the network was healthy.
That’s exactly the trap. I had been unconsciously treating “traffic flows correctly” as a proxy for “the network is configured correctly,” and those are not the same claim. A network with no firewall rules doesn’t feel different from a well-secured one when you’re just using it. Packets route the same. The difference only shows up when someone goes looking for what’s exposed, and attackers go looking constantly. Open resolvers get conscripted into DNS amplification attacks. Exposed SSH and admin panels get credential-stuffed around the clock by bots that found you in a mass scan, not because they were targeting you.
I suspect this started life as a “temporary” state during some past setup or migration, a box brought up with connectivity working and firewalling deferred to “later.” Later never came, because nothing ever forced the issue. Working systems don’t nag you. That’s the whole problem with security regressions: the system’s silence is not consent.
The fix pattern
The concrete fix on an EdgeRouter (or anything Vyatta/EdgeOS-flavored) is a pair of firewall rulesets applied to the WAN interface, both defaulting to drop:
WAN_LOCALgoverns traffic destined for the router itself. This is the one that slams the door on internet-facing SSH and the admin GUI.WAN_INgoverns traffic being routed through the router to hosts behind it.
The pattern, genericized and illustrative rather than my verbatim config, looks like this:
firewall {
name WAN_LOCAL {
default-action drop
rule 10 {
description "Allow established/related"
action accept
state {
established enable
related enable
}
}
rule 20 {
description "Allow ICMP (optional)"
action accept
protocol icmp
}
}
name WAN_IN {
default-action drop
rule 10 {
description "Allow established/related"
action accept
state {
established enable
related enable
}
}
}
}
interfaces {
ethernet eth0 {
firewall {
local {
name WAN_LOCAL
}
in {
name WAN_IN
}
}
}
}
The shape is the important part. Default-action is drop, so the ruleset is deny-by-default: anything I don’t explicitly allow gets dropped. The only inbound traffic that gets through is what’s part of a connection something inside my network initiated (the established/related rule). Unsolicited connections from the internet to the router’s own services now hit a wall. If I later want to reach the router remotely, I do it through the VPN that’s already terminating on the LAN side, not by leaving SSH naked on the WAN.
The open resolver got handled separately, by making sure the DNS service only listens on internal interfaces instead of answering on the WAN. A recursive resolver has no business taking questions from the public internet, and the fix is to bind it to the networks that are actually allowed to ask.
After applying all of it, I re-ran the same external scan. The ports that had been answering for 55 days went dark. That’s the confirmation that matters: not “does my network still work” (it always did), but “does the outside world still see anything it shouldn’t.”
The takeaway
The lesson I keep coming back to is that “working” and “secure” are different properties, and only one of them announces itself. A misconfigured-open network behaves identically to a locked-down one until the moment it doesn’t, and by then you’re not the one who noticed first.
So the practical habit I’ve adopted, and the one I’d push on anyone running their own gear: periodically scan your own WAN IP from outside your network and look at what answers. It takes five minutes and a machine that isn’t on your LAN. Don’t infer your security posture from the fact that everything works. Go check what’s actually listening at the edge, because the traffic flowing correctly tells you nothing about the doors standing open.
I did eventually build that guest VLAN. But it felt very different doing it on a router that was finally enforcing the boundaries I’d been imagining all along. That segmentation work, and the mistake I made there, is the next post.