Migrare le sorgenti APT al formato deb822 .sources

Migrare le sorgenti APT al formato deb822 .sources

Se hai portato un server a Debian 13, l'hai già vista: da trixie, ogni apt update su un sistema con le sorgenti in formato storico stampa l'avviso "Notice: Some sources can be modernized. Run 'apt modernize-sources' to do so". Puoi silenziarlo, e più avanti ti mostro anche come, ma l'avviso dice una cosa vera: il formato one-line di /etc/apt/sources.list, quello che scriviamo a mano da venticinque anni, è ufficialmente deprecato, e il suo successore, il formato deb822 dei file .sources, è già il default delle installazioni nuove di trixie, che arrivano con /etc/apt/sources.list.d/debian.sources al posto del vecchio file. La rimozione del formato storico non avverrà prima del 2029, quindi nessuno ti corre dietro; ma ho migrato tutte le macchine che gestisco, le mie e quelle dei clienti, e in questo articolo ti spiego perché conviene farlo adesso, con la testa, invece che fra tre anni, di fretta. Metto i due formati uno accanto all'altro, ti mostro cosa il nuovo sa fare e il vecchio no, dove sta il guadagno di sicurezza vero (una parola: Signed-By), e la procedura di migrazione completa con i due punti esatti in cui può andare storta.

TL;DR

  • Migrazione automatica: apt modernize-sources converte sources.list e i .list in file .sources, aggiunge Signed-By dove riesce a determinarlo e salva gli originali come .bak.
  • Verifica dopo: controlla che in /etc/apt/sources.list.d/ non convivano un .list residuo e un .sources per lo stesso repo: apt segnala "Conflicting values" e si rifiuta.
  • Terze parti: chiave del repo in /etc/apt/keyrings/, riga Signed-By: nella stanza; niente più chiavi fidate globalmente.
  • Silenziare l'avviso (se proprio non vuoi migrare ora): APT::Get::Update::SourceListWarnings "false"; in un file sotto /etc/apt/apt.conf.d/.
  • Bookworm: il comando non esiste su Debian 12; lì la conversione si fa a mano, o si aspetta l'upgrade.

Cosa cambia davvero fra il formato one-line e deb822?

La risposta sintetica: cambia la struttura, da righe posizionali a stanze con campi espliciti, e cambia il modello di fiducia, perché la chiave di firma di ogni repository diventa un campo di prima classe (Signed-By) legato a quel solo repository, invece di una chiave fidata globalmente. Tutto il resto, mirror, suite, componenti, resta concettualmente identico: cambia come lo scrivi, non cosa significa. Il modo più rapido per toccare con mano la differenza è guardare lo stesso archivio scritto nei due formati. Questo è il classico sources.list di un server trixie con la suite di sicurezza:

deb https://deb.debian.org/debian trixie main contrib non-free-firmware
deb https://deb.debian.org/debian trixie-updates main contrib non-free-firmware
deb https://deb.debian.org/debian-security trixie-security main contrib non-free-firmware

E questa è la stessa configurazione in formato deb822, in /etc/apt/sources.list.d/debian.sources:

Types: deb
URIs: https://deb.debian.org/debian
Suites: trixie trixie-updates
Components: main contrib non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

Types: deb
URIs: https://deb.debian.org/debian-security
Suites: trixie-security
Components: main contrib non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

Tre righe dense contro due stanze parlanti: a prima vista sembra solo più verboso. La sostanza sta nelle proprietà che il confronto diretto mette in fila:

ProprietàOne-line (.list)Deb822 (.sources)
Suite multiple per voceno, una riga per suitesì, Suites: trixie trixie-updates in una stanza
Chiave di firma per reposolo con [signed-by=...] inline, poco usatocampo Signed-By: di prima classe
Disattivare temporaneamente un repocommenti a mano su ogni rigaEnabled: no, una riga, reversibile
Opzioni leggibilidentro parentesi quadre, sintassi cripticaun campo per riga, autoesplicativo
Un file per repositoryconvenzione, non strutturastruttura naturale in sources.list.d/
Parsing per automazioneregex artigianaliformato a campi, lo stesso di apt show

La voce che vale da sola la migrazione è la seconda. Nel modello storico, le chiavi GPG dei repository finivano in un portachiavi fidato globalmente: prima con il famigerato apt-key add, deprecato da anni proprio per questo, poi con i file buttati in /etc/apt/trusted.gpg.d/, che è la stessa cosa con un percorso diverso. Fidato globalmente significa che la chiave del repo di un piccolo vendor qualunque può firmare, agli occhi di apt, anche i pacchetti dell'archivio Debian: se quel vendor viene compromesso, o è malintenzionato, il suo repository può servirti un openssl o una libc "aggiornati" e apt li accetterà. Con Signed-By il legame diventa esplicito e puntuale: quella chiave vale per quel repository e per nessun altro. È la differenza fra dare a ogni fornitore le chiavi di casa e dare a ciascuno la chiave della sola stanza che gli compete, e su un server dove nel tempo si accumulano i repo di Docker, di un pannello, di un vendor di monitoring, non è una sottigliezza da puristi: è superficie d'attacco che si chiude.

Il guadagno vero del deb822 non è la leggibilità: è che il modello di fiducia smette di essere globale. Ogni repository di terze parti che aggiungi con la sua chiave in Signed-By è un fornitore che non può più parlare a nome di Debian.

Il formato è documentato per esteso nella pagina SourcesList della wiki Debian e nella manpage ufficiale sources.list(5); non è nemmeno una novità in senso stretto, visto che apt lo supporta da oltre un decennio. La novità di trixie è che è diventato il default delle installazioni nuove e la destinazione raccomandata per tutte le altre, con un comando dedicato che fa la conversione al posto tuo.

C'è anche un guadagno organizzativo che si apprezza col tempo: la struttura naturale a un file per repository dentro sources.list.d/. Nel mondo one-line era una convenzione che ogni vendor interpretava a modo suo; nel mondo deb822 è la forma stessa del sistema, e un ls della directory diventa l'inventario leggibile delle fonti software della macchina, con nomi parlanti e un diff pulito a ogni modifica. Su un server che vive anni e passa di mano fra fornitori, questa leggibilità d'inventario vale più di quanto sembri il giorno della migrazione.

Perché farlo adesso, se il vecchio formato vive fino al 2029?

Perché la deadline lontana è l'argomento per pianificare, non per rimandare. La rimozione del formato storico non arriverà prima del 2029, e Debian 14 lo supporterà ancora: nessuna urgenza tecnica, ed è esattamente il motivo per cui il momento giusto è ora. Le migrazioni fatte con anni di margine si fanno con la simulazione, la verifica e il rollback pronto; quelle fatte a ridosso di una rimozione si fanno di corsa, tutte insieme, nel fine settimana sbagliato. C'è poi un costo silenzioso del rimandare: ogni repository di terze parti che aggiungi da qui ad allora nel formato vecchio è lavoro di conversione futura che stai accumulando, e ogni chiave che nel frattempo finisce in trusted.gpg.d è fiducia globale concessa che prima o poi dovrai revocare e rinegoziare. Convertire oggi significa che tutto ciò che aggiungi da domani nasce già nella forma giusta, e l'avviso a ogni apt update smette di addestrarti a ignorare gli avvisi, che è forse il danno peggiore che un nag ricorrente possa fare a un sysadmin.

La migrazione automatica: apt modernize-sources

Su qualunque sistema con apt 3.0, cioè da trixie in avanti (su bookworm il comando non esiste: lì o converti a mano o, più sensatamente, aspetti di fare l'upgrade), la conversione è un comando solo:

apt modernize-sources

Il comando dichiara esattamente cosa farà prima di farlo: sostituisce i file .list con gli equivalenti .sources, aggiunge i valori Signed-By dove riesce a determinarli automaticamente, e salva gli originali come file .bak. Rispondendo N al prompt ottieni una simulazione, il che lo rende uno di quei rari comandi di migrazione che puoi guardare in faccia prima di fidarti. A conversione fatta, il vecchio /etc/apt/sources.list non esiste più, resta il suo .bak accanto, e il tuo archivio principale vive in /etc/apt/sources.list.d/debian.sources. Il rollback, se mai servisse, è il ripristino dei .bak: niente di irreversibile.

I punti dove la migrazione può andare storta, nella mia esperienza su un numero ormai a due cifre di macchine convertite, sono due, ed entrambi si controllano in un minuto. Il primo: le opzioni esotiche fra parentesi quadre. Il comando trasferisce signed-by e trusted; se in qualche riga avevi opzioni più rare, arch=, pin particolari, quelle vanno riportate a mano nella stanza corrispondente, e il .bak è lì apposta per il confronto. Il secondo, più insidioso: i duplicati residui. Se dopo la conversione in sources.list.d/ convivono un .list sopravvissuto (magari installato da un pacchetto di terze parti nel frattempo) e un .sources che puntano allo stesso repository con valori diversi, apt non sceglie: si ferma con un errore di "Conflicting values" e ti costringe a decidere. La verifica post-migrazione è quindi sempre la stessa coppia:

ls -la /etc/apt/sources.list.d/
apt update

Un listing senza doppioni e un apt update che scorre pulito, senza avvisi e senza errori, chiudono la pratica. Una nota per chi lavora su VPS: molte immagini preconfigurate dei provider arrivano con file .list propri, tipicamente il mirror interno del datacenter, e quei file partecipano alla conversione come tutto il resto; dopo la migrazione vale un'occhiata in più per confermare che il mirror del provider sia ancora lì, nella sua stanza, e che la macchina non sia silenziosamente passata al mirror pubblico con latenze diverse. Noterai anche un effetto collaterale gradevole: l'avviso di modernizzazione sparisce dai log, il che per chi monitora l'output di apt update con strumenti automatici significa log tornati silenziosi come devono essere. Se invece hai deciso di rimandare la migrazione e l'avviso ti inquina i log nel frattempo, la direttiva APT::Get::Update::SourceListWarnings "false"; in un file sotto /etc/apt/apt.conf.d/ lo spegne: è la scelta che sconsiglio, ma documentarla è onesto.

Questo genere di manutenzione preventiva, fatta quando nulla brucia, è ciò che distingue i parchi macchine che invecchiano bene: nel mio profilo professionale trovi come lavoro sui VPS in produzione delle PMI, dove la modernizzazione delle configurazioni viaggia sempre insieme agli aggiornamenti pianificati.

Il caso serio: i repository di terze parti

Sull'archivio Debian la migrazione è cosmetica, perché la fiducia era già ben riposta. È sui repository di terze parti che il formato nuovo paga davvero, e conviene approfittare della migrazione per rimettere in ordine anche loro. Il pattern corretto, identico per qualunque vendor, è: la chiave GPG del repo scaricata in /etc/apt/keyrings/ (o /usr/share/keyrings/ per quelle installate da pacchetti), mai più in trusted.gpg.d, e una stanza .sources che la referenzia esplicitamente. Per un ipotetico repository di un vendor di monitoring:

Types: deb
URIs: https://apt.example-vendor.com/debian
Suites: trixie
Components: main
Architectures: amd64
Signed-By: /etc/apt/keyrings/example-vendor.gpg

Mentre lo fai, il censimento viene gratis, ed è un piccolo audit di sicurezza che raccomando di non saltare: per ogni file in sources.list.d/ chiediti se quel repository serve ancora. Nei subentri trovo regolarmente repo di pannelli disinstallati da anni, di versioni PHP di terze parti abbandonate, di software provato una volta e dimenticato: ognuno è una chiave fidata e una fonte di pacchetti che non guardi mai. Enabled: no è il purgatorio perfetto per quelli su cui hai dubbi: il repo resta documentato, la fiducia è sospesa, e riattivarlo è una riga. Un controllo finale con apt policy ti mostra da quali fonti apt sta davvero attingendo, con quali priorità, ed è il modo più rapido per accorgerti di sovrapposizioni strane fra repository che offrono gli stessi pacchetti.

C'è infine l'angolo dell'automazione, che per chi gestisce più di una macchina è il motivo forse più concreto di tutti. Il formato a campi è fatto per essere scritto e verificato dalle macchine: un template Ansible che deposita un file .sources completo di Signed-By è dichiarativo, idempotente e leggibile nel diff di un commit, tutto ciò che le regex sul vecchio sources.list non sono mai state. Sui parchi che seguo, la migrazione l'ho fatta proprio così: apt modernize-sources orchestrato sulle macchine, verifica dei duplicati, e da lì in avanti i file .sources sono gestiti come configurazione versionata, non più modificati a mano sul server.

Se il tuo VPS è appena passato a trixie, questa migrazione è il naturale completamento del salto: l'ho inserita stabilmente nella coda dei lavori post-upgrade, dopo le verifiche di cui ho scritto nella sequenza per aggiornare a Debian 13 via SSH senza restare chiusi fuori, e prima del ritorno alla normale amministrazione. Se invece sei ancora su bookworm, la voce va semplicemente a calendario insieme all'upgrade, seguendo la guida completa da bookworm a trixie: fare le due cose in un unico intervento pianificato è più efficiente che inseguirle separatamente. E se la fotografia onesta è che di file .list, chiavi in trusted.gpg.d e repository dimenticati il tuo parco macchine è pieno, e non c'è il tempo interno per metterci mano, contattami per una consulenza: il riordino delle sorgenti e delle chiavi di fiducia è un intervento da mezza giornata a macchina che ripaga a ogni aggiornamento futuro, e che di solito fa emergere anche un paio di sorprese che era meglio scoprire così.

Ultima modifica: