Этот скрипт Python предоставляет функции для анализа различных типов журналов: журналов URL-адресов, журналов брандмауэра и журналов событий. Каждая функция использует регулярные выражения для извлечения соответствующей информации из записи журнала и возвращает словарь с проанализированными данными.
Сервер системного журнала был настроен в соответствии с руководством здесь: https://documentation.meraki.com/General_Administration/Monitoring_and_Reporting/Syslog_Server_Overview_and_Configuration.
Образцы системного журнала Meraki можно найти здесь: https://documentation.meraki.com/General_Administration/Monitoring_and_Reporting/Syslog_Event_Types_and_Log_Samples.
Я создал этот простой скрипт для парсинга 100 лучших веб-сайтов. Вы можете работать на машине с Meraki MX, и она будет генерировать много системных журналов.
https://github.com/repenno/top_100
Я разработал этот сценарий для анализа системных журналов в объекты JSON и вставки в базу данных VectorDB, поддерживающую запросы шкалы времени.
Я использую Langchain и OpenAI для создания чат-ботов по запросу для реагирования на инциденты безопасности и исследования сетевых событий.
parse_url_log(log_entry: str) -> dict
: анализирует журналы URL.parse_firewall_log(log_entry: str) -> dict
: анализирует журналы брандмауэра.parse_event_log(log_entry: str) -> dict
: анализирует журналы событий. Давайте разберем регулярные выражения, используемые в скрипте:
метод parse_url_log:
Шаблон регулярного выражения, используемый в этом методе, предназначен для сопоставления записей журнала URL-адресов. Вот разбивка шаблона:
(?P<date>w{3}s+d{1,2}s+d{2}:d{2}:d{2})
: эта часть шаблона соответствует дате. w{3}
соответствует любому символу слова (равному [a-zA-Z0-9_]) ровно 3 раза, что соответствует трехбуквенному сокращению дня недели (понедельник, вторник и т. д.). s+
соответствует любому пробельному символу (пробелу, табуляции, разрыву строки) один или несколько раз. d{1,2}
соответствует любой цифре (равной [0–9]) от 1 до 2 раз, что соответствует дню месяца (1–31). d{2}:d{2}:d{2}
соответствует времени в формате ЧЧ:ММ:СС.
(?P<ip>d{1,3}.d{1,3}.d{1,3}.d{1,3})
: Эта часть шаблона соответствует IP-адресу. адрес. d{1,3}
соответствует любой цифре от 1 до 3 раз, что соответствует каждому октету IP-адреса (0–255). .
соответствует буквальной точке.
(?P<id>d+.d+)
: эта часть шаблона соответствует идентификатору, состоящему из одной или нескольких цифр, точки и одной или нескольких цифр.
(?P<user>w+)
: эта часть шаблона соответствует имени пользователя, состоящему из одного или нескольких словесных символов.
(?P<type>w+)
: эта часть шаблона соответствует типу, состоящему из одного или нескольких словесных символов.
src=(?P<src>d{1,3}.d{1,3}.d{1,3}.d{1,3}:d+)
: Эта часть шаблон соответствует исходному IP-адресу и порту. Структура аналогична приведенному выше шаблону IP-адреса, но с :d+
в конце, чтобы соответствовать номеру порта.
dst=(?P<dst>d{1,3}.d{1,3}.d{1,3}.d{1,3}:d+)
: Эта часть шаблон соответствует IP-адресу и порту назначения. Структура аналогична исходному IP-адресу и шаблону портов, приведенным выше.
mac=(?P<mac>[0-9A-Fa-f:]{17})
: эта часть шаблона соответствует MAC-адресу. [0-9A-Fa-f:]
соответствует любой цифре или букве от A до F (в верхнем или нижнем регистре) или двоеточию. {17}
указывает, что длина этого шаблона должна составлять ровно 17 символов, чтобы соответствовать формату MAC-адреса.
agent='(?P<agent>.+?)'
: эта часть шаблона соответствует строке пользовательского агента, заключенной в одинарные кавычки.
request:s+(?P<request>w+s+w+://.+)
: эта часть шаблона соответствует методу запроса и URL-адресу.
метод parse_firewall_log:
Шаблон регулярного выражения, используемый в этом методе, предназначен для сопоставления записей журнала брандмауэра. Он похож на шаблон записи журнала URL-адреса, но включает дополнительные поля, характерные для журналов брандмауэра, такие как протокол, спорт (порт-источник), dport (порт назначения) и шаблон.
метод parse_event_log:
Шаблон регулярного выражения, используемый в этом методе, предназначен для сопоставления записей журнала событий. Он похож на предыдущие шаблоны, но включает дополнительные поля, специфичные для журналов событий, такие как event_type, URL-адрес, категория (необязательно), сервер и client_mac.
Каждая группа в этих шаблонах называется с помощью ?P<name>
, что упрощает извлечение определенных фрагментов информации из записи журнала.
fw_log_entry = "Oct 2 21:22:43 192.168.128.1 1 1696306963.825147405 satosugu firewall src=fe80::cde:941e:d4ef:3d22 dst=ff02::fb protocol=udp sport=5353 dport=5353 pattern: 1 all"
parsed_log = MerakiMXSyslogParser . parse_firewall_log ( fw_log_entry )
print ( parsed_log )
url_log_entry = "Oct 2 21:18:42 192.168.128.1 1 1696306722.864107379 satosugu urls src=192.168.128.3:58754 dst=192.229.211.108:80 mac=0C:4D:E9:BE:F4:B2 agent='Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0' request: POST http://ocsp.digicert.com/"
parsed_log = MerakiMXSyslogParser . parse_url_log ( url_log_entry )
print ( parsed_log )
event_log_entry = "Oct 2 21:09:28 192.168.128.1 1 1696306168.009553886 satosugu events content_filtering_block url='https://youtube.com/...' category0='User-defined Blacklist' server='192.178.50.78:443' client_mac='0C:4D:E9:BE:F4:B2'"
parsed_log = MerakiMXSyslogParser . parse_event_log ( event_log_entry )
print ( parsed_log )
event_log_entry = "Oct 2 21:12:00 192.168.128.1 1 1696306320.822027826 satosugu events content_filtering_block url='https://xvideos.com/...' server='185.88.181.2:443' client_mac='0C:4D:E9:BE:F4:B2'"
parsed_log = MerakiMXSyslogParser . parse_event_log ( event_log_entry )
print ( parsed_log )
Выходные данные каждой функции представляют собой словарь с проанализированными данными из записи журнала.
{ 'date' : 'Oct 2 21:22:43' , 'ip' : '192.168.128.1' , 'id' : '1696306963.825147405' , 'user' : 'satosugu' , 'type' : 'firewall' , 'src' : 'fe80::cde:941e:d4ef:3d22' , 'dst' : 'ff02::fb' , 'protocol' : 'udp' , 'sport' : '5353' , 'dport' : '5353' , 'pattern' : '1 all' }
{ 'date' : 'Oct 2 21:18:42' , 'ip' : '192.168.128.1' , 'id' : '1696306722.864107379' , 'user' : 'satosugu' , 'type' : 'urls' , 'src' : '192.168.128.3:58754' , 'dst' : '192.229.211.108:80' , 'mac' : '0C:4D:E9:BE:F4:B2' , 'agent' : 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0' , 'request' : 'POST http://ocsp.digicert.com/' }
{ 'date' : 'Oct 2 21:09:28' , 'ip' : '192.168.128.1' , 'id' : '1696306168.009553886' , 'user' : 'satosugu' , 'type' : 'events' , 'event_type' : 'content_filtering_block' , 'url' : 'https://youtube.com/...' , 'category' : 'User-defined Blacklist' , 'server' : '192.178.50.78:443' , 'client_mac' : '0C:4D:E9:BE:F4:B2' }
{ 'date' : 'Oct 2 21:12:00' , 'ip' : '192.168.128.1' , 'id' : '1696306320.822027826' , 'user' : 'satosugu' , 'type' : 'events' , 'event_type' : 'content_filtering_block' , 'url' : 'https://xvideos.com/...' , 'category' : None , 'server' : '185.88.181.2:443' , 'client_mac' : '0C:4D:E9:BE:F4:B2' }
Для этого сценария требуется встроенный модуль re
Python для регулярных выражений.
Запросы на вытягивание приветствуются! Если вы хотите внести существенные изменения, пожалуйста, сначала откройте вопрос, чтобы обсудить, что вы хотели бы изменить.