Your remote access works — but you have not proved it
Three flats, three answers. Why a successful request from home proves nothing, why bans never expire — and why one location has nothing at all.
Contents
The most honest reason for looking into my own flat from outside is not a technical one: Bruno stays there. What he does once the door closes was a mystery for a long time — and that is what made me not only set up remote access but actually trust it.
Because a camera you cannot reach when it matters reassures nobody.
Three flats, three answers to the same question:
| Remote access | |
|---|---|
| Kapfenberg | running since 29.08.2026 |
| Vienna | since 08.09.2026, after an evening of fault-finding |
| Merano | not documented at all |
The third entry is the most honest one, and I come back to it at the end.
The setup that exists in two houses
internet --443--> router --forwarding--> Pi --> proxy --> Home Assistant
Plus a dynamic DNS name. That is not a luxury: in Kapfenberg the public address changed within three weeks. That is exactly what the name is for — and exactly why, from that day on, the documentation carries the name and no longer the number.
How remote access cannot be proved
This is the part I value most, because I walked into both dead ends myself.
First dead end: the request from inside your own house. Fetching the public
name from the home network returns 200 OK. It looks like proof and is not: the
request goes to the router, which hands it back through its own forwarding rule.
It was never on the internet. This is called NAT hairpinning.
Second dead end: a fetch by a tool that “runs in the cloud.” The thought was obvious — if the fetch runs on somebody else’s infrastructure it comes from outside.
It ran locally. The proof was in the ban log: the recorded sender was the home’s own public address, complete with the tool’s user agent. Hairpinning again, just with a different label on the envelope.
What both do show: the forwarding rule exists and points at the right machine. What neither shows: whether the provider lets incoming connections through at all.
Exactly two routes are valid:
- From a phone over mobile data, Wi-Fi switched off.
- From a machine outside, a rented server for instance.
The trick with the failed attempt
The counter-check in the log only works on a failed attempt — the ban log records rejected logins only. So log in wrongly on purpose; then the real sender address is there.
Count along while doing it: after five failed attempts the address lands in the ban list. Tolerable for a mobile address, annoying for your own line.
Bans never expire by themselves
Read in the source: the ban list is loaded from the file at start-up, after which it lives in memory and is only added to. There is no expiry time.
From that follows something easily overlooked: cleaning the file is not enough. Without a restart the ban stays active in memory.
Two things belong cleanly apart:
| lives where | survives a restart? | |
|---|---|---|
| counter of failed attempts | memory | no — zero after every start |
| completed ban (5 failures) | file | yes, permanently |
So you cannot stumble into a ban over several days. It takes five failures in one run.
The cleanup runs daily at four in the morning: remove entries older than 24 hours — and restart only if something was actually removed. On most days nothing happens at all.
I tested it with an artificial list from the address range reserved for documentation:
| Entry | Age | Result |
|---|---|---|
| first | 30 h | removed |
| second | 2 h | kept |
| third | date unreadable | kept |
The third case is deliberate. Lifting a ban because you cannot read its date would be the wrong direction in which to err.
The correction that makes documentation worthless
For eight lines my own documentation said that only “the proxy on 443” is exposed.
Measured from the office, so genuinely from outside:
port 22 answers <- the SSH add-on
port 443 answers <- the proxy
port 2222 timeout
port 22222 timeout
Port 22 is exposed as well. Claude had relied on that documentation and claimed on its basis that packages could not be deployed from here. Wrong — I noticed it myself.
Documentation that does not know about an exposed port is worse than none: it sounds like a verified statement.
I then looked up how that open gate is secured:
| password login | off |
| keyboard-interactive | off |
| login as main user | yes |
| stored keys | exactly one |
So: main user yes, but with exactly one key. Whoever does not have it gets nowhere on port 22, however often they try. The exposure is defensible — it just had not been written down.
Two factors and an objection that does not hold
The objection to two-factor login was: with only one phone it is tedious to enter a second factor every time you log in.
That does not hold. Home Assistant issues a refresh token per device and browser. Tick “stay signed in” and you enter the second factor once per device, not once per session.
What I did reject was the obvious shortcut of declaring the home network blanket trustworthy and skipping the login there. It shifts security onto the assumption that only authorised people are on your Wi-Fi — and that holds exactly until one device on the network is compromised.
And the third location
For Merano there is no remote-access file. Not a short one, not an incomplete one — none.
That is not an omission of this article, it is the state of things. And a second open item hangs off it: the same ineffective configuration section that cost me an evening in Vienna is probably sitting there too. It has not been checked.
The most honest entry in a comparison between locations is the one where nothing is written.
What I’d suggest
- Test from outside, not from inside. Phone on mobile data, Wi-Fi off. Everything else may be hairpinning and still looks like success.
- Trust no tool you believe runs elsewhere. Check the log for the sender address that actually arrived.
- Use a name, not the address. It changes, and it does so without notice.
- Write down every exposed port, including the convenient one. An incomplete list of open gates is more dangerous than none.
- Clean the ban list — with a restart. Without one the ban stays in memory whatever the file says.
- Set up the second factor before you open the port. Afterwards it becomes a task that gets left lying around.
So what?
Remote access is the one point in these three flats where a mistake means more than inconvenience. Everything else costs data or comfort at worst. Here there is a door.
Which makes it all the more unpleasant how easily you talk yourself into success. Twice I believed I had proved access from outside, and both times the request had never left the house. Each time it looked like proof — green status, 200 OK, all good.
The difference between “it works” and “I checked it” is not academic where remote access is concerned. In one case you know the door opens. In the other you only know you are standing on the right side of it.
If you want to follow this: use RSS
No newsletter. You give me no address, I keep no list, and nobody has to agree to anything to learn that an article is finished. RSS is the older and, for both sides, the more honest solution.
How it works, and why no newsletter
- 1Get a feed reader. No account needed with an app on your phone or a browser extension; use a hosted service if you prefer.
- 2Add the address above to it.
- 3Done. New articles turn up in your reader by themselves — unread stays unread, and nothing lands between invoices and ads in your inbox.
Why that is better: your reader fetches the file. I get no address and cannot see who reads or whether anyone opened it. Unsubscribing means deleting the entry — no link, no confirmation mail, no me.
