Привіт, це Kernelka! Якщо ви серйозно ставитеся до безпеки, настав час навести лад у логах входів: хто, коли і звідки входив у вашу систему. Покажу, як поєднати auditd і rsyslog для централізованого аудиту входів на Linux, акуратної фільтрації, довготривалого зберігання та розумних оповіщень 🕵️.

Що саме ми аудіюємо

Мета — зібрати події успішних і невдалих входів (локальні консолі, sshd, su, sudo) і події auditd типів USER_LOGIN, USER_AUTH, USER_START, USER_END. Ми фільтруємо їх через rsyslog, зберігаємо окремо як структуровані log-файли Linux, пересилаємо на центральний сервер Linux і вмикаємо оповіщення. Також торкнемося тем автоматизація задач і cron та systemd timers для простих нотифікацій.

Підготовка оточення

Встановіть потрібні пакети (клієнт і сервер):

# Debian/Ubuntu
sudo apt update
sudo apt install -y auditd audispd-plugins rsyslog rsyslog-relp mailutils

# RHEL/CentOS/Rocky/Alma
sudo dnf install -y audit audispd-plugins rsyslog rsyslog-relp mailx

# Увімкнути сервіси при старті
sudo systemctl enable --now auditd rsyslog

Налаштування auditd і вивід у syslog

auditd вже генерує події входів (через PAM). Нам потрібно віддати їх у rsyslog через плагін audisp-syslog.

Увімкніть плагін audisp-syslog

# На сучасних системах файл, як правило, тут:
# /etc/audit/plugins.d/syslog.conf
# На старіших Debian/Ubuntu — тут:
# /etc/audisp/plugins.d/syslog.conf

# Увімкнути плагін (спробувати обидва шляхи)
sudo sed -i 's/^active = no/active = yes/' /etc/audit/plugins.d/syslog.conf 2>/dev/null || true
sudo sed -i 's/^active = no/active = yes/' /etc/audisp/plugins.d/syslog.conf 2>/dev/null || true

sudo systemctl restart auditd

Перевірте, що з'являються події входів:

# Спробуйте залогінитися по SSH (успішно і з хибним паролем)
ssh localhost

# Перегляд останніх подій логіну від auditd
sudo ausearch -m USER_LOGIN,USER_AUTH -ts recent | tail -n 20

# Звіт по логінах
sudo aureport -l --failed --success

Фільтрація та централізація через rsyslog (клієнт)

Створимо окремий файл з правилами, який:

  • фільтрує події входів з auditd, sshd, sudo, su;
  • пише їх локально у структурований файл JSON;
  • пересилає на центральний сервер по RELP+TLS (надійно і з підтвердженням доставки) ⚡.
# Підготуйте кореневий сертифікат ЦС для TLS (приклад шляхом /etc/rsyslog.d/ca.pem)
# sudo cp /path/to/ca.pem /etc/rsyslog.d/ca.pem

sudo tee /etc/rsyslog.d/60-login-audit.conf > /dev/null <<'RSY'
# Шаблон JSON для подій логіну
template(name="LoginJSON" type="list") {
  constant(value="{")
  constant(value="\"host\":\"") property(name="hostname")
  constant(value="\",\"app\":\"") property(name="programname")
  constant(value="\",\"msg\":\"") property(name="msg" format="json")
  constant(value="\",\"time\":\"") property(name="timereported" dateFormat="rfc3339")
  constant(value="\"}\n")
}

# Відбір подій входів з auditd/sshd/sudo/su
if (
  ($programname == "audisp-syslog" and re_contains($msg, "type=USER_(LOGIN|AUTH|START|END|ACCT)"))
  or ($programname == "sshd" and (re_contains($msg, "Accepted") or re_contains($msg, "Failed password")))
  or ($programname == "sudo" and re_contains($msg, "session (opened|closed)"))
  or ($programname == "su"   and re_contains($msg, "session (opened|closed)"))
) then {
  action(type="omfile" file="/var/log/login-audit.log" template="LoginJSON")
  action(type="omrelp" target="log.example.net" port="6514" tls="on" 
         tls.caCert="/etc/rsyslog.d/ca.pem" template="LoginJSON" 
         queue.type="LinkedList" queue.size="10000" action.resumeRetryCount="-1")
  stop
}
RSY

sudo systemctl restart rsyslog

# Перевірка: має з'явитися /var/log/login-audit.log з JSON-рядками
sudo tail -f /var/log/login-audit.log

Центральний rsyslog-сервер: прийом і зберігання

На центральному сервері приймемо RELP+TLS і складемо події по хостах.

sudo tee /etc/rsyslog.d/10-relp-input.conf > /dev/null <<'RELPSRV'
module(load="imrelp")

# Шаблон для файлів за хостами
template(name="PerHostLogin" type="string" string="/var/log/remote/%HOSTNAME%/login-audit.log")

# Вхід RELP з TLS (CA тут як приклад)
input(type="imrelp" port="6514" tls="on" tls.caCert="/etc/rsyslog.d/ca.pem" ruleset="central")

ruleset(name="central") {
  action(type="omfile" DynaFile="PerHostLogin" createDirs="on")
}
RELPSRV

sudo systemctl restart rsyslog

Довготривале зберігання (logrotate)

Налаштуємо ротацію для локального файлу клієнта; подібно можна для директорії /var/log/remote/ на сервері.

sudo tee /etc/logrotate.d/login-audit > /dev/null <<'ROT'
/var/log/login-audit.log {
  weekly
  rotate 26           # ~півроку
  compress
  missingok
  notifempty
  create 0640 root adm
  postrotate
    /bin/systemctl kill -s HUP rsyslog.service || true
  endscript
}
ROT

Оповіщення про підозрілі входи

Варіант A: миттєво через rsyslog (email)

Надішлемо лист при невдалих аутентифікаціях:

sudo tee /etc/rsyslog.d/61-login-alerts.conf > /dev/null <<'ALRT'
# Лист при помилковому вході (auditd або sshd)
if (re_contains($msg, "Failed password|type=USER_AUTH.*res=failed")) then {
  action(type="ommail" server="localhost" to="secops@example.net" 
         subject="[SEC] Login failed on %hostname%" from="rsyslog@example.net")
}
ALRT

sudo systemctl restart rsyslog

Порада: переконайтесь, що поштовий агент (postfix/msmtp) налаштований на відправлення назовні.

Варіант B: періодичні перевірки (systemd timer)

Скрипт шукає за останні 2 хвилини підозрілі події і шле дайджест. Це проста автоматизація задач через cron та systemd timers.

# Скрипт-сканер
echo '#!/usr/bin/env bash
set -euo pipefail
OUT=$(journalctl -S "-2 minutes" -u ssh --no-pager | \ 
  egrep -i "Failed password|Accepted password" || true)
AUD=$(ausearch -m USER_AUTH,USER_LOGIN -ts recent 2>/dev/null | tail -n 100 || true)
if [[ -n "$OUT" || -n "$AUD" ]]; then
  {
    echo "SSH events (last 2 min):"; echo "$OUT";
    echo; echo "auditd events (last 2 min):"; echo "$AUD";
  } | mail -s "[SEC] Login digest on $(hostname)" secops@example.net
fi' | sudo tee /usr/local/sbin/login-digest.sh > /dev/null
sudo chmod +x /usr/local/sbin/login-digest.sh

# Юніти systemd
echo '[Unit]
Description=Login digest mailer

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/login-digest.sh' | sudo tee /etc/systemd/system/login-digest.service > /dev/null

echo '[Unit]
Description=Run login digest every 2 minutes

[Timer]
OnBootSec=2min
OnUnitActiveSec=2min

[Install]
WantedBy=timers.target' | sudo tee /etc/systemd/system/login-digest.timer > /dev/null

sudo systemctl daemon-reload
sudo systemctl enable --now login-digest.timer

Альтернативні способи

  • audisp-remote: надсилати події auditd на окремий audit-сервер (рідний плагін для auditd).
  • syslog-ng: альтернатива rsyslog з подібними можливостями (фільтри, TLS, шаблони).
  • journal-remote/journal-upload: централізувати журнали systemd без rsyslog, якщо логіка фільтрації мінімальна.

GUI-спосіб (швидкий перегляд)

Для візуального огляду подій зручний веб-інтерфейс Cockpit: розділ Logs дозволяє швидко відфільтрувати sshd та audit.

# Встановлення Cockpit
# Debian/Ubuntu
sudo apt install -y cockpit
# RHEL-сімейство
sudo dnf install -y cockpit
sudo systemctl enable --now cockpit.socket
# Відкрийте https://<IP>:9090 у браузері, дивіться Logs і фільтруйте "sshd"/"audit"

FAQ

  • Не бачу подій USER_LOGIN у auditd. Переконайтесь, що працює auditd (systemctl status auditd) і в PAM-стеку є pam_loginuid.so (типово так). Перевірте ausearch -m USER_AUTH -ts recent.
  • rsyslog не шле на сервер. Перевірте DNS/порт, TLS-CA (/etc/rsyslog.d/ca.pem), лог rsyslog. Для тесту: logger -t test "hello" і дивіться на приймальній стороні.
  • TLS-помилка сертифіката. CA на клієнті має підписувати сертифікат сервера; CN/SAN повинен збігатися з іменем вузла, на який ви підключаєтесь.
  • Занадто багато подій. Звужуйте фільтри у rsyslog (залиште лише USER_* і sshd), використовуйте окремий файл і ротацію, вмикайте черги з дисковим бекендом.
  • Чому бачу auid=4294967295? Це «unset» (анонімна сесія). Перевірте коректність PAM/SSH-конфігів та спосіб запуску процесу.

Порада від Kernelka

Зберігайте архів логів на окремому розділі або S3-сумісному сховищі, а щотижня робіть самоперевірку: штучно створіть невдалий вхід і переконайтеся, що подія з'явилася локально, на центральному сервері й прийшло оповіщення. Маленькі регулярні тести рятують у великі дні інцидентів 😉

Підсумок

  • Увімкнули auditd і передали його події у rsyslog.
  • Виділили логіку фільтрації входів і зберегли в окремий файл.
  • Налаштували захищену централізацію (RELP+TLS) на сервер.
  • Додали довготривале зберігання через logrotate.
  • Увімкнули оповіщення: миттєво (rsyslog) або періодично (systemd timer).