Перейти до вмісту
EuroVPSEuroVPS

Власне дзеркало RPM, і збірка виправлення до того, як його випустить дистрибутив

Як тримати консистентне локальне дзеркало RPM і, коли виправлення вже є upstream, але ще не в пакеті, зібрати його чисто, щоб офіційний пакет згодом його замінив.

Автор EuroVPS Engineering

5 хв читання
Власне дзеркало RPM, і збірка виправлення до того, як його випустить дистрибутив

Коли публікується серйозна вразливість, дві речі вирішують, скільки часу ваші сервери залишаться вразливими: як швидко ви можете отримати пакети і чи існує вже виправлений пакет. Локальне дзеркало вирішує перше. Здатність самостійно зібрати чистий пакет із власної специфікації мейнтейнера вирішує друге. Ось як ми робимо і те, й інше на Enterprise Linux, і як робити це так, щоб саморобні пакети не залишалися валятися після того, як прийдуть офіційні.

Навіщо взагалі тримати власне дзеркало

Публічні дзеркала підтримують щедрі люди та організації, і у звичайний день вони швидкі. У день, коли виходить критичне виправлення, кожен сервер у світі одночасно просить ті самі пакети. Локальне дзеркало всередині вашої власної мережі перетворює це на локальну операцію копіювання. Воно також дозволяє оновлювати сервери, свідомо відрізані від інтернету, такі як системи резервного копіювання та керування, не відкриваючи їх.

Є і тихіша перевага: дзеркало, що зберігає повну історію пакетів, дозволяє перебудувати сервер до відомого стану або відкотити пакет із вашої власної копії.

Дзеркалюйте так, щоб ніколи не віддавати напівсинхронізований репозиторій

Наївне дзеркало є rsync або reposync просто в каталог, який публікує ваш вебсервер. Якщо клієнт запускає dnf, коли синхронізація на півдорозі, він може побачити нові метадані, що посилаються на пакети, які ще не прийшли, або старі метадані, що вказують на пакети, які щойно видалили. Результат: заплутані помилки саме в найгірший момент.

Натомість синхронізуйте у дві фази:

  • Спершу пакети. Завантажте пакети в опублікований каталог. Старі метадані досі описують консистентний набір, бо нічого з того, на що вони посилаються, ще не видалено.
dnf reposync --repoid=os-baseos --arch=x86_64 --arch=noarch \
    --delete --norepopath -p /srv/repo/os/baseos
  • Потім метадані, замінені одним рухом. Завантажте upstream repodata/ у сусідній каталог (кожен файл, на який посилається repomd.xml), перевірте його, потім замініть опубліковані метадані одним перейменуванням. Клієнти бачать або старий репозиторій, або новий, ніколи суміш.
mv /srv/repo/os/baseos/repodata /srv/repo/os/baseos/repodata.old
mv /srv/repo/os/baseos/repodata.new /srv/repo/os/baseos/repodata

Використання upstream метаданих замість генерування власних за допомогою createrepo_c зберігає репозиторій точно таким, яким його зібрав видавець.

Дайте кожному завданню синхронізації lock, щоб два запуски ніколи не перетиналися, записуйте невеликий файл стану з результатом і часом, і сповіщайте когось, коли завдання падає. Дзеркало, яке мовчки перестало синхронізуватися минулого місяця, гірше за відсутність дзеркала, бо йому всі довіряють.

Клієнти тоді використовують простий файл репозиторію, що вказує на ваше дзеркало:

[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

Коли виправлення існує, а пакета немає

Іноді upstream проєкт випускає виправлений реліз, а мейнтейнер дистрибутива чи репозиторію ще не запакував його. Часто цей розрив становить години; іноді дні.

Правило, якого ми дотримуємося: збирайте upstream реліз із власного пакування мейнтейнера, не змінюйте нічого іншого і переконайтеся, що офіційний пакет замінить ваш автоматично.

Збирайте в чистій кімнаті

Використовуйте свіжий контейнер того самого випуску дистрибутива, що й цільові сервери, щоб середовище збірки було відомим і одноразовим:

podman run --rm -it -v ./build:/build:Z oraclelinux:<release> bash
dnf install -y rpm-build rpmdevtools dnf-plugins-core
rpmdev-setuptree

Починайте з останнього пакета вихідних кодів мейнтейнера (SRPM) для гілки, яку ви використовуєте, встановіть його і встановіть його залежності збірки:

rpm -ivh php-<current>.src.rpm
dnf builddep -y ~/rpmbuild/SPECS/php.spec

Змініть лише версію і перевірте джерело

Завантажте виправлений upstream tarball з офіційного сайту проєкту і перевірте його за контрольною сумою, яку публікує проєкт.

sha256sum php-<fixed>.tar.xz

У spec-файлі оновіть Version до виправленого релізу і замініть джерело. Залиште патчі, опції configure і списки файлів такими, як написав мейнтейнер. Якщо патч мейнтейнера більше не накладається на новий реліз, зупиніться і зрозумійте чому, перш ніж іти далі.

Оберіть release, який поступиться місцем

Це крок, про який забувають. Ваш пакет має сортуватися нижче за майбутній офіційний пакет мейнтейнера тієї самої версії, щоб звичайний dnf upgrade замінив ваш. Release, що починається з 0., робить це надійно:

Release: 0.1.local%{?dist}

Перевірте це, перш ніж щось збирати, тим самим порівнянням, яке використовує rpm:

rpmdev-vercmp 0:X.Y.Z-0.1.local.elN 0:X.Y.Z-1.elN.maint

Офіційний release має виявитися новішим. Якщо ні, змінюйте свій рядок release, доки не виявиться.

Зберіть, протестуйте, збережіть докази

rpmbuild -ba ~/rpmbuild/SPECS/php.spec

Зберігайте зібрані пакети з їхніми контрольними сумами і позначкою контрольної суми вихідного tarball, щоб будь-хто пізніше міг точно сказати, що було встановлено і звідки воно взялося.

Публікуйте свої збірки в окремому репозиторії на вашому дзеркалі, не змішуючи з копією репозиторію вендора. Коли офіційний пакет з’являється в дзеркальному репозиторії, наступне звичайне оновлення замінює ваш, а ваш окремий репозиторій можна спорожнити.

Віддамо належне

Ніщо з цього не замінює людей, які підтримують пакети. Мейнтейнери репозиторіїв, такі як Remi Collet, на чиї репозиторії PHP покладається значна частина світу Enterprise Linux, часто випускають виправлення надзвичайно швидко. Збірка з їхньої специфікації є способом покрити останні кілька годин, а не заміною їхньої роботи. Під час виправлень PHP2Shell ми писали про обидві сторони цього: PHP2Shell: виправлені пакети PHP і Шана Remi.

Контрольний список для вашої власної платформи

  • Звідки ваші сервери отримують пакети, і що станеться, якщо це місце повільне?
  • Чи можна оновлювати ваші ізольовані сервери, не відкриваючи їх в інтернет?
  • Чи може клієнт колись побачити напівсинхронізований репозиторій на вашому дзеркалі?
  • Чи повідомляють когось, коли синхронізація дзеркала падає?
  • Якби вам довелося зібрати пакет сьогодні ввечері, чи дозволяє ваш рядок release офіційному пакету його замінити?

Якщо вам потрібна допомога з налаштуванням дзеркала або процесу екстреної збірки, наші інженери радо поділяться тим, що працює. Поговоріть з інженером

Related

  • /what-we-do/operations/package-builds-mirror/
  • /what-we-do/operations/emergency-vulnerability-response/
  • /what-we-do/data-web/php-upgrades-security-patching/

Опубліковано 8 вересня 2026 р..

Усі нотатки з практики