Come evitare di eseguire comandi sul server sbagliato

Rendi impossibile confondere la produzione: imposta un prompt rosso in PS1 su ogni server di produzione, e colora anche la barra di stato di tmux e il terminale. Poi crea abitudini che intercettano lo sbaglio: esegui prima un dry run, elenca un glob prima di cancellarlo, scrivi "${DIR:?}" negli script e tieni attivo il bracketed paste. Riducono gli errori. Niente qui li rende impossibili, quindi i backup contano comunque.

Aggiornata il . Prompt, protezioni per rm, dry run, colori della barra di stato di tmux e bracketed paste sono stati provati su Debian 13 in un container usa e getta (bash 5.2, GNU coreutils 9.7, tmux 3.5), via SSH da macOS.

Un prompt rosso in produzione

La maggior parte degli errori di server sbagliato nasce dal fatto che due terminali sembrano uguali. Il prompt è ciò che leggi un attimo prima di premere Invio, quindi cambialo lì. Aggiungi questo in fondo a ~/.bashrc sul server. Deve andare in fondo, perché il .bashrc della distribuzione imposta PS1 prima e lo sovrascriverebbe:

PS1='\[\e[1;37;41m\] PRODUCTION \[\e[0m\] \u@\h:\w\$ '

Mostra PRODUCTION bianco su rosso, poi il solito utente, host e cartella. \[ e \] dicono a bash che i codici colore non occupano spazio, così i comandi lunghi vanno a capo correttamente.

Aggiungi la stessa riga a /root/.bashrc: nella nostra prova sudo -i mostrava l'etichetta rossa solo perché c'era anche in quel file. Per lo staging usa il giallo con \e[1;30;43m. Funziona solo con bash interattivo, quindi le altre shell richiedono una loro impostazione.

Terminale su iPhone con l'etichetta Production nel titolo, che mostra una finestra con la domanda Run this on production? prima di una cancellazione ricorsiva forzata, con i pulsanti Cancel e Run itTerminale su iPhone con l'etichetta Production nel titolo, che mostra una finestra con la domanda Run this on production? prima di una cancellazione ricorsiva forzata, con i pulsanti Cancel e Run it

Colora la barra di tmux e il terminale

Se usi tmux sul server, colora la sua barra di stato, in ~/.tmux.conf lì:

set -g status-style bg=red,fg=white,bold
set -g status-left " PRODUCTION "

Controlla che sia stato caricato con tmux show -g status-style.

Sul tuo computer, la maggior parte delle app di terminale può aprire un host in un profilo separato. Dai alla produzione una finestra con lo sfondo rosso scuro. Puoi anche far impostare il colore alla tua configurazione SSH, nei terminali che supportano la sequenza OSC 11:

Host prod-*
    PermitLocalCommand yes
    LocalCommand printf '\033]11;#400000\007'

Il colore non torna da solo com'era quando esci, e il supporto varia, quindi provalo prima nel tuo terminale.

Con molti server, nomi chiari e gruppi aiutano quanto i colori: vedi come gestire molti server SSH.

Cancellare i file in sicurezza

rm di GNU rifiuta già il caso peggiore:

$ rm -rf /
rm: it is dangerous to operate recursively on '/'
rm: use --no-preserve-root to override this failsafe

Protegge solo il / letterale. In rm -rf /* la shell espande prima l'asterisco, quindi rm riceve /bin, /etc e il resto, e il controllo non si applica. Uno spazio di troppo in rm -rf /var/app /* lo fa per sbaglio. Queste abitudini aiutano di più:

  • Guarda prima di cancellare. Metti echo davanti per vedere in cosa si espande un glob: echo rm -rf /tmp/app/*. Poi togli l'echo.
  • Unisci con &&, non con ;. Con cd /var/app/tmp && rm -rf ./*, un cd fallito si ferma lì. Con ; la cancellazione parte in qualunque cartella ti trovi.
  • Proteggi le variabili negli script. rm -rf "${DIR:?}/" si ferma con un errore quando DIR è vuota, mentre un semplice "$DIR/" diventerebbe /. Anche set -u all'inizio di uno script si ferma sulle variabili non impostate.
  • Prima sposta, poi cancella. mv in una cartella di parcheggio si può annullare. rm no.
  • Usa rm -I. Chiede una volta prima di rimuovere più di tre file o di rimuovere in modo ricorsivo. Non rispondere nulla non rimuove nulla, come nella nostra prova.
  • Usa --preserve-root=all. Rifiuta anche una cartella su un filesystem diverso da quello del genitore, quindi rifiuterebbe un disco montato: rm: skipping '/dev/shm', since it's on a different device.

Gli ultimi due possono andare in un alias sul server, alias rm='rm -I --preserve-root=all'. Gli alias valgono solo per le shell interattive, non per gli script né per sudo rm, e questi flag esistono solo in GNU.

Prima un dry run

ComandoAnteprima
rsyncrsync -an --delete --itemize-changes src/ dst/
findfind . -name '*.tmp' -print prima, poi sostituisci -print con -delete
git cleangit clean -n
apt-getapt-get -s remove package

Con SQL, esegui prima BEGIN;, poi l'istruzione, controlla il numero di righe e chiudi con COMMIT; o ROLLBACK;. Questo non copre le istruzioni che il database conferma da solo. MySQL lo fa con le modifiche alle tabelle, per esempio.

Incollare più righe

In un terminale un'interruzione di riga nel testo incollato agisce come Invio, quindi un incolla può eseguire comandi prima che tu li legga. Il bracketed paste risolve il problema. Il terminale marca il testo incollato e la shell lo inserisce senza eseguire nulla. Abbiamo incollato due righe echo in bash tramite tmux:

  • Con l'opzione attiva, entrambe le righe sono rimaste al prompt e non è stato eseguito nulla fino a Invio.
  • Con l'opzione disattivata, la prima riga è stata eseguita appena incollata.

Nelle versioni attuali di bash è attivo per impostazione predefinita. Controlla con questo comando in una shell interattiva:

bind -v | grep bracketed-paste

Se dice off, aggiungi set enable-bracketed-paste on a ~/.inputrc. Aiuta solo dove il programma lo richiede. Incollare in un programma che non lo fa, o in una vecchia shell, esegue comunque riga per riga.

Cosa non possono fare

Il colore del prompt aiuta solo se lo guardi. Non protegge uno script, un job cron o un comando eseguito con ssh server 'command', che non mostra mai un prompt. Gli alias si possono aggirare e niente di tutto questo ferma un errore negli argomenti di un comando che volevi davvero eseguire.

Quindi mantieni le protezioni più grandi: backup collaudati, account e chiavi separati per la produzione e il minimo sudo che serve a ciascuno. Vedi sudo via SSH per regole mirate.

Domande

Come rendo rosso il prompt di bash su un server di produzione?

Imposta PS1 con un codice colore a sfondo rosso in fondo a ~/.bashrc su quel server, e in /root/.bashrc per sudo -i. Va in fondo, così il PS1 della distribuzione non lo sovrascrive.

rm -rf / funziona ancora su Linux?

rm di GNU rifiuta la / letterale, a meno di aggiungere --no-preserve-root. Non protegge rm -rf /*, perché la shell espande prima l'asterisco in tutte le cartelle principali.

Come vedo cosa cancellerà un comando prima di eseguirlo?

Metti echo davanti per vedere in cosa si espande un glob, oppure usa l'opzione di prova: rsync -n, git clean -n, o find con -print prima di -delete.

Fonti

Altro in Mettere in sicurezza un server

Tutte le guide