Il vostro mirror RPM, e costruire la correzione prima che la distro la rilasci
Come gestire un mirror RPM locale coerente e, quando una correzione è uscita upstream ma non è ancora pacchettizzata, costruirla in modo pulito perché il pacchetto ufficiale prenda poi il suo posto.

Quando viene pubblicata una vulnerabilità seria, due cose decidono per quanto tempo i vostri server restano esposti: quanto in fretta riuscite a scaricare i pacchetti, e se il pacchetto corretto esiste già. Un mirror locale risolve la prima. La capacità di costruire da soli un pacchetto pulito, dalla specifica stessa del maintainer, risolve la seconda. Ecco come facciamo entrambe le cose su Enterprise Linux, e come farlo senza lasciare in giro pacchetti fatti in casa dopo l'arrivo di quelli ufficiali.
Perché gestire un proprio mirror
I mirror pubblici sono gestiti da persone e organizzazioni generose, e in un giorno normale sono veloci. Il giorno in cui arriva una correzione critica, ogni server del mondo chiede gli stessi pacchetti nello stesso momento. Un mirror locale dentro la vostra rete trasforma tutto in un'operazione di copia locale. Vi permette anche di aggiornare server deliberatamente isolati da internet, come i sistemi di backup e di gestione, senza aprirli.
C'è un beneficio più silenzioso: un mirror che conserva lo storico completo dei pacchetti vi permette di ricostruire un server a uno stato noto, o di riportare indietro un pacchetto, dalla vostra copia.
Fare mirroring senza mai servire un repository sincronizzato a metà
Il mirror ingenuo è un rsync o un reposync direttamente nella directory che il vostro web server pubblica. Se un client esegue dnf mentre la sincronizzazione è a metà, può vedere nuovi metadati che fanno riferimento a pacchetti non ancora arrivati, o vecchi metadati che puntano a pacchetti appena eliminati. Il risultato sono errori confusi esattamente nel momento sbagliato.
Sincronizzate invece in due fasi:
- Prima i pacchetti. Scaricate i pacchetti nella directory pubblicata. I vecchi metadati descrivono ancora un insieme coerente, perché nulla di ciò a cui fanno riferimento è stato ancora rimosso.
dnf reposync --repoid=os-baseos --arch=x86_64 --arch=noarch \
--delete --norepopath -p /srv/repo/os/baseos
- Poi i metadati, scambiati in un colpo solo. Scaricate la
repodata/upstream in una directory affiancata (ogni file a cuirepomd.xmlfa riferimento), verificatela, poi sostituite i metadati pubblicati con una singola rinomina. I client vedono il vecchio repository o il nuovo, mai un misto.
mv /srv/repo/os/baseos/repodata /srv/repo/os/baseos/repodata.old
mv /srv/repo/os/baseos/repodata.new /srv/repo/os/baseos/repodata
Usare i metadati upstream, invece di rigenerare i vostri con createrepo_c, mantiene il repository esattamente come l'ha costruito chi lo pubblica.
Date a ogni job di sincronizzazione un lock perché due esecuzioni non si sovrappongano mai, scrivete un piccolo file di stato con esito e orario, e avvisate qualcuno quando un job fallisce. Un mirror che ha smesso di sincronizzarsi in silenzio il mese scorso è peggio di nessun mirror, perché tutti si fidano di lui.
I client usano poi un semplice file di repository che punta al vostro mirror:
[local-baseos]
name=Local mirror: BaseOS
baseurl=https://mirror.example.internal/os/baseos/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
Quando la correzione esiste ma il pacchetto no
A volte il progetto upstream rilascia una versione corretta e il maintainer della distribuzione o del repository non l'ha ancora pacchettizzata. Spesso quel divario è di ore; a volte di giorni.
La regola che seguiamo: costruite la release upstream dalla pacchettizzazione stessa del maintainer, non cambiate nient'altro, e assicuratevi che il pacchetto ufficiale sostituisca il vostro automaticamente.
Costruite in una camera bianca
Usate un container fresco della stessa release di distribuzione dei server di destinazione, così l'ambiente di build è noto e usa e getta:
podman run --rm -it -v ./build:/build:Z oraclelinux:<release> bash
dnf install -y rpm-build rpmdevtools dnf-plugins-core
rpmdev-setuptree
Partite dall'ultimo pacchetto sorgente (SRPM) del maintainer per il ramo che usate, installatelo, e installate le sue dipendenze di build:
rpm -ivh php-<current>.src.rpm
dnf builddep -y ~/rpmbuild/SPECS/php.spec
Cambiate solo la versione, e verificate il sorgente
Scaricate il tarball upstream corretto dal sito ufficiale del progetto e verificatelo con il checksum che il progetto pubblica.
sha256sum php-<fixed>.tar.xz
Nel file spec, aggiornate Version alla release corretta e sostituite il sorgente. Lasciate patch, opzioni di configure ed elenchi di file come li ha scritti il maintainer. Se una patch del maintainer non si applica più alla nuova release, fermatevi e capite il perché prima di andare avanti.
Scegliete una release che si faccia da parte
È il passo che la gente dimentica. Il vostro pacchetto deve ordinarsi più in basso dell'eventuale pacchetto ufficiale del maintainer della stessa versione, così che un normale dnf upgrade sostituisca il vostro. Una release che inizia con 0. lo fa in modo affidabile:
Release: 0.1.local%{?dist}
Verificatelo prima di costruire qualunque cosa, con lo stesso confronto che usa rpm:
rpmdev-vercmp 0:X.Y.Z-0.1.local.elN 0:X.Y.Z-1.elN.maint
La release ufficiale deve risultare più nuova. Se non lo è, cambiate la vostra stringa di release finché non lo è.
Costruite, testate, conservate le evidenze
rpmbuild -ba ~/rpmbuild/SPECS/php.spec
Conservate i pacchetti costruiti con i loro checksum e una nota del checksum del tarball sorgente, così chiunque possa dire in seguito esattamente cosa è stato installato e da dove veniva.
Pubblicate le vostre build in un repository separato sul vostro mirror, non mescolate nella copia del repository del vendor. Quando il pacchetto ufficiale arriva nel repository mirrorato, il successivo aggiornamento normale sostituisce il vostro, e il vostro repository separato può essere svuotato.
Il merito a chi spetta
Niente di tutto questo sostituisce le persone che mantengono i pacchetti. Maintainer di repository come Remi Collet, dai cui repository PHP dipende gran parte del mondo Enterprise Linux, rilasciano spesso le correzioni con notevole rapidità. Costruire dalla loro specifica è un modo per coprire le ultime ore, non un sostituto del loro lavoro. Durante le correzioni di PHP2Shell abbiamo scritto di entrambi i lati: PHP2Shell: pacchetti PHP corretti e Rispetto per Remi.
Una checklist per la vostra piattaforma
- Da dove scaricano i pacchetti i vostri server, e cosa succede se quel posto è lento?
- I vostri server isolati possono essere aggiornati senza aprirli a internet?
- Un client potrebbe mai vedere un repository sincronizzato a metà sul vostro mirror?
- Qualcuno viene avvisato quando una sincronizzazione del mirror fallisce?
- Se doveste costruire un pacchetto stanotte, la vostra stringa di release lascia che quello ufficiale lo sostituisca?
Se volete aiuto per impostare un mirror o un processo di build d'emergenza, i nostri ingegneri sono lieti di condividere ciò che funziona.
Related
- /what-we-do/operations/package-builds-mirror/
- /what-we-do/operations/emergency-vulnerability-response/
- /what-we-do/data-web/php-upgrades-security-patching/
Pubblicato il 8 settembre 2026.
Tutte le note dal campo