On Saturday evening my new security monitor finished its first proper run and told me I had 6,688 problems.
I read the list for a while. Then I made tea, came back, and read some more. It is a strange feeling, being told you are under siege by a machine you built yourself, on a weekend at my workdesk, with the kettle on.
The final count, after I fixed the things that were actually my fault, was 12. Six of those needed a decision. Four I could patch, and did that evening. The rest are notes to keep an eye on.
So my monitor was wrong about 99.8% of what it said. That is not a small error. It is the entire output. And the interesting part — the part worth writing down — is that nearly all of it was my fault, not the machine’s.
What I asked for
I run a handful of services on my own hardware: a website, a few small tools, a few intranet pages. Nothing dramatic. I wanted something to watch them while I am not looking — something that notices a certificate about to expire, or a piece of software with a known hole in it.
I did not want a cloud service reading my logs, no way. I wanted a small program, on my own metal, whose source I can read. That is also how I was able to find the bugs below. You cannot audit a dashboard you do not own.
What I got
The first report was an avalanche. Among the highlights:
- A warning about a bug from 2001, in software I had installed for one day and never started.
- An urgent notice about “Apache Struts“, a web framework I have never knowingly installed, in a sentence that happened to contain the word Apache. My machine does not run Struts. It runs Apache, which is a different thing wearing the same surname.
- Repeated alarms about a hole in a program’s server component, on machines that only had the client. More on that one, because it is the funniest.
Twenty-plus years in this trade and I still get a small, cold feeling when a machine says “urgent”. Then I read the detail and it turns into tired affection. The bot was not lying. It was answering a slightly different question from the one I asked, at full volume, forever.
Mistake one: I read “unfixed” as “dangerous”
Here is the thing I had forgotten, and it is the single most useful idea in this whole piece.
When someone finds a flaw in software, the people who look after that software have three options, not two. They can fix it. They can decide it does not matter enough to fix. Or they can still be deciding.
My monitor treated all three as “you are in danger”. It saw the word “open” and raised an alarm, because “open” reads like “unresolved”, and unresolved reads like “this is about to hurt you”.
The reality is duller. Plenty of those flaws sit in parts of the program I will never use, or need an attacker who is already logged in, or live in code unchanged since the last century. The maintainers looked, wrote “not worth it”, and moved on. That is a judgement call by people who know the code, and it deserves respect.
When I made the tool respect that judgement, it stopped showing me nearly 32,000 entries it had been holding back. Thirty-two thousand warnings that the people who wrote the software had already decided were not worth a patch.
I had been drowning in other people’s filings, not in any real danger.
Mistake two: I broke the arithmetic
This one is my bug, in my code, and it is gloriously stupid.
Software version numbers sometimes carry a prefix, like 1: in front of 2.0. It means “we changed how we count; this numbering is newer than the old numbering even if the digits look smaller”. One of those 1: moments.
I stripped that prefix off the version installed on my machines — but not off the version the security data said contained the fix. So the comparison ran between a number with a prefix and a number without one, and my code kept concluding that the repaired software was older than the repair.
The effect: every single thing that had already been fixed looked unfixed. My monitor was reading a shelf of new books and reporting them all as overdue.
If you take one line from this article, take this: the tool was not wrong about the world. It was wrong about how to compare two numbers. That is a much smaller, much more fixable kind of wrong — and it would have been invisible if I had only ever looked at the summary line instead of the list.
Mistake three: it could not notice good news
A monitor that only reports problems, and never notices when they go away, is not a monitor. It is a nag with an opinion.
Mine did exactly that. I patched four real holes, and the next morning the report was still red. The tool only ever added lines. It had no way to remove one.
So I taught it to close its own findings: if a problem stops appearing on a machine that was just checked, mark it fixed. The evening I patched those four, the next run quietly closed all four by itself. That was the first moment the thing did something a nag cannot do. I nearly took a photo.
Mistake four: the telnet server I do not run
My favourite. The tool raised a serious alarm about a hole in a telnet server. Telnet is ancient. It is how we connected to computers before we knew better.
I do not run a telnet server. What I had was the telnet client — the program you use to connect to someone else’s server. Both come from the same package family, so the security data listed the flaw against the family name, and my tool matched the family and shouted.
That is a recall notice for a car, sent to you because you own their bicycle bell. Same company. Not the same object. Not remotely the same risk.
The fix was four lines: if the vulnerable component is a specific program, require that program to actually be installed before believing the alarm.
What I changed
Four rules, all of them dull, which is usually how you can tell a rule is doing work:
- Respect the maintainers’ judgement. If they have looked and said “not worth fixing”, do not wake me.
- Compare versions properly, including the odd prefixes.
- Cap the list. Forty findings, at most two per package. One noisy library should not own the whole report.
- Let findings close themselves when the problem stops appearing.
Twelve open items. Six needing a decision. Four patched that evening, and the next run closed all four without help.
The quietest, most useful line on the report is not the list of what is wrong. It is the count of what went quiet since yesterday. A tool that can prove improvement is the only kind I believe when it says nothing at all.
The part that matters if you are not technical
You will meet this problem in a form that has nothing to do with servers. Some dashboard will tell you that 300 invoices are overdue, or that 47 customers are at risk. The number will be big and the colour will be red. Before you act on it, ask three questions.
What would make this warning go away? If nothing can, it is decoration. A warning you cannot clear is not information; it is furniture.
How many of these would you act on today? The honest number is almost always small. A list of 6,688 things is not a list. It is a mood.
Who decided this counts as a problem? Often nobody did. A field was empty, or a word matched, and a rule fired. “Open” is not the same as “dangerous”, and “detected” is not the same as “matters”.
A good alert tells you what to do next. A bad one tells you how hard it is working.
Why this is written plainly
I could have written this with the usual furniture: severity scores, vector strings, the names of specific flaws. It would have looked more impressive and reached fewer people.
I have spent most of my working life in rooms where that language is the price of entry. It keeps the club small, and it makes the people outside it easy to frighten — useful if you are selling them a subscription, useless if you are trying to help them.
The lesson here is not a command. It is a habit of mind: when a machine says something is urgent, ask what it is measuring, and whether it can ever say “fixed”. Anybody can learn that. A shopkeeper drowning in a stock system that flags 400 “critical” items can learn it. So can a parent reading a school app that calls their child “at risk” because a form is late.
So the words here are deliberately plain, and I have explained the jargon where it was unavoidable. Not because the reader cannot handle the technical version, but because the technical version is where this knowledge usually goes to die — filed neatly, read by twelve people, and never allowed to reach the person who actually has to decide whether to panic.
The bot is quiet now. Twelve items, four of them already closed by its own hand.
I still check it every morning. Not because I doubt it any more — I count the numbers because counting is cheap, and it is the only way I have ever caught a machine lying with confidence.
Trust the work. Count the summary.
