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

TL;DR. Attackers found Tdarr (a self-hosted media transcoder) sitting on the open internet with no login and used its built-in "run a command" features to install two cryptocurrency-mining backdoors. One of them had been there for five months. The miner earned the attacker about a dollar from this machine, but it ate ~9 GB of RAM and most of the CPU, which knocked the NAS connection offline. Both backdoors are removed, the server is locked down, and the logs show no break-ins through SSH.
2
miner backdoors found & removed
~5 mo
oldest backdoor went unnoticed (since May 10)
321,273
failed SSH password attempts in 5 weeks
0
successful SSH break-ins
~$1
what the attacker earned from this server
0
SSH attacks reaching the server since lockdown

Timeline

How they got in

Not through a password. Two misconfigurations combined:

  1. 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.
  2. 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"
PlantedMay 10~Sep 14 (mining logged from Aug 20)
DisguiseFilename copied from a legit community pluginGeneric default-looking flow name
What it rancurl … down.mvip8.ru/setup_mvip8_miner.sh | bashDownloads XMRig 6.26.0 from GitHub, mines Monero
Mining pool—xmrpool.eu:5555
Evidence it ranNo mining logs survive; unknown14,114 accepted shares across 192 job logs
StatusRemovedRemoved

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:

~0.0016
XMR mined by this server (est., nonstop Aug 20 – Oct 16)
0.279
XMR earned by the attacker's wallet in total
~10
machines mining for that wallet right now
~0.5%
this server's share of the attacker's total

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
DateFailed attempts
102
countries the attacks came from
27,455
attempts on the worst day (Sep 30)
~9,400
average attempts per day

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
CountryAttemptsShareIPs

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

UsernameAttempts
admin9,919
ubuntu9,720
user5,669
deploy3,603
test2,269
debian2,266
postgres1,280

Noisiest attackers

IPCountryFailed attempts
175.107.244.96Pakistan26,686
176.53.159.198Turkey15,401
176.53.159.197Turkey14,991
195.178.110.30Andorra6,473
109.160.32.43Netherlands3,534

What got fixed

ProblemFix
Two miner backdoors in TdarrRemoved; container stopped; evidence archived with the script made non-executable
Tdarr reachable from the internetBound to localhost only
Docker ports bypassing the firewallDOCKER-USER iptables rules: only 80/443 reach containers from the internet; everything else is dropped
Host firewallufw enabled, default-deny inbound; verified it survives reboot
SSH exposed to the worldSSH now only reachable over the private VPN (Tailscale)
Root login over SSHDisabled
Brute-force attemptsfail2ban auto-bans (12 bans in its first hour)
NAS share dropping under loadMount options hardened; monitoring script rewritten to stop alert floods

Checked and found clean

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

  1. Docker ignores your firewall by default. If you use ufw with Docker, add DOCKER-USER rules or bind ports to 127.0.0.1. "I have a firewall" isn't true until you've tested it from outside.
  2. 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.
  3. Put admin access behind a VPN. Moving SSH to Tailscale took the attack count from ~9,400/day to zero instantly.
  4. Weird symptoms are signals. This was found because a NAS kept disconnecting. High CPU or RAM with no explanation deserves a look at top.
  5. Check your plugins. Backdoor #1 hid for five months by copying a legitimate plugin's file name.