понедельник, 25 марта 2019 г.

Splunk. Powershell. Автоматизация рутины

Приветствую, уважаемый читатель!

Хотел бы рассказать про решение следующей задачи: автоматизированный контроль работоспособности белого списка сайтов на межсетевом экране. Казалось бы, простая задача, но и у неё есть свои нюансы.





Задача может быть сформулирована следующая, обеспечить работоспособность некоторого количества разрешенных сайтов (например, 100 сайтов) через L4 межсетевой экран, а остальной доступ в сеть Интернет отключить.

Основная сложность заключается в том, что L4 межсетевые экраны умеют оперировать IP-адресами и номерами TCP/UDP-портов. Соответственно, для обеспечения нормальной работоспособности необходимо с определенной периодичностью резолвить доменные имена 100 сайтов в IP-адреса и контролировать их изменения.

Как-то упростить себе жизнь можно реализацией следующего алгоритма:
  1. Каждый день с помощью скрипта резолвить необходимые доменные имена и сохранять их в каком-либо виде (средство реализации - PowerShell).
  2. Отправлять полученные IP-адреса в SIEM для дальнейшего анализа (средство реализации - PowerShell).
  3. Осуществлять сравнение IP-адресов для каждого домена между собой с целью поиска изменений (средство реализации - Splunk).
  4. Отправка администратору оповещения о найденных изменениях (средство реализации - Splunk).


Далее реализация по пунктам



1. В PowerShell для преобразования доменных имен существует специальный командлет - Resolve-DnsName. Необходимо учитывать, что для одного домена может отрезолвиться несколько IP-адресов и их все нужно учесть. Скрипт ниже берет список доменных имен из файла и сохраняет в коллекцию результаты работы командлета Resolve-DnsName.


$time = (Get-Date).ToString("dd:MM:yy")
$array=@()

foreach ($DNSName in (Get-Content "C:\White\IP.txt")) {
    $IPs = Resolve-DnsName -Type A -Name $DNSName | select Name,IP4Address
    foreach ($IP in $IPs) {
        $obj = New-Object psobject
        $obj | Add-Member -Type NoteProperty -Name SDNAME -Value $DNSName
        $obj | Add-Member -Type NoteProperty -Name Domain -Value $IP.Name
        $obj | Add-Member -Type NoteProperty -Name IP -Value $IP.IP4Address
        $array+=$obj
    }
}



2. Отправить результаты в Splunk можно в формате JSON, через HTTP-event коллектор.




foreach($white_ip in $array) {

    if ($white_ip.IP -match '\d{1,3}.\d{1,3}') {
        $s_SDNAME = $white_ip.SDNAME
        $s_Domain = $white_ip.Domain
        $s_IP = $white_ip.IP


$JSONDoc = @"
{
"sourcetype":"whiteIP",
"event":{
"Collect_time":"$time",
"Source DNS":"$s_SDNAME",
"Domain":"$s_Domain",
"IP":"$s_IP"}
}
"@

$JSONDoc
Invoke-WebRequest -uri "http://10.10.10.5:8088/services/collector/event" -Headers @{"Authorization"="Splunk 6C658085-9B72-4659-84CC-D095FFD1DF6C"} -Method POST -Body $JSONDoc
}

} 


3. Эта часть самая важная. SPL-запрос состоит из 2-х частей, первая часть (до join) получает для каждого домена список его сегодняшних IP-адресов, а вторая часть запроса (после join) получает для каждого домена список его вчерашних IP-адресов. Если произошло изменение, то в новое поле IP_change проставляется «1».


sourcetype=WhiteIP
| eval now_t=strftime(now(),"%d:%m:%y")
| where (now_t = Collect_time)
| sort IP
| mvcombine IP
| eval IP_today=mvjoin(IP,",")
| join type=left Domain [search sourcetype=WhiteIP
| eval now_t=strftime((relative_time(now(),"-1d@d")),"%d:%m:%y")
| where (now_t = Collect_time)
| sort IP
| mvcombine IP
| eval IP_yesterday=mvjoin(IP,",")
| table now_t,Collect_time,Domain,IP_yesterday,"Source DNS"]
| eval IP_change=if((IP_today=IP_yesterday),"0","1")
| where (IP_change="1")
| table Domain,IP_today,IP_yesterday,IP_change,"Source DNS"


Для сравнения используется следующий алгоритм: IP-адреса для каждого домена из первой и второй части запроса сортируются, и с использованием операторов mvcombine и mvjoin соединяются через “,” в обычную строку.

Т.е. события из такого вида:


преобразуются в такой:


Естественно, данные строки можно легко сравнить между собой через eval, и на выходе получаем такой результат:



Как видно из скриншота набор IP-адресов для домена ocsp.int-x3.letsencrypt.org за сутки изменился и на это стоит обратить внимание.



4. Один из самых простых способов отправить оповещение администратору – использование оператора sendemail. Учитывая, что оповещения необходимо слать каждый день, то нужно создать savedsearch-запрос и выполнять его по расписанию (рассказывал тут - http://unitybas.blogspot.com/2018/06/splunk-savedsearch.html).


| sendemail to="user@domain.ru" from=IPChecker@domain server=mx.domain.ru subject="White List IP" message="IP change:" inline=True sendresults=true format=table


Ниже пример письма-оповещения: 


Как-то так  J



Комментариев нет:

Отправить комментарий