main

Централизованный сбор логов с уведомлениями

Когда админу делать нечего - он бэкапы настраивает. Когда СОВСЕМ нечего - безопасность. © Профессиональная народная поговорка.

Итак, задача: централизованно собирать, хранить и (желательно) анализировать логи.

Дано:

  • ~100 хостов, ~100-800 мб логов в день всего.
  • сервер с софтрейдом, 3 Тб места, 1Гб памяти и старым Xeon'ом

Ограничения:

  • бюджета и железа под эту задачу никто не даст, разве что пост-фактум, когда "петух в жопу клюнет"
  • минимальное потребление ресурсов на сервере логов, минимум нагрузки на отправителя логов
  • делается для собственных нужд, поэтому наличием красивых отчётиков можно пренебречь

Разведка местности

Гугл говорит нам, что тема как-то реализуется или в масштабе большой компании с сотнями серверов, или отдельно взятого локалхоста. В первом случае это махровый энтерпрайз, в плохом смысле, а во втором - как правило, только плохонький анализатор одного лога "за день" с отчётом в итоге.

Тем не менее, стоит отметить решения из первой категории (в порядке возрастания адекватности):

  • splunk -- на официальном сайте стандартное ко-ко-ко про "облака", "high availability", "99.999", "mission critical" и прочий булшит. Тот обрезок, что предлагается скачать "на попробовать", всем видом подразумевает дальнейшую дойку клиента за саппорт.
  • OSSIM -- это не просто анализатор логов, а "security information and event management", как они это называют. Понапихано всякого, в частности мониторинг доступности и считалка трафика.
  • logstash -- оно же "буратино" или "полено". Анализатор логов, довольно мощный, но с ма-аленьким недостатком -- жаба. Что ставит крест на использовании у нас.

Далее, те что реально ставились и тестировались.

  • Prelude -- таки анализатор логов, по схеме "агент/сервер". Есть агент (c++), коллектор (c++), анализатор (python) и вебморда (python).
  • ossec -- древний, но живой и здоровый проект. Основной функционал - анализатор логов, но в случае чего может и правило в фаервол добавить. Писан ещё до победоносного нашествия скриптоты, поэтому быстр и брутален. Вебморды к нему как-то не прижились, поэтому рассчитывайте только на логи и письмо в почту. Важно - имеет накопленную и общедоступную базу паттернов для логов.

Реализация / коллектор

Prelude долго у меня гонялся в тестовом варианте, но всё же не взлетел: 4 хоста - 8 гигов базы за 3 месяца1. Сами логи не хранит, только сгенеренные event'ы.

Окончательно он меня добил вот этим (случайно заметил через консоль mysql'а):

| 152490 | prelude-manager | 10.1.1.4:41330 | preludemanager | Query   |    0 | updating |
DELETE FROM Prelude_Node WHERE _parent_type = 'H' AND _message_ident IN
(32863, 32864, 32865, 32866, 32867,
 <ещё куча-куча id'ов>,
 <...>
 <ещё куча-куча id'ов>, 33861, 33862) |

Идентификаторы последовательные, общим числом в тысячу штук.

А так всё отлично - передача информации на коллектор шифруется, при отвале связи сообщения спулятся и досылаются, вебморда это всё кажет, импорт просто syslog'а по сети - есть, в общем - красота. Когда-нибудь обязательно его ещё погоняю, скажем следующую мажорную версию.

Вернувшись в начало пути, я решил сперва организовать сбор и хранение логов, а потом уже к ним докручивать анализатор.

В качестве коллектора был выбран syslog-ng, из-за простоты и расширенных возможностей по организации файлов логов.

@version:3.5

# общие настройки
options { chain_hostnames(off); flush_lines(50); threaded(yes); };

# "сетевые" логи пишем в архив
source s_external { udp(ip(192.168.1.33) port(514)); };

destination d_archive {
  file("/mnt/logs/$YEAR-$MONTH-$DAY/$HOST.log"
    owner(nobody) group(nogroup) perm(0600) dir_perm(0700) create_dirs(yes));
};

log { source(s_external); destination(d_archive); };

# "свои" сообщения пишем в отдельный файл, для отладки и статистики
source s_internal { internal(); };

destination d_ownlog {
  file("/var/log/syslog-ng.log");
};

log { source(s_internal); destination(d_ownlog); };

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

# syslog-ng -s # проверяем конфиг
# service syslog-ng start # запускаем

На rsyslog это делается не так очевидно, но намного короче:

$CreateDirs on
module(load="imudp")
input(type="imudp" address="0.0.0.0" port="514" ruleset="logarchive")

$template DynFile,"/mnt/logs/%$YEAR%-%$MONTH%-%$DAY%/%fromhost-ip%.log"
ruleset(name="logarchive") {
  *.info    -?DynFile
  *.*       stop
}

Всё, приходящие логи пишутся, теперь проходимся по нужным хостам, чтобы включить их отправку. В /etc/*syslog.conf добавить примерно следующее:

*.info            @192.168.1.33 # поменять на нужный адрес

...и перезапустить там syslog.

Реализация / анализатор

В силу пункта №3 ограничений, было решено не маяться фигнёй, и настроить наименее жручее, хоть и не самое удобное решение, то бишь ossec.

Здесь придётся немного повозиться. Установку я расписывать не буду, она у всех специфичная, поэтому только покажу, что подпилить в конфигах. Я не использую "active response", поэтому убираю из конфига все секции с ним.

/var/ossec/etc/ossec.conf:

<ossec_config>
  <global>
    <email_notification>yes</email_notification>
    <email_to>root@localhost.</email_to>
    <smtp_server>127.0.0.1</smtp_server>
    <email_from>ossec.localdomain</email_from>
  </global>

  <!-- рекомендую проредить этот список от неиспользуемых наборов -->
  <rules>
    <include>rules_config.xml</include>
    <include>pam_rules.xml</include>
    <include>sshd_rules.xml</include>
    <include>telnetd_rules.xml</include>
    <include>syslog_rules.xml</include>
    <include>arpwatch_rules.xml</include>
    <include>named_rules.xml</include>
    <include>smbd_rules.xml</include>
    <include>vsftpd_rules.xml</include>
    <include>pure-ftpd_rules.xml</include>
    <include>proftpd_rules.xml</include>
    <include>ftpd_rules.xml</include>
    <include>roundcube_rules.xml</include>
    <include>wordpress_rules.xml</include>
    <include>cimserver_rules.xml</include>
    <include>web_rules.xml</include>
    <include>web_appsec_rules.xml</include>
    <include>apache_rules.xml</include>
    <include>nginx_rules.xml</include>
    <include>php_rules.xml</include>
    <include>mysql_rules.xml</include>
    <include>postgresql_rules.xml</include>
    <include>ids_rules.xml</include>
    <include>squid_rules.xml</include>
    <include>firewall_rules.xml</include>
    <include>postfix_rules.xml</include>
    <include>sendmail_rules.xml</include>
    <include>imapd_rules.xml</include>
    <include>mailscanner_rules.xml</include>
    <include>dovecot_rules.xml</include>
    <include>racoon_rules.xml</include>
    <include>vpn_concentrator_rules.xml</include>
    <include>spamd_rules.xml</include>
    <!-- <include>policy_rules.xml</include> -->
    <include>asterisk_rules.xml</include>
    <include>ossec_rules.xml</include>
    <include>attack_rules.xml</include>
    <include>local_rules.xml</include>
  </rules>

  <!-- сканирование localhost'а на предмет подозрительной активности -->
  <syscheck>
    <!-- Frequency that syscheck is executed -- default every 20 hours -->
    <frequency>72000</frequency>

    <!-- Directories to check  (perform all possible verifications) -->
    <directories check_all="yes">/etc,/usr/bin,/usr/sbin</directories>
    <directories check_all="yes">/bin,/sbin</directories>

    <!-- Files/directories to ignore -->
    <ignore>/etc/mtab</ignore>
    <ignore>/etc/hosts.deny</ignore>
    <ignore>/etc/mail/statistics</ignore>
    <ignore>/etc/random-seed</ignore>
    <ignore>/etc/adjtime</ignore>
    <ignore>/etc/httpd/logs</ignore>
  </syscheck>

  <!-- возможно потребуется исправить пути -->
  <rootcheck>
    <rootkit_files>/var/ossec/etc/shared/rootkit_files.txt</rootkit_files>
    <rootkit_trojans>/var/ossec/etc/shared/rootkit_trojans.txt</rootkit_trojans>
  </rootcheck>

  <global>
    <white_list>127.0.0.1</white_list>
  </global>

  <!--
    Самая главная секция в нашем случае, обязательно указать allowed-ips,
    иначе слушать порт откажется, типа "всё запрещено, мне нечего делать, завершаюсь"
  -->
  <remote>
    <connection>syslog</connection>
    <port>1514</port>
    <protocol>udp</protocol>
    <allowed-ips>127.0.0.0/8</allowed-ips>
  </remote>

  <!-- менять не рекомендую, эти настройки достаточно разумны -->
  <alerts>
    <log_alert_level>1</log_alert_level>
    <email_alert_level>7</email_alert_level>
  </alerts>

  <!-- Active Response Config -->
  <!-- у меня - не используется -->

  <!-- Files to monitor (localfiles) -->
  <!-- у меня - не используется -->

</ossec_config>

Пробуем запустить, смотрим логи (/var/ossec/logs/ossec.log), исправляем огрехи.

Теперь нам нужно отзеркалить приходящие логи с syslog-ng, чтобы ossec мог их анализировать. Вариант "писать всё в общий файл специально для ossec'а" меня не вдохновил, поэтому я включил секцию <remote> выше, чтобы ossec запустил свой сборщик логов и дописал в конфиг syslog-ng следующее:

destination d_ossec { udp("127.0.0.1" port(1514)); };

# исправлено
log {
  source(s_external);
  destination(d_archive);
  destination(d_ossec); # добавлена эта строчка
};

# killall -SIGHUP syslog-ng

Опять смотрим лог ossec'а (/var/ossec/logs/alerts/alerts.log), ждём первых alert'ов. Если пошли - значит всё работает. Вот как-то так оно должно выглядеть:

** Alert 1409290111.203427: mail  - syslog,arpwatch,new_host,
2014 Aug 29 05:28:31 10.123.58.1->127.0.0.1
Rule: 7201 (level 4) -> 'Arpwatch new host detected.'
Src IP: 0.0.0.0
Aug 29 09:28:32 10.123.58.1 arpwatch: bogon 0.0.0.0 e0:69:95:1f:d1:95

Такое же самое сообщение должно прилететь в почту, видите "203427: mail - "?

И в дальнейшем, по мере расследования различных факапов, дописываются новые правила для логов.


  1. большая часть из которых - тупо heartbeat'ы ↩