De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.


Gráficos estatísticos de vírus

Colaboração: Fabiano Caixeta Duarte

Data de Publicação: 25 de Outubro de 2005

Há quem goste de um bom conjunto de gráficos estatísticos para acompanhar o trabalho de seus servidores. Vamos aqui mostrar um exemplo de como acompanhar os vírus que estão sendo filtrados por um sistema anti-vírus acoplado a um servidor de e-mails.

O gráfico conterá um resumo mensal categorizado por vírus apontando a quantidade de vírus interceptados por dia.

O ambiente utilizado foi FreeBSD + Sendmail + ClamAV. Entretanto, com algumas poucas modificações, pode-se adequar o script apresentado a outros contextos.

A ferramenta utilizada para realizar a plotagem dos dados em gráficos (arquivos png) foi o GnuPlot.

A estratégia

As informações para composição dos gráficos são colhidas do log do servidor de e-mail.

No caso do sendmail+clamav, o servidor registra no log a ocorrência de um vírus com a seguinte expressão "Infected with <virus_name>".

  # grep Infected /var/log/maillog
  Sep 17 15:20:39 servidor sm-mta[85830]: j8HIKH3Z085830: Milter add: header: X-Virus-Status: Infected with Worm.SomeFool.AD

As informações relevantes para geração dos gráficos são dia e nome do vírus. Ou seja, só nos interessam as colunas 2 e 13.

  # grep Infected /var/log/maillog | awk '{print $2" "$13}'
  17 Worm.SomeFool.AD

No exemplo mostrado, demonstramos apenas um vírus capturado. Vamos mostrar agora um pequeno conjunto em que podemos observar a existência de mais de uma ocorrência de cada vírus na mesma data. É um conjunto de informações fictícias. Numa situação real a quantidade de vírus encontrados (infelizmente) é bem maior.

  # grep Infected /var/log/maillog | awk '{print $1" "$2" "$13}'
  17 HTML.Phishing.Bank-1
  17 Worm.SomeFool.P
  17 Exploit.HTML.IFrame
  17 Worm.SomeFool.P
  17 HTML.Phishing.Bank-1
  17 HTML.Phishing.Bank-1
  17 Worm.SomeFool.AD
  17 Worm.SomeFool.Gen-2

A estratégia é agrupar as ocorrências de cada vírus, contá-las e armazená-las em um arquivo que será lido pelo gnuplot. Na verdade, geramos um arquivo para cada vírus, possibilitando a plotagem das estatísticas de todos os vírus em um mesmo gráfico.

  # grep Infected /var/log/maillog |
         awk '{print $2" "$13}' |
         sort |                      # Ordena as ocorrências
         uniq -c \                   # Conta as ocorrências de cada vírus
   > $TMP                            # Armazena o resultado em um arquivo temporário
  # cat $TMP
       1 17 Exploit.HTML.IFrame
       3 17 HTML.Phishing.Bank-1
       1 17 Worm.SomeFool.AD
       1 17 Worm.SomeFool.Gen-2
       2 17 Worm.SomeFool.P

Para tornar o processo automático, optamos por armazenar os logs do servidor de e-mail agrupando-os por dia. Isto quer dizer que programamos o sistema para rotacionar os logs uma vez por dia. Assim, podemos filtrar as informações do dia anterior trabalhando sobre o arquivo /var/log/maillog.0.bz2.

O próximo passo é separar as informações em arquivos, cada um com o nome do vírus.

  while read count day virus; do
         echo $count $day >> $PLOTDIR/$virus
  done < $TMP

Com os arquivos montados, basta agora executar o gnuplot para plotar o gráfico. Não está no escopo desta dica detalhar o funcionamento do gnuplot (pode ser o conteúdo de outra dica).

O script

Segue a íntegra do script. Devemos agendar sua execução diária pelo cron, de forma que os gráficos sejam atualizados diariamente a partir das informações do log do dia anterior.

  #!/bin/bash
  
  # VirusGraphGen - Gerador de gráficos de Vírus
  # Desenvolvido por Fabiano Caixeta Duarte
  # Agosto / 2005
  
  # Capturar a data levando em consideração que a data base é o dia anterior.
  # Assim, evitamos problemas em fim de mês.
  LANG=en_US
  month=`date -v-1d +%b` # Em Linux: substituir "-v-1d" por "1 day ago"
  LANG=pt_BR.ISO8859-1
  MES=`date -v-1d +%B`
  ANO=`date -v-1d +%Y`
  
  # Criação das variáveis globais
  THIS=`basename $0`
  WORKDIR=/var/run/${THIS}
  TMP=$WORKDIR/$$
  PLOTFILE=$WORKDIR/virus.plot
  PLOTDIR=$WORKDIR/$month
  GRAPHDIR=/var/www/data/images
  
  # Garantir a existência dos diretórios de trabalho
  mkdir -p $WORKDIR
  mkdir -p $PLOTDIR
  
  # Filtrar as linhas de alerta de vírus
  bzgrep Infected /var/log/maillog.0.bz2 |
         awk '{print $2" "$13}' |
         sort |
         uniq -c > $TMP
  
  # Separar os vírus e acrescentar aos arquivos já existentes.
  # Assim, em cada arquivos teremos um acompanhamento diário dos vírus filtrados
  while read count day virus; do
         echo $count $day >> $PLOTDIR/$virus
  done < $TMP
  
  #Construindo a linha de múltipla plotagem. O nome do vírus é usado como legenda.
  PLOTLINE="plot "
  for i in `ls $PLOTDIR`; do
         PLOTLINE="$PLOTLINE '$i' u 2:1 t '$i',"
  done
  PLOTLINE=${PLOTLINE%,*} # Retirar vírgula do fim da linha
  
  #Construção do arquivo de plotagem a ser usado pelo gnuplot
  cat << EOF > $PLOTFILE
  set term png
  set out "$GRAPHDIR/virus-${month}.png"
  set title "Virus do mes de $MES/$ANO"
  set key below
  set style data lines
  set xlabel "Dia do mes"
  set ylabel "Nr de Ocorrencias"
  set xrange [1:31] writeback
  set yrange [0:15]
  set xtics 1
  cd '$PLOTDIR'
  $PLOTLINE
  EOF
  
  # Ufa, enfim o gráfico :)
  /usr/local/bin/gnuplot $PLOTFILE
  
  # Tchau arquivos temporários. Obrigado por sua contribuição :)
  rm -R $TMP $PLOTFILE
  

Referências

Error: No site found with the domain 's2.dicas-l.com.br' (Learn more)