Rotazione delle credenziali database dopo una violazione ISPConfig

Ruoto le credenziali nel momento in cui sospetto una violazione. Non dopo averla confermata. La rotazione delle credenziali database su un server ISPConfig suona come manutenzione di routine. Smette di essere routine il giorno in cui trovi una web shell su un sito ospitato. O un file di configurazione che non sai spiegare, finito in un backup pubblico. A quel punto, ogni password legata a quello stack di database deve essere nuova. Verificata. Documentata. Non semplicemente presunta a posto.

rotazione delle credenziali database: lucchetto e chiave sopra un database ISPConfig

Quando la rotazione non è più facoltativa?

Ci sono alcuni scenari che tornano a sufficienza da farmi tenere pronto un piano di rotazione. Preferisco non improvvisarne uno sotto pressione.

Un plugin o un CMS su un sito ospitato viene compromesso. Ho raccontato un caso reale su questo tipo di server in PHP2Shell: come ho protetto i server in attesa della patch, una vulnerabilità PHP che permetteva a un attaccante di piazzare una web shell prima che esistesse una patch. Una volta che una web shell viene eseguita sotto un utente di hosting, spesso può leggere il config.inc.php di quel sito. Su un box ISPConfig condiviso, quel file sta proprio accanto alle credenziali del database del pannello di controllo stesso. Non solo la credenziale che l’attaccante stava effettivamente cercando.

Un file di configurazione finisce dove non dovrebbe. Un archivio di backup lasciato in una cartella pubblica. Un repository pubblicato con un file fuori posto. Un log più leggibile di quanto chiunque intendesse. config.inc.php e mysql_clientdb.conf non hanno motivo di stare in nessuno di questi posti. Gli errori succedono comunque, compresi i miei.

Un amministratore di sistema lascia il team. Per quanto amichevole sia l’addio, le credenziali database condivise che deteneva sono credenziali di cui non mi fido più del tutto. La fiducia non si trasferisce automaticamente quando qualcuno esce dalla porta.

Un’intrusione sospetta, anche non confermata. Questo è il caso più difficile da spiegare a chi non ha mai gestito un server sotto sospetto di attacco. Non si aspetta la prova prima di agire. Si presume la compromissione e si ruota. Una rotazione non necessaria costa un pomeriggio. Una saltata, dopo una violazione reale, può costare ogni sito ospitato dal server.

Perché la rotazione delle credenziali database manuale è così incline all’errore

La prima volta che ho ruotato a mano le credenziali database di ISPConfig, ho sottovalutato quanti file fossero coinvolti. Devono tutti cambiare insieme, altrimenti qualcosa si rompe silenziosamente poche ore dopo.

C’è config.inc.php sul lato server, e una seconda copia sul lato interfaccia. Entrambe devono avere gli stessi nuovi valori. C’è mysql_clientdb.conf, che ISPConfig legge per gestire il database di ogni sito ospitato, non solo la propria manutenzione interna. Dovecot, Pure-FTPd e Postfix mantengono ciascuno una propria copia di alcune delle stesse credenziali. Mail e FTP possono smettere di autenticarsi silenziosamente se aggiorni l’utente del database e ne dimentichi anche solo uno dei tre.

Poi c’è la topologia Master/Slave che alcune delle mie installazioni usano. Un nodo Slave si autentica al database del suo Master sulla rete, con una password separata. Quella password va ruotata sul Master stesso, non solo in locale. Sbaglia la sequenza, e uno Slave può chiudersi fuori dallo stesso Master da cui dovrebbe replicare.

Niente di tutto questo è concettualmente difficile. Sono tanti file. Diversi servizi da riavviare, in un ordine sensato. Quasi nessuna tolleranza per un errore di digitazione, specialmente mentre lo fai sotto pressione, appena dopo aver trovato qualcosa che non volevi trovare. Questa combinazione è esattamente il motivo per cui la rotazione delle credenziali database continuava a sembrarmi più rischiosa a mano di quanto il compito stesso dovrebbe essere. È per questo che ho scritto reset_DB_password.sh, dopo aver vissuto il problema io stesso più di una volta.

Cosa fa davvero reset_DB_password.sh

reset_DB_password.sh rileva se il nodo è Standalone, Master o Slave. Poi esegue solo le fasi che quel ruolo richiede.

La Fase A ruota la password root locale di MySQL. È la password che ISPConfig stesso usa per gestire il database di ogni sito ospitato. Lo script aggiorna mysql_clientdb.conf per farlo corrispondere al nuovo valore.

La Fase B ruota la password dell’utente di controllo ispconfig. Aggiorna config.inc.php sia sul lato server che sul lato interfaccia. Poi aggiorna le credenziali corrispondenti dentro Dovecot, Pure-FTPd e Postfix, così mail e FTP continuano ad autenticarsi senza un passaggio manuale separato su altri tre file di configurazione.

La Fase C viene eseguita solo su uno Slave. Si connette da remoto al database del Master. Ruota lì la password dell’utente Slave, poi aggiorna dbmaster_password in locale, così la replica continua ad autenticarsi correttamente con il nuovo valore.

Dopo la Fase B, lo script offre di riavviare Dovecot, Pure-FTPd e Postfix per te. Dico quasi sempre di sì. Una rotazione delle credenziali che lascia un servizio di posta in esecuzione con la vecchia password non è finita, è solo silenziosamente rotta. Riavviare nella stessa sessione, subito dopo il cambio dei file di configurazione, mantiene tutto dentro una sola breve finestra di manutenzione invece di tre scoperte separatamente più avanti.

Backup prima che qualcosa cambi

Prima di toccare un solo file, lo script esegue una copia rsync completa di /usr/local/ispconfig/ in una cartella con timestamp. Tenta anche un mysqldump non bloccante dei database mysql e dbispconfig. Non bloccante di proposito: preferisco finire una rotazione delle credenziali database piuttosto che restare in attesa di un dump bloccato per qualche motivo non collegato. Ogni file di configurazione che modifica riceve prima una propria copia .bak, prima che qualsiasi stringa al suo interno venga sostituita.

Niente di tutto questo sostituisce una strategia di backup indipendente. Continuo a fare uno snapshot separato, o un backup completo, prima di eseguire questo script su qualsiasi server che conta davvero. Il disclaimer dello script stesso dice la stessa cosa, in modo più diretto di quanto abbia appena fatto io.

Dry run prima, sempre

Ogni fase chiede conferma prima di cambiare qualcosa. –dry-run simula un’intera esecuzione senza toccare un solo file. Uso il dry-run prima su ogni server, ogni volta. Anche su quelli su cui ho già ruotato le credenziali, e penso di conoscere bene. –skip-local-root salta la Fase A, per quando serve ruotare solo la password dell’utente di controllo. –role=master o –role=slave forzano il rilevamento automatico, per il raro caso in cui non legga correttamente da solo la topologia di un server.

Le password che genera sono di 32 caratteri, solo lettere e cifre. Lunghe abbastanza da resistere a un tentativo di indovinare. Semplici abbastanza che i parser di MySQL e PHP non si inceppino mai su un simbolo fuori posto in una stringa di connessione. Ho testato lo script su ISPConfig 3.3.1p1. Non l’ho eseguito contro rami più vecchi o più nuovi. Non darei per scontato un comportamento identico lì, senza prima verificarlo io stesso.

Il ruolo di un nodo non è sempre ovvio a colpo d’occhio, specialmente su un server che hai ereditato invece di costruire tu stesso. È per questo che esiste –role, e perché l’output del dry-run merita di essere letto riga per riga la prima volta, non scorso velocemente. Preferirei passare due minuti a confermare che uno Slave è davvero uno Slave, piuttosto che scoprirlo nel modo peggiore a metà rotazione.

Cosa ti direi prima che tu lo esegua

Avviso: lo script è fornito così com’è, a scopo informativo. L’uso è sotto la tua esclusiva responsabilità: non mi assumo alcuna responsabilità per perdita di dati, interruzioni di servizio, o qualsiasi errore generato da un utilizzo scorretto o da un contesto diverso da quello in cui lo eseguo io stesso. Fai sempre un backup indipendente o uno snapshot VM prima di eseguirlo in produzione, indipendentemente da ciò che il passaggio di backup dello script già catturi per te.

È software libero. Puoi ridistribuirlo e modificarlo, con attribuzione a me come autore originale. Il codice sorgente di reset_DB_password.sh, e il resto della collezione ispconfig-fast-tools, è su GitHub su github.com/matteocisilino/ispconfig-fast-tools.

La rotazione delle credenziali database è un’abitudine, non un lavoro di pulizia

La rotazione delle credenziali database dopo una violazione confermata è semplicemente una risposta agli incidenti competente. La maggior parte degli amministratori lo farebbe senza bisogno di sentirlo due volte. L’abitudine più difficile è farlo dopo una violazione solo sospettata, prima che ci sia una prova. È l’unica versione del piano che limita davvero il danno, mentre è ancora limitabile. Uno script che esegue le fasi giuste per il ruolo di un server, fa prima i propri backup, e mi permette di simulare l’intera esecuzione prima di toccare qualcosa di reale. È quello che rende l’abitudine praticabile un martedì sera, invece che teorica in un articolo di blog.

ISPConfig, MySQL, PHP, Dovecot, Pure-FTPd, Postfix e gli altri nomi citati sono marchi dei rispettivi proprietari. Sono usati solo per identificare i prodotti.

Commenti

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Avviso sui cookie di WordPress da parte di Real Cookie Banner