В рассылке linux-api предложено новое решение для унификации и модернизации подсистемы аутентификационных логов в Linux — lastlog, btmp, utmp и wtmp. Идея, подробно описанная в RFC на GitHub, заключается в переходе от традиционных файловых форматов к стандартизированному хранению данных на основе SQLite. Это позволит решить несколько давно назревших проблем, включая ограниченную поддержку 32-битных временных меток, что вызовет проблемы после 2038 года, недостаточную гибкость форматов и сложности в управлении логами при интенсивной нагрузке.
Текущее состояние и ключевые проблемы
На сегодняшний день в Linux для хранения информации об аутентификации используются несколько файлов, каждый со своим форматом, описанным, например, в Glibc:
/var/log/lastlog: содержит данные о последнем входе пользователей. Временная меткаll_timeв структуреstruct lastlogимеет 32-битный типtime_t, что ограничивает её значение до 2038 года./var/log/btmp: фиксирует неудачные попытки входа в систему./var/run/utmp: отражает текущие сеансы пользователей./var/log/wtmp: хранит историю входов и выходов пользователей, а также информацию о перезагрузках системы.
Основные недостатки текущей реализации:
- Поле
tv_secв структуреutmpxиll_timeвlastlogиспользуют 32-битный типint32_t. Это означает, что после 19 января 2038 года эти поля перестанут корректно отображать время, если, конечно, не будет выполнено преобразование типов. Переход на 64-битные временные метки затруднён из-за проблем совместимости ABI. - Добавление новых полей в записи логов (например, идентификаторов сессий или IP-адресов) требует изменения существующих структур данных и может нарушить обратную совместимость.
- Утилиты вроде
last,lastb,whoиlastlogчасто сканируют весь файл для получения нужной информации. Это неэффективно, особенно для больших файлов, где требуется фильтрация по пользователю, терминалу или другим параметрам. - Отсутствие атомарных операций при записи данных. Это может привести к повреждению логов в случае системных сбоев или неожиданного завершения процессов.
- При записи одновременно несколькими процессами (например,
sshdиlogin) используются блокировкиflock, которые не всегда обеспечивают надёжную работу в NFS-средах.
Предлагаемое решение: SQLite
В рамках RFC предлагается перевести хранение всех аутентификационных логов в базу данных SQLite. Для этого разработаны новые C-библиотеки: liblastlog2, libbtmp2, libutmp2 и libwtmp2. Они будут использовать 64-битные временные метки типа INTEGER и позволят более гибко управлять схемами данных, в том числе добавлять новые поля без нарушения совместимости (посредством ALTER TABLE).
Переход на SQLite обеспечит ряд преимуществ:
- Использование 64-битного типа
INTEGERдля временных меток решает проблему 2038 года. - Возможность индексации полей для быстрого поиска и фильтрации данных по пользователю, терминалу или другим критериям.
- Поддержка транзакций (ACID-свойства) и механизма WAL (Write-Ahead Logging) для повышения надёжности и целостности данных.
- SQLite — это встраиваемая база данных с минимальными накладными расходами и широким распространением, что упрощает её интеграцию.
Механизм "двойной записи" (dual-write)
Для миграции и обеспечения совместимости предлагается использовать механизм "двойной записи":
- Программы, которые пишут данные в логи (например,
login,sshd,sudo,cron), будут модифицированы для одновременной записи как в старые файловые форматы, так и в новую базу данных SQLite. - Предполагается создать новые утилиты для чтения логов (
last2,lastb2,who2,lastlog2), которые будут читать данные из SQLite. При этом старые утилиты сохранят свою функциональность, работая с файлами. - В перспективе, после полного перехода, запись в старые файловые логи будет отключена, а старые утилиты могут быть обновлены для чтения из SQLite или выведены из эксплуатации.
Дальнейшие шаги и области для проработки
Авторы RFC выделяют несколько задач, требующих дальнейшего изучения:
- Интеграция с другими подсистемами, например, с
libsession2для управления сеансами. - Механизмы очистки старых записей из базы данных.
- Определение места хранения базы данных (например,
/var/lib/для постоянных данных или/var/log/для логов). - Адаптация существующих инструментов анализа логов под новый формат.
- Обеспечение ротации и компрессии баз данных SQLite.
- Разработка отказоустойчивых механизмов (fallback), чтобы система продолжала работать, даже если SQLite-база повреждена или недоступна. Например, при невозможности записи в SQLite-файл, данные временно могли бы дублироваться в старом файловом формате.