Home

Реклама

Май 31, 2007


Previous Entry в избранное рассказать другу Next Entry
07:26 pm - Фильтрация DNS запросов с помощью ng_ipfw+ng_bpf
Недавно настроил для ИКС фильтрацию DNS запросов по типу. Возможно этот опыт пригодится еще кому то. Аналогичным образом можно фильтровать не только DNS, но и любые пакеты по их содержимому, если условие можно выразить в виде понятном bpf. Сама статья лежит на citrin.ru, а здесь только пара слов о том, зачем и почему это было мне нужно.

То ли пользователи в своей массе глупеют, то ли программисты разрабатывающие трояны умнеют, но за последние полгода в ИКС резко увеличилось число машин на которых установлены трояны, используемые для рассылки спама и DDoS-аттак (и другой подобной деятельности).

Когда число зараженных машин (и скорость появления новых членов "ботнета") превысила разумные пределы было принято решение закрыть пользователям 25-й порт. Мера это крайняя, но она было вынуждена. А более мягкие решения, например, автоматическое выявление спам-ботов и блокировка 25-го порта только машин рассылающих спам, с возможностью снятия блокировки через веб-интерфейс, небольшой сети сети с маленьким бюджетом, просто не по карману.

После того как 25-й порт был закрыт, я думал, что о проблеме спамботов у пользователей ИКС можно будет забыть если не на всегда, то на долго.

Однако у них оказался побочный эффект. Несмотря на то, что рассылать спам у них уже не получается они по прежнему пытаются это делать. При этом посылают к ДНС серверу много запросов на MX-записи. Чем вызывают повышенную загрузку сервера (и в небольшой степени внешнего канала).

Отсюда возникло желание зафильтровать запросы на MX-записи. Честные пользователи страдать от этого не должны - им MX-записи не нужны. Даже если кто то отправлял почту через локальный MTA (таких не больше нескольких человек из тысячи), то после закрытия 25-го порта им пришлось прописать relayhost/smarthost. Так что MX-записи не нужны даже им.

Но оказалось это не так просто сделать сделать. Все же в итоге задача была решена с помощью связки ipfw+ng_ipfw+ng_bpf. О том как это можно сделать я написал небольшую заметку у себя на сайте.

Надо сказать, что задача отняла у меня сравнительно много времени (часа два тольк ушло на ручное составление bpf-программы) - в сумме часов 5 наверно (всё ни как не приучу себя учитывать потраченное время). И овчинка не стоила выделки - нагрузка на сервер от спамботов была не на столько большой чтобы довести сервер до состояния 0% idle, можно было было на них просто забить. Но мне давно хотелось разобраться с тем, как фильтровать пакеты по их содержимому с помощью bg_bpf и был хороший повод этим заняться :)

Заодно разобрался с тем как работает bpf и узнал про багу особенность работы libpcap когда она собрана с поддержкой IPv6: функция pcap_compile для DLT_RAW сначала проверяет каждый пакет как будто это пакет IPv6 (даже если на самом деле это IPv4), а потом проверяет как IPv4. И за этого под правило попадает большое пакетов чем нужно (хоть и с низкой вероятностью). Разработчики пишут, что в CVS это уже исправлено.

(Оставить комментарий)

Comments:


From:[info]netch
Date:Август 17, 2007 06:09 am none (UTC)
(Link)
> часа два тольк ушло на ручное составление bpf-программы

tcpdump -d[d][d] не мог помочь?
From:[info]ospf_ripe
Date:Август 17, 2007 07:09 am none (UTC)
(Link)
tcpdump -d[d][d] немного помог. Только поскольку он считает все смещения для ethernet фрейма, а из ng_ipfw приходят IP пакеты, смещения нужно пересчитывать. А поскольку в ethernet фрейме полей больше чем в IP пакете, программу для IP пакета, пограмму нужно еще и укорачивать. Чтобы сделать все это нужно дезассемблировать bpf программу (вывод -ddd недостаточно понятнен и местами приходилось просто по кодам команд смотреть в net/bpf.h) и разобраться как она работает.
From:[info]buddy_ekb
Date:Ноябрь 26, 2007 10:30 am none (UTC)

туннельный интерфейс

(Link)
если указывать tcpdump'у в качестве -i туннельный интерфейс, то можно получить искомую микропрограмму без влезания в дебри net/bpf.h.
[User Picture]
From:[info]nuclight
Date:Январь 26, 2009 12:27 pm none (UTC)

Re: туннельный интерфейс

(Link)
На 6.x это приведет к нерабочей программе:
# tcpdump -di tun0 src host 1.2.3.4
tcpdump: WARNING: tun0: no IPv4 address assigned
(000) ld       [0]
(001) jeq      #0x2000000       jt 2    jf 5
(002) ld       [16]
(003) jeq      #0x1020304       jt 4    jf 5
(004) ret      #96
(005) ret      #0
# tcpdump -di lo0 src host 1.2.3.4
(000) ld       [0]
(001) jeq      #0x2000000       jt 2    jf 5
(002) ld       [16]
(003) jeq      #0x1020304       jt 4    jf 5
(004) ret      #96
(005) ret      #0
# tcpdump -di ng0 src host 1.2.3.4
(000) ld       [0]
(001) jeq      #0x2000000       jt 2    jf 5
(002) ld       [16]
(003) jeq      #0x1020304       jt 4    jf 5
(004) ret      #96
(005) ret      #0
# tcpdump -dr dltraw.pcap src host 1.2.3.4
reading from file dltraw.pcap, link-type RAW (Raw IP)
(000) ld       #0x0
(001) ld       [12]
(002) jeq      #0x1020304       jt 3    jf 4
(003) ret      #65535
(004) ret      #0

Видно, что в случае туннельных интерфейсов и лупбэка оно ищет адрес на 4 байта позже, чем в чистом DLT_RAW, а при вызове из ipfw именно RAW и надо. Сам файл dltraw.pcap (там только лишь 24 байта заголовка для определения типа линка), если лень извращаться с ipfwpcap, можно получить так:
echo '1MOyoQIABAAAAAAAAAAAAP//AABlAAAA' | uudecode -mr > dltraw.pcap
[User Picture]
From:[info]_dyr
Date:Октябрь 30, 2007 10:01 am none (UTC)
(Link)
Немного отвлечённый вопрос на тему ngctl и ng_bpf: как получить getprogram из ng_bpf, не зная имени хука? Пример (mpd4 + shape):
nas3# ngctl list | grep bpf
  Name: mpd5864-B-3-lim Type: bpf             ID: 0000a2d3   Num hooks: 6
  Name: mpd5864-B-4-lim Type: bpf             ID: 0000a2ab   Num hooks: 6
  Name: mpd5864-B-1-lim Type: bpf             ID: 0000a28a   Num hooks: 6
  Name: mpd5864-B-323-lim Type: bpf             ID: 00009b6b   Num hooks: 6
  Name: mpd5864-B-733-lim Type: bpf             ID: 000092fa   Num hooks: 6
  Name: mpd5864-B-638-lim Type: bpf             ID: 000092eb   Num hooks: 6
  Name: mpd5864-B-284-lim Type: bpf             ID: 000091bf   Num hooks: 6
  Name: mpd5864-B-244-lim Type: bpf             ID: 00008fc5   Num hooks: 6
  Name: mpd5864-B-423-lim Type: bpf             ID: 00008bb7   Num hooks: 6
  Name: mpd5864-B-52-lim Type: bpf             ID: 0000812c   Num hooks: 6
  Name: mpd5864-B-192-lim Type: bpf             ID: 00006a2d   Num hooks: 6
  Name: mpd5864-B-701-lim Type: bpf             ID: 00005bae   Num hooks: 6
  Name: mpd5864-B-619-lim Type: bpf             ID: 00004a78   Num hooks: 6
  Name: mpd5864-B-389-lim Type: bpf             ID: 00003fef   Num hooks: 6
  Name: mpd5864-B-104-lim Type: bpf             ID: 000035d7   Num hooks: 6
  Name: mpd5864-B-380-lim Type: bpf             ID: 00002ad5   Num hooks: 6
  Name: mpd5864-B-359-lim Type: bpf             ID: 00002785   Num hooks: 6
  Name: mpd5864-B-6-lim Type: bpf             ID: 000018ed   Num hooks: 6
  Name: mpd5864-B-123-lim Type: bpf             ID: 00000c2f   Num hooks: 6
nas3# ngctl msg mpd5864-B-123-lim getprogram
ngctl: send msg: No such file or directory
nas3#

From:[info]ospf_ripe
Date:Октябрь 31, 2007 10:20 am none (UTC)
(Link)
1. Сначала смотрим название хука (в колонке Local hook):

ngctl show mpd5864-B-123-lim:

потом зная его смотрим уже bpf-программу

ngctl msg mpd5864-B-123-lim: getprogram \"hook_name\"
[User Picture]
From:[info]_dyr
Date:Октябрь 31, 2007 07:11 pm none (UTC)
(Link)
Огромное спасибо, очень помогли.
Anton Yuzhaninov - Фильтрация DNS запросов с помощью ng_ipfw+ng_bpf

> Свежие записи
> Архив
> Друзья
> Личная информация
> Мой сайт


> Go to Top
LiveJournal.com

Реклама