The most surprising thing about crypto mining in containers is how often it’s not malicious actors, but rather misconfigured applications or developers themselves unintentionally running miners.
Let’s look at a typical scenario. Imagine you have a Kubernetes cluster running a web application. A developer, perhaps to test something or out of sheer convenience, spins up a container that silently starts mining Monero. This isn’t an external breach; it’s an internal process consuming your cluster’s resources.
Here’s what that looks like in practice. You’d start noticing unusual CPU spikes, not tied to your application’s known workloads.
# In Kubernetes, check node resource usage
kubectl top nodes
# Drill down into pods consuming high CPU
kubectl top pods -n <namespace> --sort-by=cpu
# If a specific pod is the culprit, inspect its logs for suspicious output
kubectl logs <pod-name> -n <namespace>
You might see output like this from a miner process:
[2023-10-27 10:30:00] CPU 0: detected XMRig v6.17.0
[2023-10-27 10:30:01] CPU 1: accepted 12345 / 12346 (99.99%) diff=10000
[2023-10-27 10:30:05] CPU 2: hash rate: 500.0 H/s
The core problem is that containers, by their nature, provide an isolated environment, but that isolation doesn’t inherently prevent resource-intensive processes from running. If a container has access to significant CPU and network, it can be a perfect, albeit unintended, mining rig.
The mental model for detecting this involves a few layers:
-
Resource Monitoring: This is your first line of defense. Unexpected, sustained high CPU usage on nodes or within specific pods, especially outside of your application’s normal operational patterns, is a red flag. This isn’t just about identifying that resources are being used, but how and by whom. Tools like Prometheus with
node_exporterandkube-state-metricsare crucial here. You’d set up alerts for sustained CPU utilization above, say, 70% for any pod not explicitly defined as a high-CPU workload. -
Network Traffic Analysis: Crypto miners need to communicate with mining pools. Monitoring outbound network connections from your containers, especially to known mining pool IP addresses or domains, can reveal illicit activity. Tools like Cilium or Falco can help here by providing network visibility at the pod level. You’d look for connections to IPs in ranges associated with pool operators or unusual port usage (though miners often use common ports like 80, 443, or 3333).
-
Process Auditing: Within the container itself, you can audit running processes. If you see
xmrig,cpuminer, or other known mining software running, that’s a direct indicator. This often requires deeper inspection, potentially using tools likekubectl debugto get a shell into a running pod or analyzing container images for embedded miners. -
Image Scanning: Before deploying, scanning container images for known mining binaries or scripts is proactive. Tools like Trivy or Clair can identify these embedded threats within the image layers.
-
Runtime Security: Tools like Falco can monitor system calls within a container. A process suddenly making many network connection attempts or high CPU-bound system calls that don’t align with the application’s expected behavior can trigger an alert.
Let’s consider a real-world fix. Suppose you’ve identified a pod named miner-pod in the default namespace consuming 90% CPU and making outbound connections to 1.2.3.4:3333.
First, you’d want to stop it immediately.
# Delete the offending pod
kubectl delete pod miner-pod -n default
# If it's part of a deployment, you might need to scale down
kubectl scale deployment <deployment-name> --replicas=0 -n default
To prevent recurrence, you need to address the root cause. If it was an untrusted image:
# Example Kubernetes Deployment snippet
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: app-container
image: my-registry/my-app:latest
# Add resource limits to prevent runaway usage
resources:
limits:
cpu: "500m" # Limit to 50% of one CPU core
memory: "512Mi"
requests:
cpu: "200m"
memory: "256Mi"
Setting resources.limits.cpu to a reasonable value, like 500m (half a CPU core), prevents any single container from hogging system resources. This is a hard cap.
If the issue is unauthorized processes within an otherwise trusted image, you’d implement runtime security policies. For example, using Pod Security Policies (though deprecated, the concept remains) or OPA/Gatekeeper to disallow specific binaries from running:
// OPA/Gatekeeper constraint template example
package k8sallowedimages
violation[msg] {
input.review.object.spec.containers[_].image == "some/miner-image:latest"
msg := "Disallowed image: miner-image is known for crypto mining."
}
Or, more granularly, disallowing execution of known miner binaries:
// OPA/Gatekeeper constraint template example
package k8sdisallowedbinaries
violation[msg] {
container := input.review.object.spec.containers[_]
process := container.securityContext.capabilities.add[_] // Simplified example, real check is more complex
process == "EXEC_BIN_XMRIG" // Fictional capability representing execution of xmrig
msg := "Disallowed binary execution: xmrig detected."
}
A more practical approach with Falco involves defining rules that look for specific syscall patterns associated with mining.
# Falco rule example
- rule: Detect XMRig miner
desc: Detects the execution of XMRig miner based on common syscalls.
condition: >
(proc.name = "xmrig" or proc.name = "xmrigd") and proc.cwd != "/usr/local/bin"
output: "XMRig miner detected (proc.name=%proc.name proc.pid=%proc.pid proc.cwd=%proc.cwd)"
priority: critical
This rule would trigger an alert if a process named xmrig or xmrigd is executed outside a specific, trusted directory.
The most effective way to combat crypto mining in containers is to combine strong image security, strict resource limits, and runtime threat detection. It’s not about trusting or distrusting applications, but about building layers of defense against unintended or malicious resource abuse.
The next hurdle you’ll likely encounter is distinguishing between legitimate, high-CPU batch jobs and actual mining operations, which often exhibit similar resource consumption patterns.