Upgrade a Trixie via SSH senza restare chiuso fuori dal server

Upgrade a Trixie via SSH senza restare chiuso fuori dal server

Il major upgrade di un server remoto è l'unico intervento sistemistico in cui lo strumento di lavoro coincide con la cosa che puoi rompere: lavori dentro una sessione SSH mentre aggiorni, fra gli altri, OpenSSH, la libc su cui poggia, il kernel e l'init che li tiene in piedi. Debian 13 trixie porta il kernel 6.12, systemd 257 e OpenSSH 10.0, e il salto da bookworm resta uno dei più lisci dell'ecosistema, a patto di rispettare la fisica del contesto: sei collegato a una macchina che magari sta in un datacenter a mille chilometri, la tua sessione è appesa a una rete che non controlli, e ogni scelta sbagliata su un prompt può trasformare un upgrade da manuale in un pomeriggio passato nella console di emergenza del provider. Negli anni ho portato a termine decine di questi upgrade su VPS di clienti, e gli incidenti che ho visto non nascevano mai dai pacchetti: nascevano dalla sessione persa nel momento sbagliato, dal file di configurazione di sshd sovrascritto senza leggere, dal riavvio fatto prima delle verifiche. La guida completa all'aggiornamento da bookworm a trixie che ho pubblicato copre il progetto intero, requisiti e pianificazione compresi; questo pezzo è il suo complemento verticale e assume un solo punto di vista, quello della connessione: la sequenza esatta che ti tiene dentro il server dall'inizio alla fine, con le vie di fuga preparate prima di servirtene.

Cosa succede alla mia sessione SSH mentre aggiorno il sistema?

La risposta breve, che sorprende chi non l'ha mai fatto: quasi niente, se la prepari. Le release notes ufficiali di trixie sono esplicite su entrambi i lati della medaglia: chi è connesso via SSH "dovrebbe accorgersi di poco durante l'upgrade" e può continuare a lavorare, ma raccomandano di eseguire il processo dentro una console virtuale fornita da screen o tmux, che permette una riconnessione sicura, e di predisporre l'accesso attraverso un terminale remoto alternativo. Le connessioni SSH già stabilite sopravvivono al riavvio del demone: quando il pacchetto openssh-server viene aggiornato e sshd riparte, la tua sessione esistente resta viva, perché è gestita da un processo figlio che non muore col padre. Il rischio vero non è la sessione che cade per colpa dell'upgrade: è cosa succede al processo di upgrade se cade la sessione, ed è un rischio che si azzera con dieci secondi di preparazione.

Quando la tua shell muore, tutti i processi che ha lanciato ricevono un SIGHUP, e un apt full-upgrade ucciso a metà della configurazione dei pacchetti lascia dpkg in uno stato interrotto: recuperabile quasi sempre, con un dpkg --configure -a fatto a mente fredda, ma è un recupero che è molto meglio non dover fare mentre metà del sistema è alla versione vecchia e metà alla nuova. Da qui la regola numero uno, non negoziabile: l'upgrade parte solo dentro un multiplexer di terminale.

Fase 0: le vie di fuga si preparano quando non servono

Prima di toccare qualunque cosa, verifica di avere un secondo modo per entrare nella macchina. Sul VPS di un provider serio ce l'hai quasi sempre: la console di emergenza via pannello, l'accesso VNC alla macchina virtuale, o il rescue system avviabile. Il punto è che deve essere verificato adesso, non scoperto durante l'emergenza: apri il pannello, lancia la console, accertati che il login funzioni e che conosci la password di root o abbia un modo per resettarla. Se la console del provider richiede una password di root e tu usi solo chiavi SSH, questo è il momento di impostarne una robusta, perché la console non usa le tue chiavi. Secondo controllo: lo spazio. Le release notes chiedono margine sul filesystem che ospita /var, dove finiscono i pacchetti scaricati; un df -h /var con qualche gigabyte libero ti evita la classe più stupida di fallimento a metà. Terzo: i backup che le release notes stesse indicano, /etc, /var/lib/dpkg, /var/lib/apt/extended_states, più naturalmente i dati applicativi, che dovresti già proteggere con la strategia che dai per scontata finché non serve. Quarto, spesso dimenticato: da dove lanci l'upgrade. Una connessione domestica instabile o una rete in mobilità sono il posto sbagliato; se la tua rete è ballerina, la mossa intelligente è fare il primo salto su una macchina intermedia stabile, un altro server, e da lì aprire la sessione verso il bersaglio, così il tratto fragile della catena resta fuori dal percorso critico.

Ultimo gesto della fase zero, che costa due minuti e in emergenza vale oro: fotografa lo stato attuale della macchina e porta la copia fuori dalla macchina. La lista dei pacchetti installati (dpkg -l), la configurazione di rete (ip a e ip r), le porte in ascolto (ss -tlnp), l'elenco dei servizi abilitati (systemctl list-unit-files --state=enabled): quattro output di testo salvati in locale sul tuo portatile. Se dopo il riavvio qualcosa non risponde, il confronto fra lo stato atteso e quello reale trasforma un'ora di brancolamento in cinque minuti di diff, e lo puoi fare anche dalla console di emergenza, quando la rete della macchina è proprio la cosa che stai debuggando.

Fase 1: screen, e la sessione che sopravvive a te

Il multiplexer trasforma la tua più grande vulnerabilità, la sessione, in una cosa sacrificabile. Uso screen per abitudine ventennale, tmux va ugualmente bene:

apt install -y screen
screen -S upgrade
# da questo momento, tutto vive dentro la sessione "upgrade"

Se la connessione cade, il processo dentro screen continua come se niente fosse: ti riconnetti al server e riagganci con screen -r upgrade, ritrovando l'upgrade esattamente dove lo avevi lasciato, prompt interattivi compresi. Vale la pena provare il giro completo una volta, prima di cominciare: stacca volontariamente con Ctrl-A d, chiudi il terminale, riapri, riaggancia. Trenta secondi di esercizio che trasformano il momento di panico classico, "è caduta la linea durante il full-upgrade", in un non evento. Il manuale di GNU screen documenta il resto, ma per un upgrade bastano questi due gesti: creare con un nome, riagganciare per nome.

Questa disciplina della via di fuga preparata è la stessa che applico a ogni intervento su macchine di produzione, ed è il motivo per cui gli imprevisti restano aneddoti invece di diventare incidenti: nel mio profilo professionale trovi come imposto gli interventi di manutenzione straordinaria sui VPS che seguo per le PMI.

Fase 2: sorgenti, minimal upgrade, e perché due tempi

Dentro screen, la sequenza canonica delle release notes è in due tempi, e i due tempi non sono pedanteria: sono il modo in cui si evita che il resolver di apt prenda decisioni drastiche con il sistema a metà del guado. Prima si aggiornano le sorgenti a trixie, nel formato che già usi (se vuoi passare al formato deb822 moderno, fallo dopo l'upgrade, con calma: apt modernize-sources esiste apposta, e mescolare i due cambiamenti nello stesso intervento è cercarsi un problema in più). Poi:

apt update
apt upgrade --without-new-pkgs
apt full-upgrade

Il passaggio intermedio con --without-new-pkgs aggiorna ciò che è aggiornabile senza installare pacchetti nuovi né rimuoverne: riduce la taglia del salto successivo e lascia il sistema in uno stato coerente se qualcosa impone una pausa. Un raffinamento che uso sulle connessioni lente: apt -d full-upgrade prima del full-upgrade vero scarica tutti i pacchetti senza toccare nulla, così la fase critica dell'installazione parte con l'archivio già in locale e la finestra di vulnerabilità alla rete si accorcia di conseguenza. Il full-upgrade finale fa il lavoro grosso, ed è lì che arrivano i momenti delicati per la connessione. Il primo è il prompt sui file di configurazione modificati, e su uno in particolare non si va di fretta: sshd_config. Se hai personalizzato porta, autenticazione o restrizioni di accesso, la risposta giusta al prompt è quasi sempre conservare la tua versione (la N di default), e riportare a mano, dopo, le eventuali novità della versione nuova, che dpkg ti lascia accanto come sshd_config.dpkg-dist. Accettare la versione del maintainer su un server che accetta solo chiavi, con la porta cambiata e il root login disabilitato, significa riaprire configurazioni che avevi chiuso per buone ragioni.

Il secondo momento delicato sono i riavvii dei servizi che i pacchetti propongono durante la configurazione: qui il criterio è semplice, i servizi applicativi possono ripartire quando vogliono, ma per sshd vale una liturgia precisa che merita il suo paragrafo.

Fase 3: la liturgia di sshd, e il firewall che non deve tradirti

Ogni volta che la configurazione di sshd cambia, per mano tua o dell'upgrade, la sequenza di sicurezza è sempre la stessa, e va eseguita nell'ordine esatto. Primo: valida la sintassi con sshd -t, che ti dice subito se il file è malformato. Secondo: riavvia il demone. Terzo, il passo che distingue chi è già rimasto chiuso fuori da chi deve ancora provarlo: apri una nuova connessione SSH di prova senza chiudere quella che hai. La sessione esistente sopravvive a un sshd rotto, perché è già stabilita; è la prossima connessione a fallire. Finché non hai verificato che si entra, la vecchia sessione è la tua assicurazione sulla vita, e non si tocca:

sshd -t && systemctl restart ssh
# ora, DA UN ALTRO TERMINALE: ssh utente@server "echo ok"
# solo dopo l'ok, questa sessione si può chiudere

La regola d'oro dell'amministrazione remota: la connessione nuova si testa sempre mentre quella vecchia è ancora aperta. Vale per sshd, per il firewall, per le VPN. Chi la rispetta non resta mai chiuso fuori; chi non la rispetta impara a rispettarla, una sola volta e per sempre.

Lo stesso principio copre il firewall. L'upgrade porta versioni nuove di nftables e dei suoi ganci di avvio: se il tuo ruleset vive in /etc/nftables.conf con la policy di default a drop, verifica prima del riavvio che il file sia sintatticamente valido (nft -c -f /etc/nftables.conf) e che la porta di SSH sia ammessa da una regola che non dipende da include esterni fragili. Un ruleset che non si carica per un errore di sintassi può degradare in due direzioni opposte a seconda della configurazione, tutto aperto o tutto chiuso, e la seconda ti separa dalla macchina esattamente come un sshd rotto. Anche fail2ban merita un pensiero: dopo il riavvio riparte con la memoria vuota, ma se durante le tue prove di connessione sbagli password o chiave più volte di fila, puoi auto-bandirti nel momento meno opportuno; la whitelist del tuo IP di gestione (ignoreip) è una riga di configurazione che vale la pena avere da sempre.

Fase 4: il riavvio, e le verifiche che chiudono l'intervento

Il full-upgrade termina, ma l'intervento no: trixie ti ha installato un kernel nuovo, e le release notes non lasciano ambiguità, il riavvio è necessario. Prima di lanciarlo, tre controlli da dentro la sessione: dpkg --audit deve tacere (nessun pacchetto in stato incoerente), needrestart ti mostra cosa sta ancora girando su librerie vecchie, e la console di emergenza del provider deve essere ancora lì, aperta in un tab, pronta. Poi systemctl reboot, e il minuto più lungo del pomeriggio: quello in cui il ping non risponde ancora. Quando la macchina torna, il giro di verifica finale: si entra via SSH (dalla connessione nuova, ovviamente), uname -r conferma il kernel 6.12, systemctl --failed elenca le unità che non sono ripartite, e i servizi applicativi rispondono. A questo giro aggiungo sempre un controllo che il salto a trixie ha reso obbligatorio: findmnt /tmp, perché il nuovo default di /tmp in RAM si attiva proprio a questo riavvio e ha un modo tutto suo di farsi notare giorni dopo, come ho raccontato nel pezzo sul backup notturno che fallisce dopo l'upgrade a Debian 13.

Se qualcosa invece va storto, la scala di reazione è quella della checklist di emergenza per VPS unmanaged: prima la console del provider, poi il rescue system, e la calma di chi sa che un sistema Debian interrotto a metà upgrade si riprende quasi sempre con dpkg --configure -a e pazienza, senza reinstallare niente. Ma il senso di tutta la sequenza che hai letto è proprio non arrivarci: ogni fase esiste perché un giorno, da qualche parte, qualcuno ha saltato quel passo ed è rimasto fuori. L'upgrade remoto ben fatto è un intervento noioso, e la noia, in questo mestiere, è il risultato che si ottiene con la preparazione. Se hai un parco di macchine ancora su bookworm e preferisci che il giro lo faccia, o lo supervisioni, qualcuno che questa liturgia la esegue da anni, finestre concordate, rollback pianificato e verifiche applicative comprese, contattami per una consulenza: un upgrade pianificato costa una frazione di un recovery improvvisato, e si dorme meglio entrambi.

Ultima modifica: