Este script Python fornece funções para analisar diferentes tipos de logs: logs de URL, logs de firewall e logs de eventos. Cada função usa expressões regulares para extrair informações relevantes de uma entrada de log e retorna um dicionário com os dados analisados.
O servidor Syslog foi configurado seguindo o guia aqui: https://documentation.meraki.com/General_Administration/Monitoring_and_Reporting/Syslog_Server_Overview_and_Configuration
Amostras do Meraki Syslog podem ser encontradas aqui: https://documentation.meraki.com/General_Administration/Monitoring_and_Reporting/Syslog_Event_Types_and_Log_Samples
Eu criei este script simples para raspar os 100 principais sites. Você pode rodar em uma máquina atrás do Meraki MX e isso gerará muito Syslog.
https://github.com/repenno/top_100
Desenvolvi este script para analisar Syslogs em objetos JSON e inserir em um VectorDB que suporta consultas de escala de tempo.
Eu uso Langchain e OpenAI para criar chatbots sob demanda para incidentes de segurança e pesquisar insights sobre eventos de networking.
parse_url_log(log_entry: str) -> dict
: analisa logs de URL.parse_firewall_log(log_entry: str) -> dict
: analisa logs de firewall.parse_event_log(log_entry: str) -> dict
: analisa logs de eventos. Vamos analisar as expressões regulares usadas no script:
Método parse_url_log:
O padrão de expressão regular usado neste método foi projetado para corresponder às entradas de log de URL. Aqui está uma análise do padrão:
(?P<date>w{3}s+d{1,2}s+d{2}:d{2}:d{2})
: Esta parte do padrão corresponde à data. w{3}
corresponde a qualquer caractere de palavra (igual a [a-zA-Z0-9_]) exatamente 3 vezes, o que corresponde à abreviatura de três letras do dia da semana (segunda, terça, etc.). s+
corresponde a qualquer caractere de espaço em branco (espaços, tabulações, quebras de linha) uma ou mais vezes. d{1,2}
corresponde a qualquer dígito (igual a [0-9]) entre 1 e 2 vezes, o que corresponde ao dia do mês (1-31). d{2}:d{2}:d{2}
corresponde à hora no formato HH:MM:SS.
(?P<ip>d{1,3}.d{1,3}.d{1,3}.d{1,3})
: Esta parte do padrão corresponde a um IP endereço. d{1,3}
corresponde a qualquer dígito entre 1 e 3 vezes, o que corresponde a cada octeto de um endereço IP (0-255). O .
corresponde a um ponto literal.
(?P<id>d+.d+)
: Esta parte do padrão corresponde a um ID que consiste em um ou mais dígitos, um ponto e um ou mais dígitos.
(?P<user>w+)
: Esta parte do padrão corresponde a um nome de usuário que consiste em um ou mais caracteres de palavra.
(?P<type>w+)
: Esta parte do padrão corresponde a um tipo que consiste em um ou mais caracteres de palavra.
src=(?P<src>d{1,3}.d{1,3}.d{1,3}.d{1,3}:d+)
: Esta parte de o padrão corresponde a um endereço IP e porta de origem. A estrutura é semelhante ao padrão de endereço IP acima, mas com :d+
no final para corresponder ao número da porta.
dst=(?P<dst>d{1,3}.d{1,3}.d{1,3}.d{1,3}:d+)
: Esta parte de o padrão corresponde a um endereço IP e porta de destino. A estrutura é semelhante ao endereço IP de origem e ao padrão de porta acima.
mac=(?P<mac>[0-9A-Fa-f:]{17})
: esta parte do padrão corresponde a um endereço MAC. [0-9A-Fa-f:]
corresponde a qualquer dígito ou letra de A a F (maiúscula ou minúscula) ou dois pontos. {17}
especifica que esse padrão deve ter exatamente 17 caracteres para corresponder a um formato de endereço MAC.
agent='(?P<agent>.+?)'
: Esta parte do padrão corresponde a uma string de agente do usuário entre aspas simples.
request:s+(?P<request>w+s+w+://.+)
: esta parte do padrão corresponde a um método de solicitação e URL.
Método parse_firewall_log:
O padrão de expressão regular usado neste método foi projetado para corresponder às entradas de log do firewall. É semelhante ao padrão de entrada de log de URL, mas inclui campos adicionais específicos para logs de firewall, como protocolo, esporte (porta de origem), dport (porta de destino) e padrão.
Método parse_event_log:
O padrão de expressão regular usado neste método foi projetado para corresponder às entradas do log de eventos. É semelhante aos padrões anteriores, mas inclui campos adicionais específicos para logs de eventos, como event_type, url, categoria (opcional), server e client_mac.
Cada grupo nesses padrões é nomeado usando ?P<name>
, o que facilita a extração de informações específicas de uma entrada de log.
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 )
A saída de cada função é um dicionário com os dados analisados da entrada de 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' }
Este script requer o módulo re
integrado do Python para expressões regulares.
Solicitações pull são bem-vindas! Para mudanças importantes, abra primeiro uma edição para discutir o que você gostaria de mudar.