Showing posts with label Kibana. Show all posts
Showing posts with label Kibana. Show all posts

Thursday, February 12, 2015

ELK: Анализ почтовых журналов.

Итак, на сегодня у нас готовы:
1. Сбор журналов почтового сервера;
2. Их парсинг для упрощения анализа.
Займемся тем, ради чего все затеяно – собственно анализом.
Автоматизированный анализ, освобождающий наше время для чтения Интернета, пока отложим и займемся первичным визуальным анализом (Exploratory Data Analysis).
Для начала, нам нужно нечто, красиво формующее получаемые журналы.
Сделаем это посредством Kibana. Для этого был сделан небольшой dashboard выложенный на  github.com . Забирайте. Прежде чем загрузить dashboard в Kibana, в любом текстовом редакторе сделайте замену “dom1.int” и “dom2.int” на свои собственные домены.



Пара слов о dashborde. Он состоит из 5ти блоков.
1. “ALLMAIL” - Cодержит общий график отражающий количество отправленных и принятых сообщений по типу: внутренние, пришедшие извне, ушедшие вовне.
2. “INTERNAL” - график и таблицы для сообщений пересылаемых внутри периметра
 таблица “Source count (all)” - количество отправленных сообщений в штуках
 таблица “Destination count (all)” - количество полученных сообщений в штуках
 таблица “Summ by src (all)” - объем отправленных сообщений в байтах
 таблица “Summ by dst (all)” - объем полученных сообщений в байтах
3. “INSIDE” - график и таблицы для сообщений входящих в периметр
 набор таблиц аналогичен блоку “INTERNAL”
4. “OUTSIDE” - график и таблицы для сообщений выходящих за периметр
 набор таблиц аналогичен блоку “INTERNAL”
5. “ALL EVENTS” - таблица сообщений с полями, разобранными на предудущем этапе:
 @timestamp – примерное время отправки\приема сообщения
 source – источник (электронный адрес)
 destination – получатель (электронный адрес)
 subject - тема
 size – размер в байтах

Давайте скорее займемся самым интересным – анализом. Рассмотрим не очень сложный сценарий, который не просто выполнить сортировками почтовых журналов – будем искать сотрудников, пересылающих свою почту на внешний почтовый ящик.
Итак открываем dashboard “Maillog analysis” (пример сделан на данных последней недели января). Выберем четрверг с полуночи до полуночи. На периоде в сутки, как будет видно дальше, анализ проще.



Сразу замечаем человечка, который, вероятно, настроил пересылку. Делаем фильтр по его внутреннему адресу, щелкнув на значке лупы в любой из таблиц.


Видим, что в рамках рабочего дня (выделено красным), графики коррелируют довольно сильно, а за пределами – графики абсолютно идентичны. Разница вида графиков в рабочее время обусловлена тем, что сотрудник отправляет почту не только на внешний почтовый ящик, но и внутри периметра.
Для более точного анализа, отфильтруем сообщения, которые адресованы только на внутренний адрес сотрудника либо на его внешний адрес.
Фильтр, содержащий логику в kibana, формируется с особенностью – логический оператор пишется с использованием прописных букв:

 destination: “username@ dom1.int” OR “external@email.box”  
 

К счастью мы видим, что пересылка осуществляется не полностью. Сотрудник настроил пересылку только с определенных адресов для получения диспетчерских сводок. Дальнейшая проверка подтвердила это. Но сейчас мы об этом не знаем. Если закрыть глаза на разницу графиков в рабочее время, то по ночным журналам можно заряжать зондер-команду и отправлять ее вязать нарушителя. Подтверждение - пересылки почты вне рабочего дня - приведено на рисунке.


Ограничения метода:
1. Высокая трудоемкость, как следствие нерегулярность.
2. Не полное покрытие – отсеиваем сотрудников с большим трафиком и не замечаем слабонагруженные адреса, которые никогда не окажутся в топах.

Вообще, созданный dashboard, позволяет увидеть много интересного:
1. Сбои в работе почтовой системы – не фатальные, которые все замечают без специальных средств, а те в которых появляются задержки в пересылке, например. На первом рисунке видно, что почтовую систему лихорадило в пятницу, хотя на сбои в пересылке почты никто не жаловался.
2. Массовые рассылки, в том числе произведенные вредоносным ПО.
Выведя его на экран ситуационного центра, проходя мимо, можно зацепиться за что-нибудь глазами и выполнить детальный анализ уже на рабочем месте.

Буду рад, если сообщество предложит свои сценарии или направления анализа, с тем чтобы модифицировать dashboard и выложить его для использования.

Wednesday, February 11, 2015

ELK: Анализ почтовых журналов. Подготовка. Logstash.

Некоторое время назад мы начали готовиться к анализу почтовых журналов. Продолжим подготовку.
Используем logstash для парсинга сообщения на поля.
Тут нет ничего интересного и сложного. Вот часть файла конфигурации (/etc/logstash/conf.d/filter.conf), разбирающая сообщения, формируемые в предыдущей заметке:
 ...  
  else if [message] =~ "Secure_Maillog" {  
    mutate { replace => { "type" => "maillog" } }  
    grok {  
     patterns_dir => "/etc/logstash/patterns"  
     match => ["message", "<134>%{SYSLOGTIMESTAMP}\s+%{SYSLOGHOST:sourcehost}  
     \s+%{WORD:syslogprog}:\s+%{NUMBER:timestamp}\t%{EMAIL:source}  
     \t%{EMAIL:destination}\t%{NUMBER:size:int}\t%{GREEDYDATA:subject}"]  
    }  
    date {  
     match => ["timestamp", "UNIX"]  
    }  
  }  
 ....  

В "/etc/logstash/patterns" хранятся файлы с шаблонами. В частности файл "/etc/logstash/patterns/mail" состоит из следующих строк:

 LOGIN [A-Za-z0-9$.+!*'(),~#%&/=:;_-]+  
 EMAIL %{LOGIN}@%{IPORHOST}  
 GREEDYDATA .*  

На сегодня все.

Saturday, November 8, 2014

ELK в технологии

Переменка.
Тренировался в способах импорта данных в Elasticsearch, так же хотелось поиграться с "интенсивными и объемными" данными. Попросил данные у метрологов за месяц. Отдали с улыбкой, сказав, что какая-то жутко прогрессивная и дорогая система визуализации данных не справилась с их объемами, поэтому анализ больше чем за 1 день сделать не получается.
Получите и распишитесь.

Характеристика данных:
1. Объем данных 7.2 гб
2. Количество записей 122 000 000
3. Количество параметров: 713
4. Период месяц

Старый десктоп и пара ноутбуков (2-4 CPU, 4Gb RAM) собранные в кластер делают месячную выборку по 4м параметрам за несколько секунд.

Схема или, в терминах эластика, mapping:
 "sdku_type": {  
  "_all" : {"enabled" : false},    
  "_source" : {"enabled" : false},    
  "properties": {  
  "@timestamp": {  
   "type": "date",  
   "format": "dateOptionalTime"  
  },  
  "field": {  
   "type": "string"  
  },  
  "value":{  
   "type": "double"  
  }  
  }  
 }  

Скрипт для импорта:

 #!/usr/bin/python  
 import csv, sys, time, json, elasticsearch  
 from elasticsearch import helpers  
 es = elasticsearch.Elasticsearch(['localhost:9200'])  

 csvfile = 'MyTable.csv'  
 jdata = dict()  
 actions = list()  
 i = 0  

 with open(csvfile, 'rb') as file :  
   line = csv.reader(file, delimiter = ',', skipinitialspace = True)  
   for row in line :  
      i += 1  
      ptime = time.strptime(row[0][0:19], "%Y-%m-%d %H:%M:%S")   
      ctime = time.strftime('%Y-%m-%dT%H:%M:%S', ptime)   
      jdata = { '@timestamp': ctime, 'field': row[1], 'value': float(row[2]) }  
      action = { '_index': 'sdku', '_type': 'sdku_type', '_id': i, '_source': json.dumps(jdata, separators=(',', ':'))}  
      actions.append(action)  
      if i % 1000000 == 0:  
        elasticsearch.helpers.bulk(es, actions)  
        print "Indexed %d, working on next 100000" %(i)  
        actions = list()  
   elasticsearch.helpers.bulk(es, actions)  
   print "Indexed %d, finishing." %(i)  

Результат:

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

Wednesday, November 5, 2014

ELK: Анализ почтовых журналов. Подготовка

Продолжим тематику визуального анализа журналов. С журналов доступа в сеть Интернет переключимся на почтовые.
Начнем с получения журналов с почтового сервера и их подготовку к передаче ELK.
Так получилось, что в моей сети в качестве внутреннего почтового сервера используется Microsoft Exchange 2003. Каким-то неведомым мне образом, раз в сутки в почту падает файл с архивом почтового журнала сервера за предыдущий день. Мы пытались настоять на том, чтобы журналы отправлялись по протоколу syslog c помощью snare, но в этом было отказано под "уважительным" предлогом "высокой чувствительности пользователей к минимальным задержкам в работе сервиса".
Сначала письмо, как и множество других, проходит через procmail. Оно попадает под действие правила:
 :0:  
 * ^Subject(.*Exchange log file*)  
 {  
   :0 Bcw  
   | /home/sa/bin/logs/ExtractAttachment.pl  
   :0 a  
   | /home/sa/bin/logs/ImportMaillog.pl  
   :0  
   inbox/mailstat/.  
 }  

Скрипт "/home/sa/bin/logs/ExtractAttachment.pl" является вариантом этого скрипта.
За скрипт "home/sa/bin/logs/ImportMaillog.pl" не судите строго. Он писался в режиме "быстрее хоть что-нибудь" и сейчас исправлять его не хочется, потому-что "работает!".
 use strict;  
 use Encode qw(decode);  
 use Time::Local;  
 use Sys::Syslog;  
 use open qw(:std :utf8);  
 my $configfile = "/home/sa/bin/logs/rcfile";  
 my $conf = new Config::General("$configfile");  
 my %config = $conf->getall;  
 open (FILE, "<:encoding(utf8)", "/tmp/maillog.tmp") or die "Can't open file /tmp/maillog.tmp!\n";  
 open (OFILE, ">/tmp/maillog") or die "unable to open /tmp/maillog !";  
 openlog("Secure_Maillog", "ndelay", "local0");  
 while (<FILE>) {  
   s/\<\>/postmaster\@udmurtneft.ru/g;  
   my @str = split(/\t/);  
   my $str18 = "";  
   if ( $str[8] =~ /102[80]/ ) {  
      if ( $str[18] =~ /=?/ ) {  
        $str[18] =~ s/UNICODE-1-1-UTF-8/UTF-8/g;  
        $str[18] =~ s/unicode-1-1-utf-7/UTF-8/g;  
        $str[18] =~ s/x-user-defined/UTF-8/g;  
        $str[18] =~ s/gb18030/windows-1251/g;  
        $str[18] =~ s/window-1251/windows-1251/g;  
        $str[18] =~ s/UNKNOWN/windows-1251/g;  
        $str[18] =~ s/134/windows-1251/g;  
        my $flag = utf8::is_utf8($str[18]);  
           $str[18] = Encode::decode('MIME-Header',$str[18]);  
           $str18 = $str[18];  
      }  
      $str[1] =~ s/ GMT//g;  
      my $time = $str[0]." ".$str[1];  
      my @t = ($time =~ /^(\d{4})-(\d{1,2})-(\d{1,2})\s(\d{1,2}):(\d{1,2}):(\d{1,2})/);  
      $t[1]--; $t[3] = $t[3]+4;  
      if ( $t[3] > 23 ) { $t[3] = $t[3] - 24 };  
      my $timestamp = timelocal 0,@t[4,3,2,1,0];  
      print OFILE "\t$timestamp\t$str[19]\t$str[7]\t$str[12]\t$str[18] \n";  
      syslog('mail|info', $timestamp."\t".$str[19]."\t".$str[7]."\t".$str[12]."\t".$str[18]);  
   }  
 }  
 closelog();  
 close(OFILE);  
 system("mysqlimport --local logs /tmp/maillog --user=$config{db}->{user} --password=$config{db}->{password}");  
 unlink("/tmp/maillog.tmp");  
 unlink("/tmp/maillog");  
 unlink("/tmp/report.zip");  
Важные строки выделены жирным. Первая из них передает строку журнала в syslog, а оттуда в logstash. Вторая записывает в олдскульный sql для тяжелого анализа.
В следующий раз, чтобы разбавить тему анализа глазами. рассмотрим что можно достать из SQL.
PS. Если вы захотите отметить, что хранить временные файлы в общей директории /tmp не безопасно, то ответа будет два:
1. На сервере, куда падают журналы, все пользователи имеют доступ к ним.
2.
 $ cat /etc/profile | grep umask  
 umask 077  

Friday, October 17, 2014

Осторожно, серпантин или особенность систем BigData.

Elasticsearch - замечательный продукт, который дарит нам не только удовольствие от пользования качественным ПО, но и ощущение скоростной езды по горной дороге. Вираж, запрос - ответ. Перевал, фильтр - выборка
А скорость?! В mysql выборка по одной учетной записи за сутки, с целью посчитать с каких же сайтов человек накачал больше всего байтов занимало 30-40 секунд. А тут суточная выборка по всем сотрудникам, с определением байтового ТОРа и пяток других запросов выполняются менее чем за секунду! Вот оно "счастие аналитика".
Но не все на СТОЛЬКО хорошо. Особенностью работы с большими данными, а ES позиционирует себя как продукт для обработки больших массивов информации, является снижение точности.
Давайте не будем падать в дебри 100% корректного описания внутренней кухни ES, а упростим описание в угоду пониманию. Кому нужны детали, добро пожаловать на сайт производителя. Все-равно лучше его не скажешь.
Итак. ES видит много-много (именно "много", а не 1478) запросов от пользователя Иванов на сайт www.ru. Все запросы примерно одинаковы (положим javasctipt резвится) и более-менее регулярны.
И тут, неожиданно для всех, аналитик Петров спрашивает - скажи ка мне, дорогой Elastic, а сколько раз сотрудник Иванов обращался к сайту www.ru. У ES нет времени на раздумья, ведь главное ответить быстро, чтобы Петров не успел забыть вопрос. Поэтому ES смотрит, что Иванов обращался к www.ru в 1й, 10й и 20 часы примерно 60 раз в час, значит за сутки он сделал около 1440 обращений. Эта цифра и летит на экран. Примерно 1440, нужно держать в голове аналитику Петрову.
Хорошо, отвечает ошалевший от скорости ответа Петров, а сколько байтов сотрудник Иванов выдернул с сайта www.ru? И практически мгновенно получает ответ 288000. Замечательно! Тем более, что это почти соответствует точной цифре, то есть примерно 288000. А ES просто умножил 1440 на средний размер ответа сервера равный 200 байтам, который опять рассчитал по быстрому.
Все довольны, Петров отходит ко сну. Занавес.
"Да ладно", скажете вы, "выдумываешь тут какую-то чушь! Я по калькулятору считал. Байты почти сошлись".
"Здорово", отвечу я, "только не всегда прогнозы и усреднения оказываются верными". Посмотрите на картинку ниже.

Утренний анализ за чашечкой кофе показал, что пользователь serg вытянул из Интернета за последние сутки примерно 221 мегабайт. Ну-ка глянем, чего это он вчера был таким вялым?
И видим, что цифра меняется в 1.5 раза! Все в шоке. Как так?
Оказывается - сменился контекст выборки и алгоритмы усреднения дали новый результат, который, кстати говоря, сильно ближе к реальному. Это и есть особенность работы с большими данными или цена скоростной выборки.
Мораль - будьте осторожны на горной серпантине и он подарит вам множество отличных видов.

Thursday, October 16, 2014

Анализ журналов прокси. Продолжение

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

Классика:«кто больше съел»
Тут все просто. В панели «Down by user» (это не оскорбление. слово download не влезло в панель) выбираем верхних пользователей, щелкаем на изображении лупы и анализируем
Причем, что удобно, мы на одном экране видим:
  1. Человечек смотрел видео с youtube;
  2. Человечек начал это делать в обед (12-13);
  3. Человечек не смог остановиться, когда обед закончился.
Можно проанализировать, что он смотрел, сопоставить это с журналами работы с информационными ресурсами, но этим сегодня заниматься не будем. Классика!
Классика «слабое звено»
Допустим, мы хотим посмотреть, кто ищет себе работу? Добавляем запрос «urihost: *job* or *rabota* or hh.ru» и наблюдаем кандидатов на анализ. Благодаря панели «Upload max» можно даже отловить момент выкладывания резюме.
В момент написания поста ничего интересного не происходило, поэтому просто посмотрите, что в обед люди не только отдыхают, но и занимаются серфингом по сайтам навевающим грусть на HR.
Стандартный «кто послал»
Вы, наверное, уже обратили внимание на панельку «Upload max» справа от панели запросов. Эта панель показывает размеры индивидуальных отправок данных через прокси-сервер. То есть на ней визуально мы можем выявить нарушения связанные с отправкой наружу информации. Таблично это делать не очень удобно
Смотрим, как у нас дела были в последние 12 часов.
Ага, видим 12 мегабайтную отправку. Уменьшаем время, за которое проводится анализ, так как количество событий в секунду превышает 50.
Уточняем. Фильтруем по пользователю и затем по имени сайта
И вот мы видим, кто отправил информацию и куда. К счастью это штатная отправка на сайт закупок, на анализ которой потребовалось несколько секунд.
Стандартный «масс-контакт»
Случилось некоторое время назад такое, что корпорация добра несколько усовершенствовала свой браузер, в результате чего в нем как-то особенно выделился функционал чата. В результате на прокси обрушился шквал запросов на соединение с IM-сервером, которые отклонялись. Это не есть хорошо.
Чтобы продемонстрировать работу по анализу, пришлось отключить фильтрацию отклоненных запросов (TCP_DENIED). В результате наблюдаем сайт требующий нашего внимания – urs.microsoft.com. Он не связан с IM, описанным в предыдущем абзаце, но для примера пойдет.
Продвинутый «ratio»К сожалению, такой вид анализа на ELK мне пока не удалось реализовать. Его идея в том, чтобы делать расчет соотношения информации отправленной на сайт к принятой. Этот способ анализа позволяет выявлять туннели и сайты-интерфейсы к IM, например. Делается все на сегодня запросом из SQL, где журналы так же хранятся. Нужно сохранить немного брутальности.
Продвинутый «reputation»
Это из раздела помечтать. Идея – дергать из репутационных баз информацию о доверии сайтам и выводить информацию на экран анализа. Идея навеяна плагином WOT для браузеров.

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

Wednesday, October 15, 2014

Анализ журналов прокси

Так получилось, что отдел, в котором я работаю, в основном состоит из сотрудников правоохранительных органов, представления о защите информации у которых отличаются от моих. В частности, одним из основных показателей благополучия в информационной системе является «правильное» использование сотрудниками ресурсов сети Интернет. «Правильное» можно расшифровать как мало и редко. И, так как проверки по этим критериям достаточно просто организовать, отчет по результатам мониторинга работы пользователей в сети Интернет становится одним из ключевых в работе отдела.
Как собирать журналы, описано многократно и много где.
Давайте поподробнее рассмотрим, как их анализировать, чтобы покрыть нужды коллег пришедших в коммерческую безопасность из органов и решить свои задачи.
Есть брутальный способ, для настоящих мужиков, через запись журналов в какой-нибудь SQL и запросы к нему из командной строки в стиле:

select id, from_unixtime(time), r_host, inet_ntoa(r_ip), r_port, sum(sc_bytes) from proxylog where time > (UNIX_TIMESTAMP() - 86400*2) and cs_username like 'ХХХ' group by r_host order by sum(sc_bytes);

Используя его, мы можем быть уверенными, что анализ журналов не сможет сделать никто кроме нас. Это по-своему круто и дает нам определенный авторитет.
Но давайте повернемся лицом к коллегам и используем стандартную на сегодня связку Logstash-Elasticsearch-Kibana (ELK в английском просторечии) для анализа журналов. Вероятно, есть более оптимальные решения, но они потребуют больше времени на настройку и тюнинг. Итак…


ELK мне было удобно поставить на Debian. Правильный "Debian way" описан на этой страничке.

Squid:
Журналы Squid падают в Logstash. Способы выбирайте сами, они описаны во многих местах.
Пара особенностей. По подсказке коллеги из головной конторы, в журнал был добавлен заголовок referrer, а по моей инициативе - количество отправленных байт. В результате директива logformat выглядит так:

%ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt %>st %{Referer}>h


Logstash:
Чтобы падающие сообщения были нормализованы, то есть из потока символов была извлечена информация, используем вот такую конструкцию:


else if [message] =~ "(squid)" {
mutate { replace => { "type" => "squid-access" } }
grok {
match => ["message", "<14>%{SYSLOGTIMESTAMP}\s+%{SYSLOGHOST:sourcehost}\s+\(%{WORD:syslogprog}\):\s+%{NUMBER:timestamp}\s+%{NUMBER:request_msec}\s+%{IPORHOST:client}\s+%{WORD:cache_result}/%{NUMBER:status}\s+%{NUMBER:size:int}\s+%{WORD:http_type}\s+(%{URIPROTO}://)?(?:%{USER}(?::[^@]*)?@)?(?:%{URIHOST:urihost})?(?:%{URIPATHPARAM})?\s+(%{WORD:username}|-)\s+%{WORD:request_route}/(%{IPORHOST:forwarded_to}|-)\s+%{NOTSPACE:content_type}
\s+%{NUMBER:send_size:int}\s+(%{URI:referer}|-)"]
}
}


Тут и мне, написавшему этот жуткий regexp, мало что понятно с ходу, но когда будете настраивать logstash разберетесь что к чему - выбора не будет.
ElasticSearch:
Прелесть этой "не базы данных" в том, что все в ней хранится как-то. Поля, индексы, типы - все это появится в момент, когда вы решите заняться оптимизацией или добиться каких-то расширенных возможностей. Что происходит внутри связки ELK нам не важно. На вход мы подаем поток текста, на выходе получаем "кузявые" таблички и графики.
Kibana:
Статей по настройке интерфейса Kibana великое множество. Мне показалось, что эффективнее всего ставить себе какую-то задачу и искать механизм реализации задачи в ограничениях данного нам средства.
В результате для анализа журналов прокси сервера получился такой интерфейс
Панельки пришлось сделать поменьше, чтобы они все помещались на монитор одновременно. Поэтому по всем параметрам показывает TOP5. Чаще всего этого достаточно. Больше чем на 1-2 "нарушителей" в день нет времени.
Схему можно скачать здесь.

Основные способы применения решения рассмотрим в следующий раз.