Централизованный сбор логов с уведомлениями
Когда админу делать нечего - он бэкапы настраивает. Когда СОВСЕМ нечего - безопасность. © Профессиональная народная поговорка.
Итак, задача: централизованно собирать, хранить и (желательно) анализировать логи.
Дано:
- ~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 - "?
И в дальнейшем, по мере расследования различных факапов, дописываются новые правила для логов.
большая часть из которых - тупо heartbeat'ы ↩