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

В этот раз все мануалы были на ELK5 или еще старше, а мне не очень хотелось ставить софтину пред-предыдущих версий. Мне хотелось взять софтину с наиболее перспективными сроками поддержки: желательно самое свежее из стабильного.

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

Итак, сегодня Mikrotik (RouterOS), Suricata 4.1, Elasticsearch+Filebeat+Kibana 6.5.

Вместо вступления


Условия:

  • Mikrotik на i386 в виртуальной машине на хосте А. Все интерфейсы на Mikrotik'е раскиданы по VLAN'ам, хост имеет один физический сетевой интерфейс.
  • Свободные ресурсы для IDS/IPS/NMS на хосте Б с единственным физическим сетевым интерфейсом.
  • 20-мегабитный канал наружу.
  • Желание получать аналитику о проходящем через внешний интерфейс Mikrotik'а трафике.
  • Бюджет в хрен рублей и фиг копеек.
  • Некоторое количество свободного от хлопот времени.

Я не стану рассказывать здесь, что такое IDS/IPS/NMS, зачем оно нужно и какое оно бывает. Все это знают и без меня, а кто не знает, тот нагуглит.

Так же я не стану обосновывать свой выбор между Snort и Suricata в пользу последнего. Это дело вкуса.

Зато поверхностно объясню, как это работает:

Suricata неким образом получает трафик. Вариантов три: а) пропускать его через себя в inline-режиме, б) получать копию трафика с порта коммутатора и в) анализировать дампы с трафиком. Полученный трафик Suricata подвергает анализу и на основе проведенного анализа выдает данные о том, что же она там в этом трафике нашла.

Данные Suricata может выдавать в JSON'е. Соответственно, имея структурированные данные, их можно скормить какой-нибудь системе для обработки, систематизации, анализа и визуализации.
Для анализа и визуализации данных, на сколько я понял, не являясь специалистом в этой области, прекрасно подходит ELK-стек. ELK-стек первоначально состоял из Elasticsearch, Logstash, Kibana. Сейчас к нему добавился Beat (семейство программ-интерфейсов, выступающих посредником между источником данных и Logstash'ем или Elasticsearch'ем). Забегая вперед, скажу, что обошлось без Logstash'а, поскольку Beat прекрасно отдает данные напрямую в Elasticsearch, а Elasticsearch отлично их кушает. Скушанные данные Elasticsearch передает Kibana — веб-интерфейсу для всего ELK-стека. Kibana, используя шаблоны, переданные ему Filebeat'ом, предоставляет пользователю визуализацию данных, так называемые Dashboard'ы. Учитывая тот факт, что Elasticsearch, Logstash, Beat и Kibana плод трудов одного производителя, все это хозяйство неплохо увязывается друг с другом, и процесс связывания неплохо документирован (по опенсорсным меркам, конечно).

Таким образом, исходя из вышесказанного, задачу можно описать так: получить копию трафика с порта маршрутизатора, передать ее в Suricata, получить от Suricata данные в JSON-формате, передать их в Filebeat, чтобы тот, в свою очередь, передал их в Elasticsearch и помог Kibana создать их визуальное отображение.

Mikrotik RouterOS


Если бы маршрутизатор Mikrotik у меня был аппаратный, то вопрос зеркалирования порта (port mirroring) не стоял бы вообще. Все решилось бы включением зеркалирования трафика, проходящего через внешний интерфейс, на любой свободный порт самого Mikrotik'а. Если бы не было свободного порта на Mikrotik'е, можно было бы включить зеркалирование порта на коммутаторе. Но в моем случае Mikrotik вообще не имел физических портов, а порт на коммутаторе получал трафик со всего хоста, на котором, кроме Mikrotik'а, было еще несколько виртуальных машин.

И тут я в очередной раз мысленно сказал: «Спасибо, Mikrotik!». Спасибо за встроенный в RouterOS сниффер. По традиции обходимся без скриншотов, одними лишь консольными командами.

Открываем терминал в WinBox'е и включаем сниффер:

/tool sniffer set filter-interface=if-out filter-stream=yes streaming-enabled=yes streaming-server=192.168.1.253
/tool sniffer start


Указываете вместо if-out имя интерфейса, трафик с которого планируете перехватывать, и вместо 192.168.1.253 — IP-адрес машины, куда по протоколу TZSP будет отправляться перехваченный трафик.

С Mikrotik'ом все.

Suricata


Вообще, я не очень линуксоголовый, поэтому больше всего люблю попсовые дистрибутивы. Ну, разве что больше люблю более аскетичный Debian. Вот и начал с него. Ну и, разумеется, в силу нелинуксоголовости ставить хотел бинарники и из репозитория. Сборка — это мне всегда лениво. Так вот, если будет возможность выбрать Debian, — не выбирайте. Я сейчас не вспомню, в каком именно месте у меня был затык в установке всего хозяйства под Debian'ом, но он был. И вся дальнейшая история об установке всего под Ubunta.

Была создана 4-ядерная виртуальная машина с 4 гигами оперативки, скачан и установлен на нее Ubuntu Server 18.04.1 LTS (x64)

Соглашение: все дальнейшие действия выполняются от имени superuser, поэтому или логиньтесь под root, или к каждой команде добавляйте sudo.

Поскольку на каждом этапе я делал снапшоты, а потом неоднократно к ним откатывался, в конце я прикурил изрядных глюков с рассинхроном времени в виртуалке с реальным временем.
Поэтому сразу выставляем правильный часовой пояс и синхронизацию по NTP:

systemctl start systemd-timesyncd
systemctl status systemd-timesyncd
dpkg-reconfigure tzdata


Для того, чтобы при установке Suricata не было проблем с зависимостями, добавляем репозитории universe в /etc/apt/sources.list:

nano /etc/apt/sources.list

deb archive.ubuntu.com/ubuntu bionic main universe
deb archive.ubuntu.com/ubuntu bionic-security main universe
deb archive.ubuntu.com/ubuntu bionic-updates main universe

Так же добавляем репозиторий, откуда будем брать Suricata:
add-apt-repository ppa:oisf/suricata-stable

Обновляем базу пакетов:
apt-get update

Устанавливаем Suricata:
apt-get install -y suricata

Следующий этап — установка правил для Suricata и их апдейта:
apt-get install -y python-pip
pip install pyyaml
pip install https://github.com/OISF/suricata-update/archive/master.zip


Запускаем обновление самого suricata-update:
pip install --pre --upgrade suricata-update

Запуск без дополнительного конфигурирования поставит нам Emerging Threats Open ruleset:
suricata-update

Чтобы посмотреть список источников, выполняем:
suricata-update list-sources

Обновление источников правил:
suricata-update update-sources

Посмотрим, что там наобновлялось в источниках, выполним повторно:
suricata-update list-sources

Включаем все бесплатные источники:
suricata-update enable-source ptresearch/attackdetection
suricata-update enable-source oisf/trafficid
suricata-update enable-source sslbl/ssl-fp-blacklist


И еще раз обновляем правила:
suricata-update

Suricata установлена.

Теперь надо получить трафик.

Trafr


Trafr — это приложение, написанное Mikrotik'ом для конвертации TZSP-трафика в pcap. Приложение 32-битное, поэтому для его запуска понадобится включить поддержку 32-битных приложений в 64-битной Ubunta:

dpkg --add-architecture i386
apt-get update && apt-get install -y libc6:i386


Скачиваем и распаковываем trafr:

wget http://www.mikrotik.com/download/trafr.tgz
tar xzf trafr.tgz


Проверяем, что трафик ловится:

./trafr -s

У меня после такого запуска в консоли виртуальной машины сломался символьный вывод в графическом режиме, пришлось перезагружаться. При удаленном подключении через ssh в PuTTY никаких проблем не было.

Если на экране видите беспорядочное мельтешение, значит трафик прилетает, и trafr его ловит. Раз так, переносим trafr на ПМЖ и запускаем его с передачей пойманного трафика через конвейер сразу в Suricata:

mv trafr /usr/local/bin/
/usr/local/bin/trafr -s | suricata -c /etc/suricata/suricata.yaml -r /dev/stdin


Сейчас проверяем, что трафик поступает в Suricata, для этого в соседнем терминале выполняем:

tail -f /var/log/suricata/fast.log

Должны увидеть шустрый скролл осмысленного текста — лог получения трафика сурикатой.

Так же не лишним будет убедиться, что Suricata трафик не только получает, но и анализирует:

tail -f /var/log/suricata/eve.json

Это как раз тот самый выход событий из Suricata в JSON-формате, который мы будем скармливать Filebeat'у.

Elasticsearch+Filebeat+Kibana 6.5


Устанавливаем необходимые зависимости:

apt-get install -y openjdk-8-jre apt-transport-https wget nginx

Обратите внимание, что Java версии 8. Все, что выше 8 — не поддерживается. Поэтому, если успели ранее установить более свежую Java, сносите ее и ставьте 8.

Убеждаемся, что Java установилась как надо:

java -version

Получим примерно такой вывод:
java version «1.8.0_191»
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)

Создаем пользователя и пароль для доступа к Kibana. Вместо admin выберите что-то, что вам больше по вкусу:

echo "admin:`openssl passwd -apr1`" | sudo tee -a /etc/nginx/htpasswd.users

Поскольку ELK будет крутиться на localhost, настраиваем reverse proxy в nginx:

nano /etc/nginx/sites-available/kibana
server {
listen 80;

server_name suricata.server;

auth_basic «Restricted Access»;
auth_basic_user_file /etc/nginx/htpasswd.users;

location / {
proxy_pass localhost:5601;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}

rm /etc/nginx/sites-enabled/default
ln -s /etc/nginx/sites-available/kibana /etc/nginx/sites-enabled/kibana


Перезапускаем nginx:

systemctl restart nginx

Ставим Elasticsearch:

apt-get install -y elasticsearch

Включаем автозапуск при загрузке ОС:

/bin/systemctl daemon-reload
/bin/systemctl enable elasticsearch.service


Запускаем:

systemctl start elasticsearch.service

Проверяем, поднялось ли:

curl -X GET "localhost:9200/"

В зависимости от производительности вашей железки, запуск ES может занять какое-то время. Если получаем connection refused, то просто повторяем запрос и ждем, пока в ответ не получим что-то вроде:
{
«name»: «lcZuxxm»,
«cluster_name»: «elasticsearch»,
«cluster_uuid»: «kmJHqJnlQe2Rk7F-CRi4EA»,
«version»: {
«number»: «6.5.1»,
«build_flavor»: «default»,
«build_type»: «deb»,
«build_hash»: «8c58350»,
«build_date»: «2018-11-16T02:22:42.182257Z»,
«build_snapshot»: false,
«lucene_version»: «7.5.0»,
«minimum_wire_compatibility_version»: «5.6.0»,
«minimum_index_compatibility_version»: «5.0.0»
},
«tagline»: «You Know, for Search»
}

Ставим Kibana:

apt-get install -y kibana

Включаем автозапуск при загрузке ОС:

/bin/systemctl daemon-reload
/bin/systemctl enable kibana.service


Запускаем:

systemctl start kibana.service

Теперь можно перейти на 192.168.1.253 (естественно, IP-адрес тот, что назначили вашей машине с сурикатой). Должна открыться титульная страница Kibana

Ставим Filebeat:

apt-get install -y filebeat

Включаем автозапуск при загрузке ОС:

/bin/systemctl daemon-reload
/bin/systemctl enable filebeat


Включаем модуль Suricata, входящий в набор модулей Filebeat:

filebeat modules enable suricata

Устанавливаем плагины для Suricata в Elasticsearch:

/usr/share/elasticsearch/bin/elasticsearch-plugin install ingest-geoip
/usr/share/elasticsearch/bin/elasticsearch-plugin install ingest-user-agent


Перезапускаем Elasticsearch:

systemctl restart elasticsearch.service

Выполняем первоначальную настройку Filebeat, заодно выполнится загрузка шаблонов в Kibana:

filebeat setup -e

Проверяем, что Filebeat нашел /var/log/suricata/eve.json и обрабатывает его, для этого запускаем Filebeat в режиме вывода на экран данных с маркером publish:

filebeat -e -d "publish"

Первым пойдет json-форматированный вывод самого Filebeat'а, потом простой текстовый вывод его логов, и только спустя некоторое время вывод из Suricata, поэтому выждите и убедитесь, что все работает. После этого прервите Filebeat и вернитесь в bash.

Включаем автозапуск при загрузке ОС:

/bin/systemctl daemon-reload
/bin/systemctl enable filebeat.service


Запускаем Filebeat:

systemctl start filebeat.service

Переходим в Kibana, выбираем в меню слева Dashboard, выбираем индекс filebeat-*. Снова выбираем Dashboard, в списке выбираем [Suricata] Alert Overview и должны получить что-то вроде такого:

image

Факультативно


Не забудьте logrotate, а не то каким бы емким ни был жесткий диск, Suricata его забьет очень быстро:

nano /etc/logrotate.d/suricata
/var/log/suricata/*.log /var/log/suricata/*.json
{
rotate 3
missingok
nocompress
create
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/suricata.pid 2>/dev/null` 2>/dev/null || true
endscript
}

Кроме того, ходили слухи, что у кого-то регулярно сниффер в Mikrotik'е при статусе running перестает отдавать трафик. Тогда пишем скрипт для перезапуска сниффера и запускаем его по расписанию:

/tool sniffer stop
:delay 30s
/tool sniffer start


Заключение


Признаться, я не вполне доволен стабильностью приведенной выше связки. А именно: стоит перезагрузиться, и начинаются чудеса. Один раз у меня перестали обрабатываться правила все, кроме пары. Пришлось все переустанавливать. Во второй раз Elasticsearch вообще перестал получать данные от Filebeat, и пришлось откатываться к снапшоту состояния до перезагрузки.

Эти проблемы пока не решил.

Кроме того, в планах реализовать IPS на базе переданных в Mikrotik IP-адресов злодеев, выявленных Suricata.

Комментарии (14)


  1. Nikopol_86
    30.11.2018 14:27

    В дополнении скажу, что тема неплохо освещена на Московском MUMе 2018 года от Романа Козлова, также у него на канале есть более подробное видео с вебинара (не воспринимайте за рекламу, просто сам немного интересуюсь данной темой). Посмотрите, может что то новое для себя откроете. Также есть телеграмм канал, можно спросить там по вашим проблемам.
    А так статья хорошая, спасибо за труды.


    1. LazyFao Автор
      30.11.2018 16:19

      Да, я просмотрел это видео. Мне оно показалось несколько поверхностным, оно скорее как источник вдохновения для реализации такой связки на базе готового решения SELKS. У меня SELKS5 тоже участвовал в ходе поиска решения, но мне его не удалось завести с trafr, видимо, потому что плохо старался). В итоге описанное в моей статье решение лично для меня оказалось более простым и понятным, хотя, как я отметил в заключении, и не лишенным недостатков.


  1. gatall
    30.11.2018 19:03

    Буквально на неделе завершил (надеюсь) создание стабильной сборки mikrotik + SELKS, трафр не идет на той сборке debian из за отсутствия архитектуры и библиотек (после доставления хорошо работает, оставил tzsp2pcap так как указывал дополнительно порт приема),
    на данный момент сборка принимает 400 мбит от порт мирроринга (микротик свитч) и под 100 от сниффера микротика роутера (c виртуального интефейса), суриката смотрит в 2 интерфейса, блеклист микротика заполняется из fast.log suricatы. Дальше дело за farewall.


    1. gecube
      01.12.2018 14:00

      fare-wall? Ну, удачи!

      Вообще, конечно, вопрос — насколько это все эффективно. Не удивительно, что функции файрволла тащат через dpdk в юзер спейс. Либо ставят отдельную коробку. Ибо все задыхается от недостатка производительности


  1. dimsoft
    01.12.2018 22:52

    А готового appliance нет?


    1. LazyFao Автор
      01.12.2018 16:06

      Вы имеете в виду virtual appliance? Если его, то нет.
      Если имеете в виду готовое решение, то оно есть, но у меня не заработало по причине, указанной в комментарии выше:

      трафр не идет на той сборке debian из за отсутствия архитектуры и библиотек (после доставления хорошо работает<...>)

      Я говорю о SELKS.


  1. athacker
    01.12.2018 10:43

    А виртуализация какая? Оно не умеет, как ESXi, делать promisc-порты в нужном влане? Это позволило бы без trafr обойтись, а напрямую в сурикату копию WAN-трафика WAN отдать.


    1. LazyFao Автор
      01.12.2018 10:58

      ESXi и есть. Если бы они были на одном хосте, то задача зеркалирования порта была бы решена силами vSwitch'а, да… Вообще, я сторонник принципа keep it simple, и если задачу можно решить минимумом привлеченных ресурсов, значит так ее и надо решать).


  1. gecube
    01.12.2018 13:57

    Чего не достаёт:


    • развертывание всего через docker'ы (изоляция сервисов — это прекрасно)
    • или хотя бы разворачивания через ansible (долой копипаст команд!!!)
    • второй" головы" для эластика (в режиме standalone он работает плохо)
    • установки trafr как сервиса (ну, нафига записать тулзу в nohup/screen, если можно написать systemd юнит)
    • настройки параметров джавы (ну, там Хип и пр.)
      Понимаю, что часть этого за скоупом статьи, но мы же делаем всё "по уму", не так ли?

    В остальном — большое спасибо, очень интересный опыт.


    1. LazyFao Автор
      01.12.2018 16:02

      Вы меня заинтриговали). В чем выражается плохая работа ES, если он один? И что именно нужно подкрутить у джавы, и что будет, если этого не сделать?

      Касаемо второго пункта — это прекрасно, но чтобы создать пакет развертывания, сначала нужно, чтобы оно хотя бы заработало после установки ручками, и именно этот процесс я описал).


      1. gecube
        01.12.2018 16:08

        Кратко. По эластику — он, например, никогда не даст «зелёный» статус кластера в однонодовом режиме.
        Ну, как минимум, неаккуратненько. Я уж не говорю про отказоустойчивость, быстродействие и т.п.
        Кстати, очень не круто может быть, когда диск на ноде с эластиком будет кончаться место.
        По джава — ну, вопрос в том, что несколько сервисов на одной машине будут «давить» друг друга. Попробуйте залить много данных в эластик и сделать «злой» запрос в кибану. Дальше уже всякие xmx, xms и прочая фигня.

        Касательно разворачивания. Ну, да, наверное, можно сначала сделать «в черную».


        1. LazyFao Автор
          03.12.2018 11:54

          Понял, спасибо.


  1. DrrRos
    01.12.2018 14:36

    Мне кажется прелесть Сурикаты как раз в работе как IPS, с его-то inline режимом и блокировкой только нежелательного трафика, а блокировать все IP только из за того, что они генерили алерты как-то грубовато.


    1. LazyFao Автор
      01.12.2018 14:44

      IDS/NMS это только обнаружение и мониторинг.
      IPS это тема для отдельного разговора. И в этом разговоре, разумеется, не будет размахивания шашкой на каждый алерт.