I Got Hacked: My Hetzner Server Started Mining Monero
Key topics
A server hacker's worst nightmare came true when a Hetzner server started mining Monero, sparking a lively discussion about the vulnerabilities that made it possible. Commenters shared their own experiences with similar incidents, with some pointing to misconfigured Docker containers as a likely culprit, while others highlighted the risks of not using user namespaces. The debate revealed a mix of opinions on the security of Docker containers, with some arguing they're often "unnecessarily privileged, allowing for escape," while others countered that such cases are "very rare." As the conversation unfolded, experts like cyphar, a maintainer of runc, weighed in, emphasizing the importance of using user namespaces to secure setups.
Snapshot generated from the HN discussion
Discussion Activity
Very active discussionFirst comment
19m
Peak period
120
0-12h
Avg / period
20
Based on 160 loaded comments
Key moments
- 01Story posted
Dec 17, 2025 at 4:13 PM EST
17 days ago
Step 01 - 02First comment
Dec 17, 2025 at 4:32 PM EST
19m after posting
Step 02 - 03Peak activity
120 comments in 0-12h
Hottest window of the conversation
Step 03 - 04Latest activity
Dec 22, 2025 at 6:11 PM EST
12 days ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
Is that the case, though? My understanding was, that even if I run a docker container as root and the container is 100% compromised, there still would need to be a vulnerability in docker for it to “attack” the host, or am I missing something?
Also, if you've been compromised, you may have a rootkit that hides itself from the filesystem, so you can't be sure of a file's existence through a simple `ls` or `stat`.
Honestly, citation needed. Very rare unless you're literally giving the container access to write to /usr/bin or other binaries the host is running, reconfigure your entire /etc, or some other insane level of over reach I doubt even the least educated docker user would do.
While of course they should be scoped properly, people act like some elusive 0-day container escape will get used on their minecraft server or personal blog. You arent that special.
And a shocking number of tutorials recommend bind-mounting docker.sock into the container without any warning (some even tell you to mount it "ro" -- which is even funnier since that does nothing). I have a HN comment from ~8 years ago complaining about this.
Imagine naming this executable "ls" or "echo" and someone having "." in their path (which is why you shouldn't): as long as you do "ls" in this directory, you've ran compromised code.
OTH if I had written such a script for linux I'd be looking to grab the contents of $(hist) $(env) $(cat /etc/{group,passwd})... then enumerate /usr/bin/ /usr/local/bin/ and the XDG_{CACHE,CONFIG} dirs - some plaintext credentials are usually here.
The $HOME/.{aws,docker,claude,ssh}
Basically the attacker just meeds to know their way around your OS. The script enumerating these directories is the 0777 script they were able to write from inside the root access container.
Go and Rust tend to lend themselves to these more restrictive environments a bit better than other options.
Thanks for mentioning it - but now... how does one deal with this?
You might still want to tighten things up. Just adding on the "rootless" part - running the container runtime as an unprivileged user on the host instead of root - you also want to run npm/node as unprivileged user inside the container. I still see many defaulting to running as root inside the container since that's the default of most images.
For rootless podman, this will run as a user with your current uid and map ownership of mounts/volumes:
No? Only if you pass in the docker socket or similar.
The core of the problem here is that process isolation doesn't save you from whole classes of attack vectors or misconfigurations that open you up to nasty surprises. Docker is great, just don't think of it as a sandbox to run untrusted code.
1. https://gvisor.dev/
2. https://firecracker-microvm.github.io/
Attacker now needs a Docker exploit and then a VM exploit before getting to the hypervisor (and, no, pwning the VM ain't the same as pwning the hypervisor).
Not only does it allow me to partition the host for workloads but I also get security boundaries as well. While it may be a slight performance hit the segmentation also makes more logical sense in the way I view the workloads. Finally, it's trivial to template and script, so it's very low maintenance and allows for me to kill an LXC and just reprovision it if I need to make any significant changes. And I never need to migrate any data in this model (or very rarely).
but will not stop serious malware
Docker is pretty much the same but supposedly more flimsy.
Both have non-obvious configuration weaknesses that can lead to escapes.
While I generally agree with the technical argument, I fail to see the threat model here. Is it that some external threat would have prior knowledge that an important target is in close proximity to a less hardened one? It doesn't seem viable to me for nation states to spend the expensive R&D to compromise hobbyist-adjacent services in a hope that they can discover more valuable data on the host hypervisor.
Once such expensive malware is deployed, there's a huge risk that all the R&D money is spent on potentially just reconnaissance.
Of course if you have a kernel exploit you'd be able to break out (this is what gvisor mitigates to some extent), nothing seems to really protect against rowhammer/memory timing style attacks (but they don't seem to be commonly used). Beyond this, the main misconfigurations seem to be too wide volume bindings (e.g. something that allows access to the docker control socket from inside the container, or an obviously stupid mount like mounting your root inside the container).
Am I missing something?
I disagree with other commenters here that Docker is not a security boundary. It's a fine one, as long as you don't disable the boundary, which is as easy as running a container with `--privileged`. I wrote about secure alternatives for devcontainers here: https://cgamesplay.com/recipes/devcontainers/#docker-in-devc...
The only serious company that I'm aware of which doesn't understand that is Microsoft, and the reason I know that is because they've been embarrassed again and again by vulnerabilities that only exist because they run multitenant systems with only containers for isolation
But for a typical case, VM's are the bare minimum to say you have a _secure_ isolation boundary because the attack surface is way smaller.
https://support.broadcom.com/web/ecx/support-content-notific...
https://nvd.nist.gov/vuln/detail/CVE-2019-5183
https://nvd.nist.gov/vuln/detail/CVE-2018-12130
https://nvd.nist.gov/vuln/detail/CVE-2018-2698
https://nvd.nist.gov/vuln/detail/CVE-2017-4936
In the end you need to configure it properly and pray there's no escape vulnerabilities. The same standard you applied to containers. Seems like you're drawing some pretty arbitrary lines here.
Are you holding millions of dollars in crypto/sensitive data? Better assume the machine and data is compromised and plan accordingly.
Is this your toy server for some low-value things where nothing bad can happen besides a bit of embarrassment even if you do get hit by a container escape zero-day? You're probably fine.
This attack is just a large-scale automated attack designed to mine cryptocurrency; it's unlikely any human ever actually logged into your server. So cleaning up the container is most likely fine.
non necessary vulnerability per. se. Bridged adapter for example lets you do a lot - few years ago there were a story of something like how a guy got a root in container and because the container used bridged adapter he was able to intercept traffic of an account info updates on GCP
Second, even if your Docker container is configured properly, the attacker gets to call themselves root and talk to the kernel. It's a security boundary, sure, but it's not as battle-tested as the isolation of not being root, or the isolation between VMs.
Thirdly, in the stock configuration processes inside a docker container can use loads of RAM (causing random things to get swapped to disk or OOM killed), can consume lots of CPU, and can fill your disk up. If you consider denial-of-service an attack, there you are.
Fourthly, there are a bunch of settings that disable the security boundary, and a lot of guides online will tell you to use them. Doing something in Docker that needs to access hot-plugged webcams? Hmm, it's not working unless I set --privileged - oops, there goes the security boundary. Trying to attach a debugger while developing and you set CAP_SYS_PTRACE? Bypasses the security boundary. Things like that.
I'm glad you're up to writing more of your own posts, though! I'm right there with you that writing is difficult, and I've definitely got some posts on similar topics up on my site that are overly long and meandering and not quite good, but that's fine because eventually once I write enough they'll hopefully get better.
Here's hoping I'll read more from you soon!
I tried handwriting https://blog.jakesaunders.dev/schemaless-search-in-postgres/ bit I thought it came off as rambling.
Maybe I'll have a go at redrafting this tomorrow in non LLM-ese.
There is nothing wrong with this article. Please continue to write as you; it's what people came for.
LLMs have their place. I find it useful to prompt an LLM to fix typos and outright errors and also prompt them to NOT alter the character or tone of the text; they are extraordinarily good at that.
> IT NEVER ESCAPED.
You haven't confirmed this (at least from the contents of the article). You did some reasonable spot checks and confirmed/corrected your understanding of the setup. I'd agree that it seems very likely that it did not escape or gain persistence on your host but in no way have you actually confirmed this.
Also your part about the container user not being root is still misinformed and/or misleading. The user inside the container, the container runtime user, and whether container is privileged are three different things that are being talked about as one.
Also, see my comment on firewall: https://news.ycombinator.com/item?id=46306974
I'm going to sit down and rewrite the article and take a further look at the container tomorrow.
(Oh and leave the LLMs out of the writing next time <3)
At any rate, this happening to you sucks! Hugs from a fellow HN user, I know that things like this can suck up a lot of time and energy. It’s courageous to write about such an incident incident, I think it’s useful to a lot of other people too, kudos!
>Edit: A few people on HN have pointed out that this article sounds a little LLM generated. That’s because it’s largely a transcript of me panicking and talking to Claude. Sorry if it reads poorly, the incident really happened though!
For what it's worth, this is not an excuse, and I still don't appreciate being fed undisclosed slop. I'm not even reading it.
They also expose kernel interfaces that, if exploited, can lead to the same.
I use them for self-hosting.
If you are using Cloudflare's DNS they can hide your IP on the dns record but it would still have to be locked down but some folks find ways to tighten that up too.
If you're using a bare metal server it can be broken up.
It's fair that it's a 3rd party's castle. At the same time until you know how to run and secure a server, some services are not a bad idea.
Some people run pangolin or nginx proxy manager on a cheap vps if it suits their use case which will securely connect to the server.
We are lucky that many of these ideas have already been discovered and hardened by people before us.
Even when I had bare metal servers connected to the internet, I would put a firewall like pfsense or something in between.
If I run vulnerable software, it will still be vulnerable through a Cloudflare tunnel, right?
Genuinely interested, I'm always scared to expose things to the internet :-).
With the amount of automated bots that port scan looking for anything/everything that's open, as well as scanning DNS records for server IPs that could be targeted, one of the nice patterns of cloud hosting is how application and data servers are hosted behind firewalls of some kind, to effectively be internal.
As for what's exposed to the web, let's say the payload of a website, if there was something vulnerable in the javascript, that could be a weakness hosted anywhere.
Cloudflare can also help achieve this without too much fuss for self-hosted projects, be it personal, and production grade, assuming the rest of the trimmings are tehre.
Oh I see, so that I benefit from the "professional" firewall of Cloudflare, as opposed to my own that I may have possibly misconfigured or forgot to update etc?
Or is there more, like Cloudflare will block IPs that know to come from malicious actors and things like this?
Free way - sign up for a cloudflare account. Use the DNS on cloudflare, they wil put their public ip in front of your www.
Level 2 is install the cloudflare tunnel software on your server and you never need to use the public IP.
Backend access securely? Install Tailscale or headscale.
This should cover most web hosting scenarios. If there's additional ports or services, tools like nginx proxy manager (web based) or others can help. Some people put them on a dedicated VPS as a jump machine.
This way using the Public IP can almost be optional and locked down if needed. This is all before running a firewall on it.
Keeping the IP secret seems like a misnomer.
Its often possible to lock down the public IP entirely to not accept connections except what's initiated from the inside (like the cloudflare tunnel or otherwise reaching out).
Something like a Cloudflare+tunnel on one side, tailscale or something to get into it on the other.
Folks other than me have written decent tutorials that have been helpful.
DNS is no issue. External DNS can be handled by Cloudflare and their waf. Their DNS service can can obsfucate your public IP, or ideally not need to use it at all with a Cloudflare tunnel installed directly on the server. This is free.
Backend access trivial with Tailscale, etc.
Public IP doesn't always need to be used. You can just leave it an internal IP if you really want.
Backend access trivial with Tailscale, etc.
Cloudflare can certainly do more (e.g. protect against DoS and hide your personal IP if your server is at home).
If you plug in a machine at home, it is behind the router, and behind the router's firewall.
If you want more of a firewall locally, something as simple as an EdgeRouter X can get you started easily with this excellent guide: https://github.com/mjp66/Ubiquiti
The nice thing about using cloudflare tunnel, is theres zero ports to expose, ever. The cloudflare tunnel app running on your local machine is what connects out to the internet and takes care of creating a secure connection between cloudflare and your machine.
If you want to forward more than one port to the machine, you could use something like cloudflare to forward to a machine on your home server, and then have the nginx proxy manager or something send the traffic around internally.
It's totally fine to start with cloudflare, and if you aren't already, something like Proxmox (youtube tutorials are pretty quick) gets you up and running and playing pretty quick. Feel free to ask any other questions you like.
One thing I don't really get is why it is "more dangerous" to expose a port on my home IP, versus exposing a port on a Cloudflare tunnel. In both cases, a random user from the Internet can reach my server, and if I host a vulnerable application on that exposed port, it can be exploited. Right?
In order to host my server at home, but keep it outside my LAN, I have been considering having two routers: a "perimeter" router (not sure if that's how it's called) that connects to my ISP, and my normal "LAN" router. The LAN router does not expose anything, as usual. I connect my server to the perimeter router, so that it is in the "DMZ" between both routers. And on the perimeter router, I expose the port to my server. My idea being that if my server gets hacked, it doesn't affect my LAN. A bit like if my server was on a remote VPS.
And then I can run something like proxmox to separate my different services on my server.
But doing this, I expose my home IP instead of a Cloudflare IP, so now I'm concerned that maybe it is a risk? :-)
- exposes the port to be available for inbound connections from anyone on the public internet. When we use a web browser, it's outbound first which initiates responses.
- with an exposed port, you are that much more at the mercy of your firewalls ability to protect and defend the open port, which becomes more of a consideration.
- some people take additional security steps to only allow certain IPs to connect to the exposed port if it works for their scenario.
Compared with the Cloudflare Tunnel:
- if it's a website, for example, nothing is open to the public at all. The CF Tunnel (or a similar tool) conencts first outbound to Cloudflare to setup a secure link between your home server.
- having this amount of security can make it harder to connect back to your own server for admin - this is where a tool like Tailscale (also free) can be handy, where you can continue to have full secured access to the server, and the public side only has whatever you want to expose to the public internet.
- if there's a port or service in specific you're looking to sort out feel free to ask.
Network design:
- keeping a server at home outside of your LAN is a good idea, it could be a perimeter router. DMZ can mean exposed to the internet without a firewall.
- if you read the guide I posted above, it's sounds like an exact match for what your'e trying to figure out - it achieves it with multiple VLANS to separate traffic rules. The PDF has some nice graphics to break it out - I wish I had somethign like this when starting out. The concepts described in the PDF should be possible on most equipment that exposes the settings, and while I don't endorse a particular product, the Ubiquiti EdgeRouter X for the $50 or so is very capable as a starting point for what you are after to be the main router. In thet case of adding a dedicated router like this, you would have to switch your modem into "bridging" mode to let this be the main router for everything. Wireless access points can then be individually added to it. Alternatively if something like pfSense interests you, their parent company makes Netgate equipment that a lot of people seem to love. Both are well represented and supported on Youtube to learn from as well.
But that alone would not solve the problem being a RCE from HTTP, that is why edge proxy provider like Cloudflare[0] and Fastfy[1] proactivily added protections in his WAF products.
Even cloudflare had an outage trying to protect his customers[3].
- [0] https://blog.cloudflare.com/waf-rules-react-vulnerability/ - [1] https://www.fastly.com/blog/fastlys-proactive-protection-cri... - [2] https://blog.cloudflare.com/5-december-2025-outage/
Backend access trivial with Tailscale, etc.
Public IP never needs to be used. You can just leave it an internal IP if you really want.
The firewall could run on a piece of dedicated equipment, where it might not be a server, or it could run in a container, on a dedicated computer, which might be the server.
Again, I'm only speaking about what I have experience with in addition to my past experience and have surprisingly found to run well despite thinking I'd never self-host again.
Unless ran as root this could return file not found because of missing permissions, and not just because the file doesn't actually exist, right?
> “I don’t use X” doesn’t mean your dependencies don’t use X
That is beyond obvious, and I don't understand how anyone would feel safe from reading about a CVE on a widely used technology when they run dozens of containers on their server. I have docker containers and as soon as I read the article I went and checked because I have no idea what technology most are built with.
> No more Umami. I’m salty. The CVE was disclosed, they patched it, but I’m not running Next.js-based analytics anymore.
Nonsensical reaction.
Nothing is immune. What analytics are you going to run? If you roll your own you'll probably leave a hole somewhere.
But kudos for the word play!
If you have decent network or process level monitoring, you're likely to find it, while you might not realize the vulnerable software itself or some stealthier, more dangerous malware that might exploit it.
Is there ever a reason someone should run a docker container as root ?
Re: the Internet.
Re: Peer-to-peer.
Re: Video streaming.
Re: AI.
Internet: The Cuckoo's Egg (nation state, more so than criminals maybe, but it's a blurry distinction)
AI: Elon Musk youtube (often cryptocurrency scam) ads
Video streaming was more obviously exclusively a porn thing
https://www.statista.com/statistics/420400/spam-email-traffi...
That's the point, it private by design and unless they tell you, nobody will ever know how much they use and for what. The true hacker spirit.
There is a vibrant community of people paying for legal goods that value privacy before FUD and ignorance.
https://monerica.com/
As opposed to email?
So... Crypto is illegal so anyone using is defacto a criminal by definition.
Also, for this particular instance this is the best bug bounty program i've ever seen. Running a monero node that hits your daily budget cap is not that bad... It could be way worse like steal you DB creditials and sell it to the highest party... So, crypto actually made this better.
Deliberate heat generation.
If it's cold and you're going to be running a heater anyways, then if your heat is resistive, then running a cryptominer is just as efficient and returns a couple dollars back to you. It effectively becomes "free" relative to running the heater.
If you use a heat pump, or you rely on burning something (natural gas, wood, whatever) to generate heat, then the math changes.
I used a rack of GPUs to heat my house for a few years back when gpu mining was decently profitable, and my electricity bill was 3-4x more than with the heat pump - so you have to keep a close eye on the math when you're running at/under profitability.
If they can enslave 100s or even 1000s of machine mining XMR for them, easy money if you set aside the legality of it.
> RandomX utilizes a virtual machine that executes programs in a special instruction set that consists of integer math, floating point math and branches. > These programs can be translated into the CPU's native machine code on the fly (example: program.asm). > At the end, the outputs of the executed programs are consolidated into a 256-bit result using a cryptographic hashing function (Blake2b).
I doubt that you anyone managed to create an ASIC that does this more efficiently and cost effective than a basic CPU. So, no, probably no one is mining Monero using an ASIC.
That said, do you have an image of the box or a container image? I'm curious about it.
I was lucky in that my DB backups were working so all my persistence wax backed up to S3. I think I could stand up another one in an hour.
Unfortunately I didn't keep an image no. I almost didn't have the foresight to investigate before yeeting the whole box into the sun!
231 more comments available on Hacker News