Возможно вы искали: 'Миллион лет до нашей эры'

May 15 2025 19:07:02
  • Как сделать 8Gamers.Ru домашней страницей?
  • Игры
    • База данных по играх
    • Игровые новости
    • Игровая индустрия
    • Обзоры на игры
    • Прохождения игр
    • Гайды к играм
    • Превью о играх
    • Игровые тизеры
    • Игровые арты
    • Игровые обои
    • Игровые скриншоты
    • Игровые обложки
    • Игровые трейлеры
    • Игровое видео
    • Вышедшие игры
    • Ближайшие релизы игр
  • Кино и ТВ
    • База данных по кино
    • Статьи о кино
    • Постеры
    • Кадры из кино
    • Кино трейлеры
    • Сегодня в кино
    • Скоро в кино
  • Комиксы и манга
    • Манга по алфавиту
    • База данных по комиксах
    • Читать онлайн комиксы
    • Читать онлайн манга
    • База персонажей
  • Читы и коды
    • Чит-коды для PC игр
    • Чит-коды для консольных игр
    • Трейнеры
    • Коды Game Genie
  • Моддинг
    • Модификации
    • Карты к играм
    • Программы для моддинга
    • Статьи о моддинге
  • Геймдев
    • Всё о создании игр
    • Список движков
    • Утилиты в помощь игроделу
    • Конструкторы игр
    • Игровые движки
    • Библиотеки разработки
    • 3D-модели
    • Спрайты и тайлы
    • Музыка и звуки
    • Текстуры и фоны
  • Рецензии
    • Игры
    • Кино
    • Аниме
    • Комиксы
    • Мангу
    • Саундтреки
  • Саундтреки
    • Лирика
  • Файлы
    • Патчи к играм
    • Русификаторы к играм
    • Сохранения к играм
    • Субтитры к кино
  • Медиа
    • Видео
    • Фото
    • Аудио
    • Фан-арты
    • Косплей
    • Фото с виставок
    • Девушки из игр
    • Рисунки
    • Рисуем онлайн
    • Фотохостинг
  • Юмор
    • Анекдоты
    • Афоризмы
    • Истории
    • Стишки и эпиграммы
    • Тосты
    • Цитаты
  • Флеш
    • Азартные
    • Аркады
    • Бродилки
    • Гонки
    • Для девочек
    • Для мальчиков
    • Драки
    • Квесты
    • Леталки
    • Логические
    • Мультфильмы
    • Открытки
    • Приколы
    • Разное
    • Спорт
    • Стратегии
    • Стрелялки
Статистика

Статей: 87772
Просмотров: 96111483
Игры
Injustice:  Gods Among Us
Injustice: Gods Among Us
...
Dark Souls 2
Dark Souls 2
Dark Souls II - вторая часть самой хардкорной ролевой игры 2011-2012 года, с новым героем, сюжето...
Battlefield 4
Battlefield 4
Battlefield 4 - продолжение венценосного мультиплеер-ориентированного шутера от первого ли...
Кино
Steins;Gate
Steins;Gate
Любители японской анимации уже давно поняли ,что аниме сериалы могут дать порой гораздо больше пи...
Ку! Кин-дза-дза
Ку! Кин-дза-дза
Начинающий диджей Толик и всемирно известный виолончелист Владимир Чижов встречают на шумной моск...
Обзоры на игры
• Обзор Ibara [PCB/PS2] 18357
• Обзор The Walking ... 18801
• Обзор DMC: Devil M... 19879
• Обзор на игру Valk... 15877
• Обзор на игру Stars! 17764
• Обзор на Far Cry 3 17948
• Обзор на Resident ... 16024
• Обзор на Chivalry:... 17508
• Обзор на игру Kerb... 17981
• Обзор игры 007: Fr... 16619
Превью о играх
• Превью к игре Comp... 17960
• Превью о игре Mage... 14464
• Превью Incredible ... 14721
• Превью Firefall 13479
• Превью Dead Space 3 16334
• Превью о игре SimC... 14730
• Превью к игре Fuse 15442
• Превью Red Orche... 15542
• Превью Gothic 3 16343
• Превью Black & W... 17354
Главная » Статьи » Разное » Использование ng_ipfw + ng_bpf для фильтрации по телу пакета во FreeBSD (netgraph filter ip udp bpf tcpdump packet freebsd)

Использование ng_ipfw + ng_bpf для фильтрации по телу пакета во FreeBSD (netgraph filter ip udp bpf tcpdump packet freebsd)

Ключевые слова: netgraph, filter, ip, udp, bpf, tcpdump, packet, freebsd, (найти похожие документы)

From: Антон Южанинов <http://citrin.ru>
Date: Mon, 24 Oct 2007 14:31:37 +0000 (UTC)
Subject: Использование ng_ipfw + ng_bpf для фильтрации по телу пакета во FreeBSD

Оригинал: http://citrin.ru/freebsd:ng_ipfw_ng_bpf


Использование ng_ipfw + ng_bpf для фильтрации по телу пакета

ipfw это удобный и гибкий пакетный фильтр, но без внешних средств
решение он может принимать только на основе данных в заголовке пакета
(ip и udp/tcp). Иногда этого недостаточно и нужно учитывать содержимое
пакета. Например у меня возникло желание зафильтровать DNS-запросы
MX-записей, которые в большом количестве делают зараженные спамерскими
троянами клиентские компьютеры, чем вызывают повышенную загрузку
DNS-сервера. В случае если клиентские компьютеры за NAT, почтовых
серверов на них быть не должно, и MX-записи им спрашивать не нужно.
Правильно ли так делать это отдельный вопрос, здесь будет рассмотрен
только технический аспект - как это сделать.

Для решения данной задачи есть как минимум три варианта:
* Из ipfw через divert-сокет отправлять пакеты процессу работающему
в userspace, который будет слушать divert-сокет и фильтровать
приходящие на него пакеты. Главный минус такого варианта - большие
накладные расходы и как следствие низкая производительность.
Другой минус - этот демон еще нужно написать. Хотя не исключено,
что кто то уже написал демон слушающий divert и фильтрующий пакеты
через bpf.
* ng_bpf - узел Netgraph использующий bpf для фильтрации пакетов
+ ng_bpf можно подключить непосредственно к ng_ether.
+ пакеты в ng_bpf можно отправлять из ipfw через ng_ipfw, при
выполнении определенного правила через.

Я выбрал последний вариант (ng_ipfw+ng_bpf), несмотря на то, что он
несколько сложнее (ниже напишу почему), чем ng_ether+ng_bpf. Во-первых
связка ng_ipfw+ng_bpf теоретически должна работать немного быстрее
(тесты не проводил), а во вторых из ipfw удобно рулить тем какие
пакеты отправлять на дальнейшую обработку в bpf, а какие нет.


bpf

Для начала нужно определиться по какому bpf-выражению будем
фильтровать пакеты. Исходная задача звучала так: DNS-запросы (бит QR
установлен в 1). Тип запроса - MX. Со вторым сложнее - в одном пакете
может быть запрос на несколько записей разных типов, а сами запросы
имеют переменную длину, и начинаются со строки заканчивающейся на 0
длина которой не указана в полях. Парсить такой запрос полностью в bpf
очень неудобно. Впрочем это и не нужно - запросы посылаемые спамботами
содержать запрос только на одну запись типа MX и можно просто
заглянуть в конец пакета - там будут поля Type (MX - 0x000f)и Class
(IN - 0 *0001). Если это проверять, то под правило будут подпадать
любые пакеты у которых в конце запрос на MX-запись.

При составлении выражения удобно пользоваться описанием формата
пакетов с сайта networksorcery.com (^1).

udp[10] & 0 *80 = 0 - проверяем, что 1-й бит, байта со смещением
10 (^2) выставлен в 1, т. е. то, что это запрос, а не ответ.

udp[udp[4:2]-4 : 4] = 0x000f0001 - последние 4 байта UDP пакета
0x000f0001. udp[4:2] это длинна UDP пакета в байтах (вместе с
заголовком).

В результате получается выражение:

udp dst port 53 and udp[10] & 0x80 = 0 and udp[udp[4:2]-4 : 4] = 0x000f0001


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

В какие инструкции нужно преобразовать выражение зависит от того, что
подается на вход bpf-фильтра - IP пакеты (начиная с заголовка
IP-пакета без каких либо дополнительных заголовков), ethernet-фреймы
(т. е. заголовок канального уровня и далее IP пакет) или пакет какого
либо другого канального уровня.

В случае если ng_bpf подключен к ng_ether на его вход подаются
ethernet фреймы, и для получения bpf-кода можно воспользоваться
способом описанным в man ng_bpf - tcpdump -ddd и последующее
приведении в формат который нужен для netgraph с помощью awk.

В случае подключения ng_bpf к ng_ipfw на вход подаются IP пакеты и
такой способ не подойдет - в начале будет пара команд проверяющих поле
в заголовке ethernet-фрейма которого в нашем случае нету, а в
последующих командах будет использовано смещение на 14 байт больше чем
нужно.

Поэтому есть два способа - составить программу руками заглядывая в man
bpf и /usr/include/net/bpf.h (за основу можно взять вывод tcpdump
-ddd, но с нуля написать не сложнее чем вручную дизассемблировать
вывод tcpdump -ddd, изменить и потом снова перевести это в bpf-код).
Это процесс сильно напоминает программирование на ассемблере с
последующим переводом этого в машинные коды.

Или можно написать небольшую программку для компиляции выражения в
bpf-код проверки IP пакетов (в libpcap это тип DLT_RAW, т. е. "сырой"
IP пакет без каких либо дополнительных заголовков).

Cначала я составил bpf-код вручную, потом решил, что такой способ
хорошо только в учебных целях, поскольку отнимает много времени и для
повседневной работы не годится.

Потом написал маленькую программку которая это делает используя
libpcap:


/*
* to compile type:
* gcc -lpcap bpf_comp.c -o bpf_comp
*/

#include <err.h>
#include <pcap.h>
#include <stdio.h>
#include <sysexits.h>

int main(int argc, char *argv[])

{
struct bpf_program bp;
unsigned int i;

if (argc != 2)
errx(EX_USAGE, "Usage %s 'filter expression'", argv[0]);

if(pcap_compile_nopcap(65535, DLT_RAW, &bp, argv[1], 1, 0)) {
errx(EX_USAGE, "filter syntax error");
}

[26]printf("bpf_prog_len=%d bpf_prog=[ ", bp.bf_len);

for (i = 0; i < bp.bf_len; i ++) {
[27]printf("{ code=%d jt=%d jf=%d k=%d } ",
bp.bf_insns[i].code, bp.bf_insns[i].jt, bp.bf_insns[i].jf, bp.bf_insns[i].k);
}

[28]printf("]n");

exit(0);
}




Для тестирования этой программы можно посмотреть bpf-программу для
фильтрации udp пакетов

:~> ./bpf_comp udp
bpf_prog_len=5 bpf_prog=[ { code=0 jt=0 jf=0 k=0 } { code=48 jt=0 jf=0 k=9 } {
code=21 jt=0 jf=1 k=17 } { code=6 jt=0 jf=0 k=65535 } { code=6 jt=0 jf=0 k=0 }]


Если у Вас получится программа, не 5 команд (bpf_prog_len=5), а 7,
значит libpcap собран с поддержкой IPv6 которая пока реализована не
очень хорошо. В результате для DLT_RAW создается фильтрующий код,
который кроме интересующих нас пакетов может поймать и лишние (это
происходит в libpcap до версии 0.9.5 включительно, а в 0.9.6 это
должно быть исправлено, но в любом случае если в сети используется
только IPv4, то лучше собирать libpcap без поддержки IPv6, чтобы
bpf-программа была короче и быстрее). Поэтому если у вас получилось 7
команд для udp, рекомендую пересобрать без поддержки IPv6:

echo 'NO_INET6=true' >> /etc/make.conf
cd /usr/src/lib/libpcap/
make clean
make
make install


Для интересующего нас выражения получается такая bpf-программа:

:~> ./bpf_comp 'udp dst port 53 and udp[10] & 0x80 = 0 and udp[udp[4:2]-4 : 4]= 0x000f0001'
bpf_prog_len=18 bpf_prog=[ { code=0 jt=0 jf=0 k=0 } { code=48 jt=0 jf=0 k=9 } {
code=21 jt=0 jf=14 k=17 } { code=40 jt=0 jf=0 k=6 } { code=69 jt=12 jf=0 k=8191 }
{ code=177 jt=0 jf=0 k=0 } { code=72 jt=0 jf=0 k=2 } { code=21 jt=0 jf=9 k=53 }
{ code=80 jt=0 jf=0 k=10 } { code=69 jt=7 jf=0 k=128 } { code=72 jt=0 jf=0 k=4 }
{ code=20 jt=0 jf=0 k=4 } { code=12 jt=0 jf=0 k=0 } { code=7 jt=0 jf=0 k=0 }
{ code=64 jt=0 jf=0 k=0 } { code=21 jt=0 jf=1 k=983041 } { code=6 jt=0 jf=0 k=65535 }
{ code=6 jt=0 jf=0 k=0 } ]


(первая команда в данном случае лишняя и её можно выкинуть, но можно
ли это делать зависит от того какая команда стоит за ней, в общем
случае проще оставлять программу как есть).


Netgraph

Для использования узлов типа ng_bpf и ng_ipfw нужно загрузить
соответствующие модули (если они не были включены в ядро):

:~# kldload ng_ipfw
:~# kldload ng_bpf


Чтобы после перезагрузки они загружались автоматически нужно добавить
в /boot/loader.conf

ng_ipfw_load="YES"
ng_bpf_load="YES"


При загрузке модуля ng_ipfw автоматически создается одни узел с именем
ipfw (дополнительные узлы типа ipfw создавать нельзя). Создаем узел
типа bpf и подключаем его к ipfw:

:~# ngctl mkpeer ipfw: bpf 1 main


Задаем созданному узлу имя:

:~# ngctl name ipfw:1 dns_mx_q_filter


Конфигурируем его:

:~# ngctl msg dns_mx_q_filter: setprogram { thisHook="main" ifMatch="" ifNotMatch="main"
bpf_prog_len=17 bpf_prog=[ { code=48 jt=0 jf=0 k=9 } { code=21 jt=0 jf=14 k=17 }
{ code=40 jt=0 jf=0 k=6 } { code=69 jt=12 jf=0 k=8191 }
{ code=177 jt=0 jf=0 k=0 } { code=72 jt=0 jf=0 k=2 } { code=21 jt=0 jf=9 k=53 }
{ code=80 jt=0 jf=0 k=10 } { code=69 jt=7 jf=0 k=128 } { code=72 jt=0 jf=0 k=4 }
{ code=20 jt=0 jf=0 k=4 } { code=12 jt=0 jf=0 k=0 } { code=7 jt=0 jf=0 k=0 }
{ code=64 jt=0 jf=0 k=0 } { code=21 jt=0 jf=1 k=983041 }
{ code=6 jt=0 jf=0 k=65535 } { code=6 jt=0 jf=0 k=0 } ] }


thisHook - хук, входящие пакеты с которого будут фильтроваться
заданной программой. ifMatch - хук куда будут отправляться пакеты для
которых выполнено условия фильтра. Если задать пустым, то пакеты будут
отбрасываться (что в данном случае и требовалось - фильтровать
определенные пакеты). ifNotMatch - все остальные пакеты отправляем
обратно в ipfw (^3).

Можно посмотреть, что программа действительно задана:

:~# ngctl msg dns_mx_q_filter: getprogram "main"


Теперь осталось интересующие нас пакеты отправить из ipfw через хук с
именем 1 в netgraph. Т. к. к хуку с именем 1 подключен узел типа
ng_bpf, то пакеты попадут к нему:

:~# ipfw add 123 netgraph 1 udp from 192.168.0.0/16 to me 53


Для просмотра статистики есть сообщение getstats

:~# ngctl msg dns_mx_q_filter: getstats "main"
Rec'd response "getstats" (3) from "[4fa]:":
Args: { recvFrames=16333 recvOctets=977179 recvMatchFrames=9133 recvMatchOcte
ts=512317 xmitFrames=7200 xmitOctets=464862 }


Из 16333 пакетов отправленных правилом ipfw в ng_bpf, 9133 пакетов
были запросами на mx-записи.

Для конфигурации ng_ipfw+ng_bpf при загрузке можно положить скрипт
в /usr/local/etc/rc.d/ (расширение .sh нужно только во FreeBSD 4, 5.
Для 6-ки его лучше убрать).


комментарии по поводу этой заметки можно писать в ЖЖ

Ремарки:

1) первоисточник этой информации RFC, но в RFC эта информация
представлена не так наглядно и удобно

2) 8 байт, заголовок UDP и 2 байта идентификатор DNS запроса

3) что с ними будет дальше зависит от значения sysctl
net.inet.ip.fw.one_pass - либо будет разрешен, либо продолжится
проверка следующих правил


Скрипт для конфигурации ng_ipfw+ng_bpf при загрузке:


#!/bin/sh

# PROVIDE: ng_bpf
# REQUIRE: LOGIN abi
# BEFORE: securelevel

. /etc/rc.subr

name="ng_bpf"

# see http://citrin.ru/freebsd:ng_ipfw_ng_bpf for more info
#
# udp[10] & 0x80 = 0 - Query bit = 1
# udp[udp[4:2]-4 : 4] = 0x000f0001 - type MX and class IN (at the end of the packet)
#
# udp dst port 53 and udp[10] & 0x80 = 0 and udp[udp[4:2]-4 : 4] = 0x000f0001
bpf_prog="bpf_prog_len=17 bpf_prog=[ { code=48 jt=0 jf=0 k=9 } { code=21 jt=0 jf=14 k=17 }
{ code=40 jt=0 jf=0 k=6 } { code=69 jt=12 jf=0 k=8191 } { code=177 jt=0 jf=0 k=0 }
{ code=72 jt=0 jf=0 k=2 } { code=21 jt=0 jf=9 k=53 } { code=80 jt=0 jf=0 k=10 }
{ code=69 jt=7 jf=0 k=128 } { code=72 jt=0 jf=0 k=4 } { code=20 jt=0 jf=0 k=4 }
{ code=12 jt=0 jf=0 k=0 } { code=7 jt=0 jf=0 k=0 } { code=64 jt=0 jf=0 k=0 }
{ code=21 jt=0 jf=1 k=983041 } { code=6 jt=0 jf=0 k=65535 } { code=6 jt=0 jf=0 k=0 } ]"

ngctl="/usr/sbin/ngctl"

start_cmd="start_cmd"
# stop not implemented
stop_cmd=":"

extra_commands="stats"
stats_cmd="getstats_cmd"

start_cmd()
{
# modules must be already loaded (via /boot/loader.conf)
debug "create ng_bpf node and connect to ipfw"
$ngctl mkpeer ipfw: bpf 1 main
$ngctl name ipfw:1 dns_mx_q_filter
debug "set bpf program"
$ngctl msg dns_mx_q_filter: setprogram { thisHook="main" ifMatch="" ifNotMatch="main" $bpf_prog }
}

getstats_cmd()
{
$ngctl msg dns_mx_q_filter: getstats "main"
}

load_rc_config $name

: ${ng_bpf_enable="YES"}

run_rc_command "$1"
568 Прочтений •  [Использование ng_ipfw + ng_bpf для фильтрации по телу пакета во FreeBSD (netgraph filter ip udp bpf tcpdump packet freebsd)] [08.05.2012] [Комментариев: 0]
Добавил: Ukraine Vova
Ссылки
HTML: 
[BB Url]: 
Похожие статьи
Название Добавил Добавлено
• Использование ng_ipfw + ng_bpf для ... Ukraine Vova 08.05.2012
Ни одного комментария? Будешь первым :).
Пожалуйста, авторизуйтесь для добавления комментария.

Проект входит в сеть сайтов «8Gamers Network»

Все права сохранены. 8Gamers.NET © 2011 - 2025

Статьи
Рецензия на Pressure
Рецензия на Pressure
Чтобы обратить на себя внимание, начинающие маленькие разработчики, как правило, уходят в жанры, ...
Рецензия на Lost Chronicles of Zerzura
Рецензия на Lost Chron...
Игры, сделанные без любви и старания, похожи на воздушный шар – оболочка есть, а внутри пусто. Lo...
Рецензия на The Bridge
Рецензия на The Bridge
«Верх» и «низ» в The Bridge — понятия относительные. Прогуливаясь под аркой, можно запросто перей...
Рецензия на SimCity
Рецензия на SimCity
Когда месяц назад состоялся релиз SimCity, по Сети прокатилось цунами народного гнева – глупые ош...
Рецензия на Strategy & Tactics: World War 2
Рецензия на Strategy &...
Название Strategy & Tactics: World War II вряд ли кому-то знакомо. Зато одного взгляда на ее скри...
Рецензия на игру Scribblenauts Unlimited
Рецензия на игру Scrib...
По сложившейся традиции в информационной карточке игры мы приводим в пример несколько похожих игр...
Рецензия на игру Walking Dead: Survival Instinct, The
Рецензия на игру Walki...
Зомби и продукция-по-лицензии — которые и сами по себе не лучшие представители игровой биосферы —...
Обратная связь | RSS | Донейт | Статистика | Команда | Техническая поддержка