Skip to content

Защита /var и /etc от дрифта

В атомарной системе на базе bootc файловая система разделена на иммутабельную (/usr) и персистентную (/var, /etc) части. Директория /var не обновляется вместе с образом — она сохраняется как есть между обновлениями. Директория /etc управляется через 3-way merge, но не все изменения гарантированно применяются.

Это создает проблему дрифта — расхождения реального состояния файловой системы с тем, что ожидает образ.

Почему возникает дрифт

Репозиторий ALT Linux Sisyphus — это классический дистрибутив, не рассчитанный на атомарные обновления. Большинство пакетов не поставляют tmpfiles.d конфиги для своих директорий и файлов. В обычной системе это не проблема — пакетный менеджер создает все нужные файлы при установке. Но в атомарной системе:

  • /var не обновляется при смене образа. Если новый пакет в образе ожидает директорию в /var, а её там нет — сервис не запустится.
  • /etc проходит через 3-way merge при обновлении, но над файлами могли быть совершены деструктивные действия на стороне пользователи
  • Права и владельцы могут разъехаться: например, GID группы изменился в новом образе, а файлы в /var остались со старым владельцем.

Кроме обновлений, дрифт может возникнуть из-за ручных действий пользователя или сбоев.

Как APM решает проблему

APM включает модуль lint, который сканирует файловую систему образа и генерирует декларативные конфиги tmpfiles.d. При каждой загрузке systemd применяет эти конфиги, приводя /var и /etc в задекларированное состояние.

Что генерируется

Команда apm system image lint --fix (скрытая команда, выполняется автоматически при сборке образа, не запускайте на рабочей системе!) анализирует rootfs и создает /usr/lib/tmpfiles.d/apm-lint.conf с тремя типами записей:

  • d — директории с правами и владельцем. Если директория отсутствует, systemd создаст её при загрузке.
  • L — симлинки с правильным target. Если симлинк пропал или указывает не туда, systemd восстановит его.
  • z — права и владелец на существующие файлы. Если файл существует, но права или владелец расходятся — systemd исправит.

Пример сгенерированного конфига

ini
# Auto-generated by apm lint
d /var/lib/chrony 0755 _chrony _chrony - -
d /var/lib/libvirt/qemu 0750 _libvirt vmusers - -
d /var/spool/cron 0730 root crontab - -
L /etc/mtab - - - - /proc/mounts
L /etc/init.d - - - - rc.d/init.d
z /etc/openssh/sshd_config 0600 root root - -
z /etc/shadow 0400 root root - -

Что не покрывается

Тип z не создает файлы — только устанавливает права на существующие. Если конфигурационный файл пропал из /etc, tmpfiles.d не восстановит его содержимое. Такие файлы должны поставляться пакетом и восстанавливаться через ostree 3-way merge. Но конфиги из /etc которые входят в образ всегда доступны на рабочей системе и находятся в /usr/etc, можно считать этот референсным состоянием, в будущем мы напишем полноценные средства восстановления для /etc.

При сборке образа

При сборке образа через apm system image apply lint запускается автоматически — конфиг генерируется и включается в образ. На живой системе ничего запускать вручную не нужно.

Применение при загрузке

При каждой загрузке systemd автоматически выполняет systemd-tmpfiles --create, который читает все конфиги из /usr/lib/tmpfiles.d/, включая apm-lint.conf. Это происходит на раннем этапе загрузки.

Исключения

Некоторые директории намеренно исключены из рекурсивного анализа, так как их содержимое управляется другими механизмами:

ДиректорияПричина
/var/home, /var/rootДомашние директории пользователей
/var/tmpВременные файлы
/var/cache/aptКэш пакетного менеджера
/etc/rc.dSysVinit симлинки, управляются chkconfig
/etc/tcbУправляются системой аутентификации
/etc/alternatives/linksУправляются системой alternatives
/etc/skel*Шаблоны для создания пользователей

Опубликовано под лицензией GPL-3.0+. Содержание доступно по лицензии CC BY-SA 4.0, если не указано иное.