аукцион / donate / услуги / RSS / распечатать / вход 
Мой мир
Вконтакте
Одноклассники

[17 февраля 2021 | 24 февраля 2021 | 1 марта 2021]

NetFlow v5 Python (часть 3) коллектор

Самописный коллектор для Netflow написанный на Python уже готов. Я пишу на третьей версии Python, по этому проблем с совместимостью с современными системами не должно возникнуть. В боевом режиме он используется на Windows, но он так же параллельно работает на Linux дистрибутивах. Если у вас возникнут проблемы, то можете обращаться ко мне, при наличии свободного времени могу оказать посильную помощь.

Логика действий у него такая. Приходящий набор разбирается по пакетам. В среднем их 30 штук в одном наборе. После их разбора они записываются в файл в бинарном виде. От текстового формата я отказался, так как он занимает слишком много места и при обработке тратится больше времени. Я так же планирую записывать в базу данных в бинарном виде, так как — это не только экономит место, но и ускоряет работу SQL-сервера. Ни для кого не секрет, что сравнивать целые числа быстрее чем строки. А уже потом можно привести к читаемому виду. Тем более, что в Python и PHP есть инструменты для конвертации из четырёхбайтового представления и обратно. Учитывая, что на уровне коллектора и анализатора нет потребности манипулировать с IP-адресами, то потребуется только работа на PHP. Например, для получения четырёхбайтового представления из строки можно использовать функцию int ip2long(string ip_address);, а для получения строки из четырёхбайтового представления можно использовать функцию string long2ip(int proper_address);.

Текущий текст коллектора теперь выглядит вот так:

#!/usr/bin/python3
# -*- Mode: Python; tab-width: 4 -*-
#       Id: collector.py, v 1.11 2021
#       Author: Ivan Kurilko 
#       https://orcinus.ru
# ======================================================================
# Copyright 2020 by Ivan Kurilko aka Orcinus Orca
#
#                         All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby
# granted, provided that the above copyright notice appear in all
# copies and that both that copyright notice and this permission
# notice appear in supporting documentation, and that the name of Ivan
# Kurilko not be used in advertising or publicity pertaining to
# distribution of the software without specific, written prior
# permission.
#
# IVAN KURILKO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
# NO EVENT SHALL IVAN KURILKO BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# ======================================================================

import socket, struct

SIZE_OF_HEADER = 24
SIZE_OF_RECORD = 48


sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('0.0.0.0', 9996))

while True:
   buf, addr = sock.recvfrom(1500)

   (version, count) = struct.unpack('!HH',buf[0:4])

   if version != 5:
      print ('Incorrect version!')
      continue

   if count <= 0 or count > 30:
      print ('Invalid count %s' % count)
      continue
   (sys_uptime, unix_secs, unix_nsecs, flow_sequence) = struct.unpack('!IIII',buf[4:20])
   starttime = unix_secs-sys_uptime//1000
   iprouter = struct.unpack('!I', socket.inet_aton(addr[0]))[0]
   write_packet = b''
   write_error = ''

   for i in range(0, count):
      try:
         
         outpacket = struct.pack('!I', iprouter)
         outpacket += struct.pack('!I', flow_sequence+i)
         outpacket += struct.pack('!I', startpkt)

         outpacket += struct.pack('!I', srcaddr)
         outpacket += struct.pack('!B', src_mask)
         outpacket += struct.pack('!H', srcport)
         outpacket += struct.pack('!H', if_input)

         outpacket += struct.pack('!I', dstaddr)
         outpacket += struct.pack('!B', dst_mask)
         outpacket += struct.pack('!H', dstport)
         outpacket += struct.pack('!H', if_output)
         outpacket += struct.pack('!H', dpkts)
         outpacket += struct.pack('!H', doсtets)
         outpacket += struct.pack('!B', prot)
         if len(outpacket) == 35: write_packet += outpacket

      except:
         continue

   file_name = 'netflow'
   with open(file_name+'.bin', 'ab') as file:
      file.write(write_packet)
      file.close()

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

Один из вариантов модификации, которые я могу предложить — это сделать защиту от постороннего Netflow-траффика. Вы можете анализировать IP-адрес входящего устройства и обрабатывать только из нужного вам списка. Но так как у меня в сети полный контроль, то я могу гарантировать, что пришедший ко мне трафик легитимный и не содержит подмены пакетов. Так же вы можете уменьшить обьём записываемого файла «отбросив» ненужную вам информацию. В конечном варианте анализатора я не буду оперировать размером сети. Получается, что я зря записываю маску подсети, но если вдальнейшем мне потребуется, то я смогу извлечь эту информацию из бинарников и добавить в SQL.

Тэги: ИТ, Cisco, программирование, Питон

Отредактировано:2021-02-24 15:17:51


Этот сайт использует файлы cookies, чтобы упростить вашу навигацию по сайту, предлагать только интересную информацию и упростить заполнение форм. Я предполагаю, что, если вы продолжаете использовать мой сайт, то вы согласны с использованием мной файлов cookies. Вы в любое время можете удалить и/или запретить их использование изменив настройки своего интернет-браузера.

Сообщайте мне о замеченных ошибках на: web@orcinus.ru. Все пожелания и советы будут учтены при дальнейшем проектировании сайта. Я готов сотрудничать со всеми желающими. В некоторых случаях, мнение автора может не совпадать с мнением автора! Phone: +7-902-924-70-49.

Top.Mail.Ru
Top.Mail.Ru LiveInternet Rambler's Top100 Яндекс.Метрика