Pull to refresh

Как улучшить анализ и управление сетевым трафиком, наблюдая за DNS

Reading time 3 min
Views 8.9K
Несмотря на то, что почти повсеместно мы используем доменные имена вместо IP-адресов, инструменты для мониторинга и контроля за сетевым трафиком как правило оперируют IP-адресами. Разрешение имен вообще (и DNS в частности) используется довольно условно.

Это связано с некоторыми особенностями работы DNS — результат разрешения имени в адрес может быстро прокиснуть, следующий запрос может вернуть другой адрес, результаты могут отличаться в зависимости от географии и провайдера запрашивающего.

Можно ли иметь актуальную таблицу соответствия имен и адресов для небольших сетей? Какие именно домены запрашивали пользователи и какие получили IP-адреса? С некоторыми оговорками — да.

Сетевые администраторы как правило используют для этого подконтрольные DNS-сервера. Предполагается, что все пользователи сети разрешают имена только на этих серверах, остальной DNS-трафик блокируется. Это хорошее решение, но работает до определенного размера сети и квалификации пользователей.

В дружественной компании нас попросили сделать netflow-отчеты более информативными. Вместо того, что отдает rDNS и whois для IP адреса, они хотели видеть из какого доменного имени на самом деле получился тот или иной адрес.

Внутри организации было несколько DNS-серверов Microsoft и BIND, у части пользователей стояли локальные кеширующие DNS'ы, некоторые пользовались публичными серверами гугла. Даже заставить всех пользователей разрешать имена на нашем сервере представлялось почти невозможным. Скорее всего мы бы получили противоположный результат — часть пользователей стали бы пускать DNS в VPN, пользоваться DNSCrypt и т.п.

Немного поразмышляв, мы решили пойти более простым путем. Что, если сканировать DNS-ответы в точках выхода трафика? Это во-первых позволит не привязываться в решении к конкретным DNS-серверам, и во-вторых не нужно будет изменять существующую конфигурацию сети и раздражать пользователей.

После неудачных поисков готовых утилит я (как инициатор) собрался с духом, взял в руки RFC и набросал небольшую программу — https://github.com/vmxdev/sidmat/.

Программа сканирует DNS-ответы серверов (этого достаточно, внутри ответов есть запросы), и если доменное имя матчится с регулярным выражением, печатает адрес из А-записи (то, что получилось в результате разрешения).

Пользуясь этой утилитой можно собрать почти всю статистику — какое доменное имя разрезолвилось в IP адрес, и когда это произошло. Подготовленный пользователь, конечно, может спрятать эту информацию (записывая узел в hosts-файл, или пользуясь другим каналом для DNS-запросов, например), но для основной массы узлов мы получим удовлетворительную картину.

Как это работает:

$ sudo ./sidmat eth0 "." iu

Мы видим доменные имена и во что они разрешаются (eth0 — интерфейс, на котором проходит DNS-трафик).

$ sudo ./sidmat eth0 "." iu | while IFS= read -r line; do printf '%s\t%s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$line"; done

Фиксируем время. Осталось перенаправить результат в файл, и можно пользоваться таблицей соответствия. Утилита может захватывать DNS-ответы с помощью pcap (в Линукс/BSD) или с помощью механизма nflog в Линуксе.

Эту же технику можно использовать и для управления трафиком. Фильтровать по доменам, получать адреса доменов с ключевым словами в именах и т.п.

Нужно иметь в виду, что управление может получиться не очень аккуратным. Если за время, когда до пользователя дойдет DNS-ответ и он начнет передавать трафик на этот узел, мы не успеем добавить адрес в ipset/iptables/таблицу маршрутизации/еще куда-то, то трафик пойдет «обычным» путем.

Кроме этого, квалифицированный пользователь может генерировать ложные DNS-ответы, то есть для репрессий лучше пользоваться этим с осторожностью.

Несколько примеров:

Как получить список IP-адресов, в которые резолвится vk.com и его поддомены? (Без опции 'u' будут печататься только уникальные IP-адреса)

$ sudo ./sidmat eth0 "^vk.com$|\.vk.com$" d

С опциями «d» или «i» видно какой именно домен разрешается в IP-адрес, «d» печатает имя домена в stderr.

Как заблокировать адреса в которые разрешается vk.com, его поддомены и все домены со словом odnoklassniki? (домены типа avk.com не попадут под правило, odnoklassnikii.com — попадут).

$ sudo sh -c '/sidmat eth0 "^vk\.com$|\.vk\.com$|odnoklassniki" | /usr/bin/xargs -I {} /sbin/iptables -A INPUT -s {} -j DROP'

Кроме небольших регулярных выражений можно использовать списки в файле (опция «f», второй аргумент интерпретируется как имя файла, его содержимое — как одно большое регулярное выражение). Списки могут быть достаточно большими, мы смотрели на производительность на списке доменов РКН (трафик на запретные домены перенаправлялся в VPN), обычный ПК-маршрутизатор совершенно спокойно с этим справился.
Tags:
Hubs:
+8
Comments 2
Comments Comments 2

Articles