James Carr · systems operation and adversarial analysis
I don't get excited by building features. I get excited by the moment something is behaving strangely and nobody knows why yet – and on a machine facing the internet, the answer is usually that somebody is trying something.
What can be seen is what they asked for, how often, and whether they came back after being blocked. What cannot be seen is why. A log line will never tell you motive, and keeping those two apart – evidence on one side, judgement on the other – is most of the work.
391 detection(s) from 40 registered countries, since 2026-08-12 18:55Z.
How to read this
A marker shows where a network is registered – where somebody rented
capacity, not where they are. Colour and size follow how many detections came
from that country.
An arc is drawn when a request arrives: it marks the two ends of that request,
not the route it took.
The host marker is the one declared position here; a machine cannot read
its own latitude.
20 detection(s) could not be placed – no coordinates for the
country, or no country recorded – and are counted in the total rather
than shown on the plot.
An AI, grounded in what I've written, honest about what it doesn't know
Ask about my experience, skills, or background. This is an AI answering from notes I wrote about myself; it will not make things up, and if it does not know it will say so. For anything real, the contact link is always better than a bot.
Read from the host at the moment you loaded the page, and updated over the open connection while you read. Nothing here is a screenshot, a mock, or a number typed into the markup. Where a reading cannot be taken, the panel says so rather than showing a plausible default.
| APPLICATION | ACTIVE / running |
| EDGE PROXY | ACTIVE / running |
| DATABASE | ACTIVE / running |
| INTRUSION FILTER | ACTIVE / running |
No addresses currently held. Bans are actioned by fail2ban at the edge from the same access log this page reads; this panel reflects the live jail.
Every timestamp on this site is UTC, to the second. A distributed log is only as good as the clocks behind it, so the node runs in UTC rather than a local zone – there is no offset to reason about during an incident, and no hour that happens twice a year.
| Source Masked source The final octet is zeroed before anything is stored or displayed. Enough to tell two sources apart and attribute a network, without retaining data that identifies a person. The full address exists only in memory, for the moment it takes to look up its country. | Country | Requests | Days | Assessment Campaign Related activity from one source network grouped over time, rather than counted as separate requests. A single probe says nothing; what an actor went looking for, how long they persisted and whether they returned is the part with analytical value. | |
|---|---|---|---|---|---|
| 213.7.27.xxx | CY Cyprus Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. | 47 | 4 | Persistent – returned after block · HIGH CONFIDENCE | + |
| 195.178.110.xxx | AD Andorra Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. | 260 | 2 | Persistent – returned after block · HIGH CONFIDENCE | + |
| 20.151.10.xxx | CA Canada Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. | 51 | 2 | Persistent – returned after block · HIGH CONFIDENCE | + |
| 45.148.10.xxx | AD Andorra Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. | 22 | 2 | Persistent – returned after block · HIGH CONFIDENCE | + |
| 102.220.160.xxx | SI Slovenia Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. | 8 | 2 | Persistent – returned after block · HIGH CONFIDENCE | + |
Ranked by significance, not recency. A row opens to show the evidence behind its verdict. The diamond flags a source that returned after a block or has been active across more than one day – the signals that separate a passing scan from something deliberate, and which only appear with time.
Watching a machine and watching an opponent are different problems. A disk filling up does not change its behaviour because you noticed. An adversary does – which is why a signature only catches what somebody already catalogued, and fails on the first day of anything new.
So detection here is built on deviation from a measured baseline rather than a list of things to look for, and the reporting keeps what was observed apart from what has been inferred, with a confidence attached to the judgement.
Blocking an address costs an opponent almost nothing – addresses are rented by the hour. Behaviour is far more expensive to change, so the durable detection is the pattern rather than the indicator. The clearest signal available is simply whether a source came back once its block expired: indiscriminate scanning never revisits.
Sometimes a system is simply broken, and that needs the same discipline. Press the button and a background worker takes a real fault – genuine CRC failures, genuine added latency. A separate detection service, which knows nothing about the trigger, records each threshold crossing as it observes it. The fault clears itself after 45 seconds, and recovery is confirmed against measurements taken afterwards rather than assumed from the fact it cleared.
Every request reaching the edge lands in the proxy's access log. A worker tails that log, classifies what matters, enriches it against a geolocation database held on this machine, masks the source to a /24 and files it. The intrusion filter reads the same log through its own rules and blocks at the packet level. Nobody is watching any of it – the automation is the claim, not the monitoring. If you would like to appear in that feed yourself, there is a range set aside for it.
Everything else here is measured by this machine, which means you are trusting the machine. These are not: they are assessments by independent services, and the links re-run them live. If a grade below has slipped since it was recorded, the link will say so rather than this page.
Recorded when the link was last run, not read live – so unlike every other figure on this site, these are a claim rather than a measurement. That is exactly why each one is a link.
If any of the above is the kind of work you need doing – running systems in real time, working out what something was actually trying to do, and building the automation that catches it next time – I'd like to hear about it.
Everything on this site runs on one small instance I own and operate. The source is public if you want to read how any of it works.
Years of high-responsibility operational work through long shifts, where monitoring, accurate logging and staying calm when something is wrong matter more than speed, and the cost of missing something is not a bad sprint.
Underneath it, a self-taught systems engineer who builds from bare metal up, an OS, an RTOS, this site, because understanding how something works at every layer is the point.
One of two core engineers on a B2B SaaS expense platform: owns production releases, monitors via Grafana and ELK, and investigates live incidents on systems other businesses depend on to pay people.
.NET and PostgreSQL day to day, on Linux, with the integration work that comes with talking to payroll and finance systems.
Blazor Server on .NET 10, PostgreSQL, behind Caddy on RHEL-family Linux (AlmaLinux 9), running as an unprivileged service user.
The application can read a fixed, closed list of host files and commands and nothing else. No request-derived value ever reaches a command or a file path.