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 выполнил его один раз для двух файлов |
Три ловушки, найденные при проверке
- Первый запуск ничего не вращает. Отладочный запуск с новым файлом состояния показал для обоих файлов:
log does not need rotating (log has already been rotated)иnot running postrotate script, since no logs were rotated. При первом запуске logrotate запоминает дату и вращает только при следующем наступлении интервала. Для проверки используйте-f. - Две принудительные ротации за день при
dateextломаются. Вторая ротация в тот же день выдалаerror: destination /tmp/zzlogs/app/access.log-20261012 already exists, skipping rotation: имя архива с той же датой уже есть. В рабочей системе такое случается при ручных перезапусках, поэтому не вращайте принудительно дважды в сутки или добавьте формат даты со временем. - Неизвестная директива игнорируется. Опечатка
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 предполагает централизованный сбор журналов и реагирование на срабатывания: срок хранения, достаточный для расследования, — условие того, что собранные данные можно использовать.
Как проверить
logrotate -d /etc/logrotate.confне выдаёт строкerror; для своих файлов принудительная ротация даёт ожидаемые архивы и права.- Известен реальный охват локального журнала (число суток), он не меньше принятого срока либо журналы пересылаются на сервер.
- Лимиты journald заданы явно и подтверждены
systemd-analyze cat-config. - Свободное место на разделе с журналами контролируется в мониторинге.
Источники
- Методика оценки уровня зрелости кибербезопасности компании, Группа Сбер: 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. Международная практика, не российский норматив.






















