Michael W. Lucas 10/27/2005
Перевод: Сгибнев Михаил
На конференции 2005's USENIX я общался с экспертом в области предотвращения вторжений.
Он рассказал историю про то, как его наняла фирма, с целью выяснить, что происходило во время случившегося
вторжения - кто это был, как сделал и что творил. Любой, кто занимался подобным, может сказать, насколько
сложно провести такое расследование, даже при полной поддержке пострадавшей компании.
Администратор сети обеспечил специалиста всеми файлами регистрации событий,
в частности файлами регистрации системы сетевой защиты.
Через несколько минут специалист убедился в бесполезности этих журнальных файлов. Хотя они и
остались неповрежденными, они содержали сведения только о блокированном трафике, по сути они делали
запись о том, что НЕ случалось, а не о том, ЧТО случилось.
Одним из лучших способов избегнуть подобной ситуации будет ведение журнальных файлов
фактических событий в сети и в реализации подобной системы нам может очень помочь NetFlow.
В предыдущих статьях рассказывалось о том, как настроить сбор статистики по протоколу NetFlow и
как преобразовать имеющиеся данные в графическую форму. С помощью NetFlow мы можем
обеспечить практически любой уровень детализации трафика в сети, чем мы сейчас и займемся.
В качестве вводной примем, что система сбора статистики, рассмотренная ранее уже установлена и
настроена.
Люди разработали множество инструментальных средств для анализа и детализации данных Netflow, в
результате чего в Интернете появилось довольно большое количество процессоров данных и если вы
вдруг захотите написать свой собственный, потратьте немного времени на поиск в Google.
В остальной части статьи мы рассмотрим несколько таких инструментальных средств.
Все описанные здесь средства не портят каким-либо образом файлы данных, метка
flowfiles
указывает на необхрдимость указания имени файла, причем вы можете указывать несколько файлов или
использовать символы подстановки. Примеры разобраны относительно текущего каталога, не забывавайте
этого и при необходимости указывайте полный путь.
flowdumper
Для просмотра индивидуальных потоков можно использовать
flowdumper(1).
По умолчанию, flowdumper выводит все данные на экран.
Я настроятельно рекомендую использовать пейджер less или more, поскольку у вас может быть
тысячи потоков в единственном файле. Flowdumper требует минимум один параметр - имя анализируемого
файла.
# flowdumper flowfiles | less
Если вас интересует трафик на конкретный хост, то вы можете выполнить поиск по IP:
FLOW
index: 0xc7ffff
router: 172.16.20.1
src IP: 192.168.1.54
dst IP: 10.0.8.3
input ifIndex: 0
output ifIndex: 0
src port: 61521
dst port: 443
pkts: 10
bytes: 3015
IP nexthop: 0.0.0.0
start time: Wed Jul 6 10:47:29 2005
end time: Wed Jul 6 10:48:32 2005
protocol: 6
tos: 0x0
src AS: 0
dst AS: 0
src masklen: 0
dst masklen: 0
TCP flags: 0x1e (PUSH|SYN|ACK|RST)
engine type: 0
engine id: 0
Ваш сенсор не будет помечать потоки с данными BGP, если BGP не применяется в сети.
Это означает, что довольно большое количество полей будет пропущено, если вы собираете
данные не с граничного, использующего BGP, маршрутизатора. Поле "router" является
IP адресом сенсора NetFlow, который не обязательно является маршрутизатором.
Отчет о потоке включает IP адрес источника, IP адрес и порт назначения, так же как
число пакетов и байтов в этом отдельном потоке.
Достаточно интересными полями являются
start time и
end time, так как на основании этих
данных можно вычислить занимаемую полосу пропускания канала.
Поле протокола соответствует записям в
/etc/protocols.
Если вы используете BGP-маршрутизатор в качестве сенсора, то отчет будет включать в себя
такие данные, как номер Автономной Системы и длина маски.
Одной из самых интересных особенностей flowdumper - его способность взаимодействовать с Perl при указании
флага
-e.
Flowdumper использует целое разнообразие переменных, определенных в
perldoc Cflow.
Вот - те, которые я нахожу самыми полезными, и они достаточно очевидны.
(Возможное исключение - $exporterip, который является адресом датчика Netflow, передавшим этот поток.)
$srcip
$dstip
$srcport
$dstport
$protocol
$tos
$exporterip
Я нахожу flowdumper достаточно полезным инстументом.
Например, когда я работал в ISP, мой босс иногда задавал такие вопросы как: "Кто в нашей сети использует VPN?"
и flowdumper позволил быстро ответить на этот вопрос.
Стандартный internet трафик использует и другие протоколы кроме TCP, UDP, и ICMP, так что мы
можем просмотреть все остальное:
# flowdumper -e '6 ne $protocol && 17 ne $protocol && 1 ne $protocol' \
flowfiles
Точно так же пакеты в моей сети не должны иметь никакого необычного Type of Service, так
как необычный ToS обычно является признаком вторжения:
# flowdumper -e '0x0 ne $tos' flowfiles
Или я могу захватывать потоки только от указанного сенсора и видеть, какой трафик попадает в ту часть сети:
# flowdumper -e '"192.168.88.134" eq $exporterip' ft-v05.2005-07-06.10*
flow-stat
Второй очевидный вопрос заключается в определении общего количества потребляемого трафика конкретным хостом.
Для ответа на этот вопрос предназначена утилита
flow-stat(1), которая позволяет
обрабатывась большое количество файлов.
На странице руководства man указано довольно много типов поддерживаемых отчетов.
Некоторые из них еще не реализованы, о чем утилита сообщит при попытке их вызова, часть могут оказаться
для вас бесполезными, особенно если вы не используетет BGP. Вот некоторые из тех, которые я считаю
наиболее значимыми:
-
0--Суммарный трафик.
-
5--порт назначения TCP/UDP. Этот отчет считает трафик в обоих набравлениях, так что вы должны
более тщательно отнестись к сортировке.
-
10--IP адрес источника и назначения. Этот отчет позволяет вам проводить сортировку по использованию
трафика между хостами, в результате чего есть возможность обнаружить машину, наиболее сильно занимающей канал.
-
11--IP адрес источника и назначения. Этот отчет позволяет вам проводить сортировку по потреблению трафика.
Для обозначения формата отчета используется флаг
-f.
Опция
-s сортирует результаты по возрастанию, в то время как
-S сортирует в убывающем порядке. Оба для сортировки используют единственный параметр, номер столбца.
Столбцы в flow-stat начинаются с 0.
Для примера, вам необходимо установить, по каким портам проходит наибольший объем трафика.
Это отчет flow-stat формата 5. Обычно я делаю два прохода - первый раз без сортировки, чтобы
убедиться, что вывод вообще есть, а второй раз сотрирую по интересующему меня столбцу.
Здесь я сотрирую по столбцу 1, обозначающему число потоков.
# --- ---- ---- Report Information --- --- ---
#
# Fields: Total
# Symbols: Disabled
# Sorting: Descending Field 1
# Name: UDP/TCP destination port
#
# Args: flow-stat -f 5 -S 1
#
#
# port flows octets packets
#
443 191969 959951160 2554217
80 42740 345856613 2384044
25 1022 8152412 14890
53 346 57947 730
445 307 20352 424
135 249 11952 249
110 212 111870 2342
44473 203 247298 757
...
Вывод здесь несколько укорочен, так как реальный отчет может тянуться на
несколько страниц.
По представленному выводу вы можете многое узнать о моей сети.
Самый популярный порт - 443, для трафика SSL.
Порты 80(http) и 25(smtp) также довольно популярны, весьма значительна доля 53(dns).
Я также получаю много запросов от протокола Microsoft, порты 445 и 135. Мое большое удивление
вызвало появление порта 110, так как в моей сети нет сервера POP3! Придется с этим разобраться...
Так как Netflow отслеживает сессию как два потока (в прямом и обратном направлениях), то
то в отчете будет большое количество маленьких потоков в широком диапазоне непривилегированных
портов.
Допустим, что FlowScan показывет, что канал сильно нагружен и хочется понять причину нагрузки.
Вполне вероятно, что клиент одного из наших серверов делает большие запросы.
Я хочу посмотреть, какие комбинации клиентов и серверов используют большинство потоков(эту
функцию реализует отчет 10 flow-stat). Необходимо отсортировать по 2-му столбцу (потоки) в убывающем порядке.
# flow-cat -p flowfiles | flow-stat -f 10 -S 2 | less
# --- ---- ---- Report Information --- --- ---
#
# Fields: Total
# Symbols: Disabled
# Sorting: Descending Field 2
# Name: Source/Destination IP
#
# Args: flow-stat -f 10 -S 2
#
#
# src IPaddr dst IPaddr flows octets packets
#
105.157.204.33 192.168.88.230 5167 15766678 52283
192.168.88.230 105.157.204.33 5123 5200858 34541
105.157.204.33 192.168.88.243 4121 27993332 63995
192.168.88.243 105.157.204.33 4112 30655019 53695
109.116.147.7 192.168.88.243 3071 8296022 23541
192.168.88.243 109.116.147.7 3069 13705493 18890
24.105.3.130 192.168.88.230 1533 4718630 16236
192.168.88.230 24.105.3.130 1521 1326074 11375
...
Сеть 192.168.88.0 принадлеит локальной сети, все остальное - удаленные сети.
Очевидно, что хост 105.157.204.33 является наиболее активным клиентом, он занимает первые
четыре строчки нашего "хит-парада"!
Третий вопрос, который мы рассмотрим в рамках утилиты flow-stat, заключается в
установлении сервера, с которым открыто самое большое число соединений в единицу времени.
За это у нас отвечает 11-ая форма отчета, отсортированная по 1-му столбцу.
# flow-cat -p flowfiles | flow-stat -f 11 -S 1 | less
# --- ---- ---- Report Information --- --- ---
#
# Fields: Total
# Symbols: Disabled
# Sorting: Descending Field 1
# Name: Source or Destination IP
#
# Args: flow-stat -f 11 -S 1
#
#
# IPaddr flows octets packets
#
192.168.88.230 224442 459688424 1878817
192.168.88.243 153038 1453679456 2635365
192.168.88.247 34503 124729216 291507
Причем довольно интересным моментом здесь является то, что хост, открывший большее
число соединений не является лидером по трафику. В зависимости от вашей конкретной
ситуации вас может интересовать или число октетов или количество пакетов.
flow-nfilter
Многое можно делать на лету с помощью flowdumper или агрегировать полученные данные flow-stat,
но есть необходимость в детальных данных, предоставляемых Netflow. Вы должны легко узнать
число SMTP сессий и посмотреть, к каких хостам делаются попытки подключения по SMTP.
Программа
flow-nfilter(1) позволяет писать детальные отчеты данных Netflow.
Конфигурация flow-nfilter полагается "на примитивы": маленькие определения, которые описывают
одну характеристику трафика - сетевой порт, IP адрес, и так далее.
Затем, примитивы транслируются в большие правила, на основе которых составляются отчеты.
По умолчанию, flow-nfilter хранит примитивы в
/usr/local/etc/flow-tools/filter.cfg.
Начнем разбор программы с них, а затем перейдем к более сложным правилам.
Каждый примитив начинается с метки
filter-primitive и имени.
Страница руководства man содержит большой список различных типов примитивов, охватывающих
большое количество ситуаций, которые могут возникнуть, но в большинстве случаев они избыточны.
Наиболее часто используемыми примитивами являются
ip-protocol,
ip-port,
ip-address и
ip-address-prefix.
Приведем пример для примитива TCP:
filter-primitive TCP
type ip-protocol
permit tcp
default deny
Здесть именем будет
TCP, инструкция
permit указывает на тип
протокола -
tcp, здесь вы можете использовать номер протокола (6), в соответствии
с
/etc/protocols.
Инструкция
default deny указывает на то, что примитив не соответствует больше
ни одному условию. Эта инструкция применяется по умолчанию, но я предпочитаю указывать ее
в явном виде.
Примитив
ip-port соответствует TCP или UDP портам.
А примитив
smtpports применяется только в случае соединения на 25 порт:
filter-primitive smtpports
type ip-port
permit 25
default deny
Знатоки среди вас навскидку смогут определить, являются ли обнаруженные этим примитивом пакеты
данными SMTP или только маскировка.
Определять диапазоны сетей можно с помощью примитива
ip-address-prefix.
Примитив
hostingnet содержит запись о сети 192.168.88.0:
filter-primitive hostingnet
type ip-address-prefix
permit 192.168.88.0/24
default deny
Наконец, можно использовать IP адрес хоста:
filter-primitive local_mailservers
type ip-address
permit 192.168.88.33
default deny
Примитивы могут весьма усложняться. Например предположим, что мне необходим примитив, включающий
в себя всю сеть, за исключением почтового сервера:
filter-primitive local_not_mailservers
type ip-address
deny 192.168.88.33
permit 192.168.88.0/24
default deny
Этот примитив будет соответствовать любому IP адресу от 192.168.88.0 до 192.168.88.32 и от
192.168.88.34 до 192.168.88.254.
Связывать несколько примитивов в один довольно удобно.
Например, политика моей компании запрещает использование telnet(порт 23) и MS SQL(порт 1433)
из внешних сетей. В случае, если такой трафик присутствует - пора бить тревогу.
filter-primitive redflags
type ip-port
permit 23
permit 1433
default deny
Вы не можете комбинировать несвязанные элементы в примитиве, однако, чтобы объединить порт 25 и протокол tcp,
вы можете создать правило.
После того, как у нас появился некий набор примитивов, мы можем создавать на их основе фильтры.
Фильтры начинаются с ключевого слова
filter-definition и имени. После них следуют
несколько инструкций
match.
Как и в случае с примитивами, фильтры поддерживают очень большое количество инструкций для соответствия
различному типу трафика. Наиболее полезными, на мой взгляд, являются инструкции
src-ip-addr,
dst-ip-addr,
src-ip-port,
dst-ip-port и
ip-protocol.
Используйте инструкцию
match для определения трафика, которому вы хотите соответствовать.
Например, если вы хотите соответствовать определенному IP адресу, то вы должны перечислить
примитивы с IP адресами в определении фильтра. Вы не сможете достаточно просто
согласовать IP адрес с примитивом протокола, поэтому можно получить полный список соответствия в
flow-nfilter(1) или проштудировать
filter.cfg,поставляемый с
flow-tools.
Для написания фильтра вам необходимо вычленить уникальную особенность искомого трафика.
Например, трафик, идущий на сервер SMTP. Какие уникальные свойства мы можем использовать?
У нас есть IP адрес, порт и протокол. Этого достаточно для написания фильтра:
filter-definition inboundmail
match dst-ip-addr local_mailservers
match dst-ip-port smtpports
match ip-protocol tcp
Здесь для строк действует неявный
AND. Для выполнения этого фильтра,
поток должен соответствовать всем примитивам этого фильтра.
Точно так же вы можете отслеживать трафик, идущий с вашего почтового сервера на другие сервера.
Для этого достаточно просто переименовать IP назначения в IP адрес источника:
filter-definition outboundmail
match src-ip-addr local_mailservers
match dst-ip-port smtpports
match ip-protocol tcp
Используя эти два фильтра, вы легко можете отслеживать весь трафик вашего почтового сервера.
Используя ключевое слово
OR вы можете обьединить фильтры:
filter-definition allmail
match dst-ip-addr local_mailservers
match dst-ip-port smtpports
match ip-protocol tcp
or
match src-ip-addr local_mailservers
match dst-ip-port smtpports
match ip-protocol tcp
Что меня особенно интересует, так это наличие трафика, которого в сети не должно быть вообще.
Никто не должен использовать
telnet(1) для доступа к моим серверам и никто не
должен подключаться извне к серверам MS SQL. Любой, кто попробует это сделать - вне всяких
сомнений является нарушителем. для реализации стоящей задачи я подготовил примитив
redflags, описывающий требуемые порты TCP/IP.
filter-definition redflags
match dst-ip-port redflags
match dst-ip-addr hostingnet
match ip-protocol tcp
Так же, любой, кто начинает рассылать электронную почту (если это не почтовый сервер), в лучшем
случае заражен трояном, а в худшем - является нарушителем, поэтому мне необходимо знать его IP адрес,
что бы своевременно и оперативно заблокировать.
filter-definition inboundmail_false
match dst-ip-addr local_not_mailservers
match dst-ip-port smtpports
match ip-protocol tcp
Я могу обьединить последние два отчета, в результате я получу список "плохих парней". Поместив его в
cron(1) можно с определенной периодичностью посылать письма системному администратору.
При запуске flow-nfilter используйте
flow-print, так как первоначально создается
бинарный файл из файлов потока, который впоследствии легко может быть обработан другими утилитами.
Flow-nfilter требует два аргумента:
-F для указания фильтра и
-f
для указания файла конфигурации фильтров:
# flow-cat -p flowfiles | flow-nfilter -F reportname \
-f /usr/local/etc/flow-tools/filter.cfg | flow-print
Для примера, проверим файл данных потока ft-v05.2005-07-06.125500-0400 на предмет исходящих почтовых
сессий. Имя файла указывает на то, что он содержит данные за 5-и минутный интервал
с 12:55 до 13 часов 6 июля 2005.
| flow-nfilter -F inboundmail -f /usr/local/etc/flow-tools/filter.cfg \
| flow-print
srcIP dstIP prot srcPort dstPort octets packets
82.158.144.145 10.8.3.199 6 4983 25 497 9
65.34.168.153 10.8.3.199 6 2379 25 509 9
200.94.218.251 10.8.3.199 6 3012 25 232 5
...
Упорядочить вывод можно с помощью утилиты
sort(1).
Если какая-то конкретная запись вызывает ваш интерес, то для детализации вы можете воспользоваться
flowdumper или использовать один из отчетов. встроенных в
flow-print(1).
Однажды, ваш системный администратор будет вас на коленях благодарить за предотвращенное вторжение.
После того, как вы начнете использовать Netflow, вы уже не сможете без него.