logrotate и journald: сколько хранить журналы и как это проверить

0
5
Обложка статьи: logrotate и journald: сколько хранить журналы и как это проверить

Журналы нужны, пока их можно прочитать: при расследовании инцидента вы смотрите на недели и месяцы назад. Если ротация настроена на «семь дней» или лимит журнала systemd выбран слишком маленьким, к моменту обнаружения взлома следов уже нет. С другой стороны, неограниченные журналы забивают диск и останавливают службы. Ниже настройка logrotate и journald, проверка на тестовых файлах и способ узнать, сколько времени охватывает ваш журнал на самом деле.

Статья опирается на логику направления «Мониторинг кибербезопасности» из методики зрелости Группы Сбер (источник); это методика для крупных компаний, мы используем её как ориентир и пересказываем своими словами. Проверка выполнена на Debian 12 (logrotate 3.21, systemd 252) на временных файлах: рабочие журналы и настройки не затрагивались. Сбор журналов на отдельный сервер: централизованный сбор логов.

Что должно получиться

Уровень Что это значит на практике
2. Гигиенический Журналы собираются централизованно, настроены оповещения, на срабатывания реагируют в согласованный срок; срок хранения достаточен для расследования

Критерии сформулированы нами по мотивам методики, это ориентир, а не оценка соответствия.

Сколько хранить

Журнал Ориентир Почему
Аутентификация, привилегированные действия, события безопасности Не менее 3–6 месяцев (на отдельном сервере сбора) Атаки обнаруживают спустя недели; для разбора нужна история
Журналы веб-сервера 1–3 месяца Расследование взломов сайта, подсчёт сроков утечек; следите за персональными данными в адресах и запросах
Журналы приложений По назначению, 14–60 дней Баланс между отладкой и объёмом; не пишите в них ПДн: разработка с ПДн
Журналы доступа к системам с ПДн По требованиям вашего уровня защищённости и политике См.: журналы ИСПДн

Локальный журнал сервера не должен быть единственным: нарушитель удаляет его первым. Копия на отдельном сервере с ограниченным доступом защищает историю.

logrotate: конфигурация

Файл /etc/logrotate.d/myapp. Путь и права замените своими. Приложение должно открывать журнал заново после ротации (или используйте copytruncate, если перезагрузить его нельзя, с риском потери нескольких строк).

# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
    daily
    rotate 14
    maxage 30
    missingok
    notifempty
    compress
    delaycompress
    dateext
    dateformat -%Y%m%d
    create 0640 root adm
    sharedscripts
    postrotate
        echo "reload-signal-sent" >> /var/log/myapp/reload.log
    endscript
}
Директива Назначение
daily, rotate 14, maxage 30 Ежедневная ротация, хранить 14 архивов, не старше 30 дней
missingok, notifempty Не ошибаться, если файла нет; не вращать пустые файлы
compress, delaycompress Сжимать архивы; последний архив оставить несжатым на сутки (приложение может ещё писать в него)
dateext, dateformat Имя архива с датой вместо номера
create 0640 root adm Создать новый файл с нужными правами и владельцем
sharedscripts, postrotate Выполнить скрипт один раз для всех файлов шаблона (например, сигнал приложению открыть журнал)

Проверка logrotate на тестовых файлах

mkdir -p /tmp/zzlogs/app
seq 1 200 > /tmp/zzlogs/app/error.log
logrotate -d -s /tmp/zz-state /tmp/zz-app.conf      # отладка: ничего не меняет
logrotate -f -s /tmp/zz-state /tmp/zz-app.conf      # принудительная ротация
ls -l /tmp/zzlogs/app

Опция -d печатает, что было бы сделано, не меняя файлы; -f принудительно вращает; -s задаёт отдельный файл состояния, чтобы не трогать рабочее состояние в /var/lib/logrotate/. Результат принудительной ротации на тестовых файлах:

Файл После -f
access.log Новый пустой файл (права -rw-r----- root adm)
access.log-20261012 Прежнее содержимое, пока не сжато (delaycompress)
postrotate.txt Одна строка от скрипта: sharedscripts выполнил его один раз для двух файлов

Три ловушки, найденные при проверке

  1. Первый запуск ничего не вращает. Отладочный запуск с новым файлом состояния показал для обоих файлов: log does not need rotating (log has already been rotated) и not running postrotate script, since no logs were rotated. При первом запуске logrotate запоминает дату и вращает только при следующем наступлении интервала. Для проверки используйте -f.
  2. Две принудительные ротации за день при dateext ломаются. Вторая ротация в тот же день выдала error: destination /tmp/zzlogs/app/access.log-20261012 already exists, skipping rotation: имя архива с той же датой уже есть. В рабочей системе такое случается при ручных перезапусках, поэтому не вращайте принудительно дважды в сутки или добавьте формат даты со временем.
  3. Неизвестная директива игнорируется. Опечатка dayly вместо daily даёт сообщение error: ... unknown option 'dayly' -- ignoring line, после чего logrotate работает с умолчаниями (без ежедневной ротации). Поэтому после правки всегда запускайте logrotate -d и ищите строки с error.

Проверка всего рабочего набора: logrotate -d /etc/logrotate.conf 2>&1 | grep -c '^error' должна дать 0. Запуск ротации выполняет таймер logrotate.timer раз в сутки в полночь: проверьте его командой systemctl list-timers | grep logrotate: колонка NEXT заполнена.

journald: хранение журнала systemd

Журнал systemd ограничивается не днями, а объёмом. Файл /etc/systemd/journald.conf.d/10-retention.conf:

# /etc/systemd/journald.conf.d/10-retention.conf
# Комментарии в systemd пишутся на отдельных строках: в конце строки с параметром они станут частью значения.
[Journal]
# хранить на диске (каталог /var/log/journal должен существовать)
Storage=persistent
# потолок объёма журнала
SystemMaxUse=500M
# всегда оставлять свободное место на разделе
SystemKeepFree=1G
# не хранить записи старше трёх месяцев
MaxRetentionSec=3month
Compress=yes
# не дублировать в rsyslog, если он не нужен
ForwardToSyslog=no
# лимит сообщений одной службы за интервал (выше значения по умолчанию)
RateLimitIntervalSec=30s
RateLimitBurst=10000
  • Комментарии в файлах systemd пишите на отдельных строках: если дописать их после значения, они станут частью значения.
  • Для хранения на диске каталог /var/log/journal должен существовать (sudo mkdir -p /var/log/journal), иначе журнал держится в памяти и теряется при перезагрузке; на многих дистрибутивах с Storage=auto достаточно создать каталог.
  • Применение: sudo systemctl restart systemd-journald (журнал не теряется, но сообщения в момент перезапуска могут задержаться).
  • Итоговую конфигурацию с учётом всех файлов показывает systemd-analyze cat-config systemd/journald.conf.

Сколько времени охватывает журнал на самом деле

journalctl --disk-usage
journalctl --list-boots --no-pager | tail -3
journalctl --no-pager -o short-iso | head -1

Первая команда показывает занятый объём, вторая — период от первой до последней записи текущей загрузки, третья — самую раннюю запись. На проверенном сервере при лимите SystemMaxUse=200M журнал занимал 191,8 МБ и охватывал около семи суток (с 5 по 12 октября). Это значит, что любое событие старше недели из локального журнала уже недоступно: для расследования нужна копия на отдельном сервере или увеличение лимита. Правило оценки: оставьте на журнал разумный объём диска и поделите его на суточный прирост (объём за неделю / 7). Объём можно сократить, фильтруя шумные службы и убирая неинформативные сообщения, а не только увеличивая лимит.

Сократить журнал вручную можно командами journalctl --vacuum-time=30d или --vacuum-size=300M: они удаляют старые записи необратимо, используйте осознанно.

Диагностика

Симптом Причина и что делать
Журнал приложения не ротируется Опечатка или не тот путь. Запустите logrotate -d, найдите error и пометку «does not need rotating»
После ротации приложение пишет в старый файл Оно держит дескриптор. Добавьте сигнал открытия журнала в postrotate или copytruncate
Журналы быстро заполняют диск Нет ограничения по размеру. Добавьте size или maxsize и лимиты journald
В расследовании не хватает событий недельной давности Лимит journald слишком мал. Увеличьте и настройте отправку на сервер сбора
После перезагрузки журнал пуст Хранение в памяти. Создайте /var/log/journal и задайте Storage=persistent

Где это в модели зрелости

Материал относится к направлению «Мониторинг кибербезопасности» (материалы направления, карта зрелости). Уровень 2 предполагает централизованный сбор журналов и реагирование на срабатывания: срок хранения, достаточный для расследования, — условие того, что собранные данные можно использовать.

Как проверить

  1. logrotate -d /etc/logrotate.conf не выдаёт строк error; для своих файлов принудительная ротация даёт ожидаемые архивы и права.
  2. Известен реальный охват локального журнала (число суток), он не меньше принятого срока либо журналы пересылаются на сервер.
  3. Лимиты journald заданы явно и подтверждены systemd-analyze cat-config.
  4. Свободное место на разделе с журналами контролируется в мониторинге.

Источники

  • Методика оценки уровня зрелости кибербезопасности компании, Группа Сбер: sberbank.ru.
  • Руководства: man logrotate, man journald.conf, man systemd-analyze для вашей версии; проект logrotate: github.com/logrotate.
  • NIST SP 800-92, Guide to Computer Security Log Management: csrc.nist.gov. Международная практика, не российский норматив.

Оставьте свой ответ