Build journal · Part 10

The alarm: closing the door the whole build was for

This is the part the whole build was for. Part 1 opened with the problem: a home alarm that needed to be reachable from outside, and the ugly, exposed way that’s normally done — a public hostname pointing at my house and an open port on the home router, a permanent invitation sitting on the internet. Everything since — the public box, the tunnel, the always-on home anchor — was infrastructure built toward this one goal: reach the alarm from anywhere, with nothing open to the world. Here’s where it finally closes.

The problem, one more time

The alarm has a small network module that lets it be checked and controlled remotely. The conventional way to use that is to forward a port on the home router to the alarm and point a tracking hostname at the home connection, so the software can find its way in from outside. It works, and it means there is a door into the home network, advertised by name, standing open around the clock for anyone on the internet to knock on. That was the arrangement I’d started with, and disliking it was the seed of this entire project.

By this point in the build, everything needed to replace it was already in place. The public box was reachable and hardened. The tunnel existed, with the home anchor permanently connected at the home end. All that remained was to route the alarm through that machinery instead of through an open door.

Closing the door

The change itself was almost anticlimactic, which is the point — the hard work was all the infrastructure that came before.

The home anchor already sits on the home network and holds a permanent link to the tunnel. So instead of the outside world reaching the alarm through the router, my devices now reach it through the tunnel: I connect to the tunnel from wherever I am, that connection lands on the public box, the public box passes it down the tunnel to the home anchor, and the anchor hands it the last short hop across the home network to the alarm. The alarm answers back along the same path. From my phone it feels no different — the alarm software connects and works exactly as before. What’s different is everything about how the connection gets there.

With that path working, I removed the old one. The forwarded port on the router came out. The tracking hostname was decommissioned. And with those gone, the home network went to what it had been missing the entire time: no inbound openings at all. Nothing pointing at the house, nothing listening for a connection from the internet, nothing for a scanner to find. The alarm is now reachable only by me, only through the tunnel, and only after I’ve connected to the public box first. The door the whole project set out to close was finally shut, and the alarm kept working anyway — the two things that usually pull against each other, done at once.

That was the goal from Part 1, achieved. It would have been a satisfying place to stop. But there was a flaw in how I’d done it, and I didn’t see it until I went looking — which is the more useful half of this story.

The rule that looked locked down

To let my devices reach the alarm across the tunnel, the home anchor needed a rule permitting that traffic to pass from the tunnel onto the home network. I wrote one: allow tunnel traffic through to the alarm. It worked — the alarm was reachable, the job was apparently done.

The problem was what that rule didn’t say. I’d written a rule that allowed the alarm. I had not written anything that denied everything else. And on this machine, the default for traffic passing through was to allow it — so my “allow the alarm” rule wasn’t restricting anything. It permitted the alarm explicitly, and it permitted every other device on the home network implicitly, by simply not mentioning them and letting the permissive default take over. Anything that came down the tunnel could reach not just the alarm, but any machine in the house.

In normal use that’s invisible, because the only thing I ever send down the tunnel toward home is alarm traffic. The gap only matters if the tunnel ever carried something hostile — if the public box, the one machine of mine that’s exposed to the internet, were ever compromised. Then whatever got in could use the tunnel as a path straight onto my home network, reaching every device on it, because the rule I thought was a wall was only ever an open gate with a welcome sign for the alarm. The whole design’s promise — that a breach of the public box reaches a rebuildable server and not the house — quietly depended on a restriction I hadn’t actually written.

The lesson is a sharp one: permitting the thing you want is not the same as forbidding the things you don’t. A rule that names an exception and stops there isn’t a boundary — it’s a boundary-shaped gap. And it looks completely correct from the one angle you naturally test it from, which is “can I reach the alarm?” The answer is yes, so you move on, and the hole stays open because nothing you’d normally do reveals it.

Closing it properly, and proving it

Fixing it took two parts: allow the alarm, then explicitly deny everything else trying to cross from the tunnel onto the home network. The order matters — the specific permission has to come before the blanket denial, so the alarm is waved through before the “block everything” rule can catch it. With both in place, tunnel traffic can reach exactly one device at home and no other.

But writing the fix wasn’t the same as knowing it worked, and by this point in the build I’d learned not to trust “looks right” — so I tested it the way the whole series keeps insisting things be tested: by trying to break it, from outside, for real. I took a phone off the home network entirely, onto mobile data, so its traffic had to take the genuine path in from the outside world through the tunnel. Then I checked three things. The alarm: still reachable — the thing I need still works. Two other devices at home, picked precisely because they aren’t the alarm — a home appliance and the router itself: now unreachable, where a moment before the fix they’d have answered. And the anchor’s own services: still fine, because those aren’t affected by this particular boundary.

Only when a genuinely remote device could reach the alarm and nothing else did I count it done — and the machine’s own traffic counters backed it up, one number showing the alarm connections waved through, another showing everything else being turned away, matching the test exactly. The point that stuck: the fix and the proof of the fix are two different pieces of work, and the second is the one that turns “I think it’s secure” into “I watched it refuse the traffic it’s supposed to refuse.” A boundary you haven’t watched reject something is just a hopeful comment in a config file.

What the whole thing adds up to

So the door is shut, verified from the outside, and the alarm works. Standing back, the shape of the finished thing is exactly what Part 1 set out to build, and nothing more than it needed to be: one small rented box exposed to the internet and hardened against it; an encrypted tunnel that only ever opens outward; a cheap always-on computer at home holding the home end; and behind all of it, a home network that accepts nothing from anyone, with its services reachable only by me and only through the tunnel. The alarm — the thing that started it — is now the safest it’s ever been to reach, precisely because reaching it no longer requires leaving any door open.

That’s the through-line of the whole build, in one service. Every part of it came from refusing the easy exposed option and doing the harder closed one instead, and the payoff is a home that’s fully reachable to me and invisible to everyone else. It started as an annoyance about an alarm and an open port. It ended as a small, quiet system I understand completely, that tells me when it’s unwell, and that keeps the front door shut without ever getting in my way.

There’s more to come — cameras waiting to be mounted, home automation to tie the pieces together, and whatever the next problem turns out to be. But the core is done, and it does the one thing I first wanted, the way I wanted it done. That was the point of writing all this down: not that the setup is impressive, but that every piece of it exists for a reason I can explain.