Вход на хостинг
IT-новости
20.04.2016 iPhone 2017 года поместят в водонепроницаемый корпус из стекла
Линейка iPhone в новом году серьезно поменяется. В этом уверен аналитический исследователь Мин Чи Ку......
30.07.2015 Ищем уникальный контент для сайта
Ищем уникальный контент для сайта Без уникального контента Ваш сайт обречен на то, что его страницы......
Владимир Мешков
NETFILTER – это новый механизм фильтрации сетевых пакетов, появившийся в составе ядра Linux версий 2.4. Данный механизм позволяет отслеживать прохождение пакетов по стеку IP-протокола и при необходимости перехватить, модифицировать, блокировать любой пакет. На базе NETFILTER построен iptables – пакетный фильтр, широко использующийся при построении межсетевых экранов.
Для включения NETFILTER в состав ядра необходимо в конфигурационном файле установить опцию CON-FIG_NETFILTER = y и пересобрать ядро. После этого все пакеты, проходящие по стеку IPv4-протокола, будут обработаны NETFILTER. Рассмотрим для примера главную приемную функцию IPv4-протокола ip_rcv (файл ip_input.c). Найдем в ней следующий код:
return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, ip_rcv_finish);
Обращение к NETFILTER выполняет макрос NF_HOOK. В вызове макроса указаны протокол (PF_INET), точка перехвата (NF_IP_PRE_ROUTING), поступивший пакет (структура skb), информация о входном и выходном интерфейсах (структура dev и NULL, соответственно). В точке перехвата пакет попадает в ловушку – так называется функция, которая на основе анализа адресной информации решает судьбу пакета: либо он пройдет дальше, либо будет уничтожен. Последний аргумент – функция, которая будет вызвана для дальнейшей обработки поступившего пакета. Эта функция будет вызвана только в том случае, если NETFILTER пропустит пакет.
В случае если NETFILTER в состав ядра не включен (опция CONFIG_NETFILTER = n) или ловушка не установлена, макрос сразу вызовет функцию ip_rcv_finish для дальнейшей обработки пакета.
Цель данной статьи – рассмотреть возможность применения NETFILTER при написании собственных модулей фильтрации сетевого трафика.
Точки перехвата
Рассмотрим схему прохождения пакета по стеку IPv4-протокола (рис.1). Поступивший на сетевой интерфейс пакет попадает в точку PRE_ROUTING. Если пакет адресован локальному хосту, ядро передает его для обработки локальному процессу (точка LOCAL_IN). Если пакет транзитный, из точки PRE_ROUTING он попадает в точку FORWARD и из нее двигается дальше в точку POST_ROUTING. В этой точке объединяются в один поток исходящие пакеты, сформированные локальными процессами (LOCAL_OUT), и транзитные пакеты, поступившие из точки FORWARD.
Рисунок 1. Схема прохождения пакета по стеку Ipv4-протокола
При помощи NETFILTER можно перехватить пакет в любой из этих точек. С этой целью к точке перехвата подключается ловушка (hook).
Если мы хотим отслеживать все пакеты, поступающие на хост (включая транзитные), мы должны подключиться к точке PRE_ROUTING.
Если нас интересуют пакеты, адресованные непосредственно нашему (локальному) хосту, то необходимо подключиться к точке LOCAL_IN и т. д.
Регистрация ловушки
Перед подключением ловушку необходимо зарегистрировать. Это осуществляется путем заполнения структуры nf_hook_ops и вызова функции регистрации ловушки nf_register_hook(). Аргументом этой функции является адрес структуры nf_hook_ops. Структура nf_hook_ops определена в заголовочном файле <linux/netfilter.h>.
Рассмотрим ее:
struct nf_hook_ops
{
struct list_head list;
/* User fills in from here down. */
nf_hookfn *hook;
int pf;
int hooknum;
/* Hooks are ordered in ascending priority. */
int priority;
};
Основные поля структуры:
n nf_hookfn *hook – ловушка, т.е. функция, которая будет вызвана для обработки (анализа) пакета. Именно эта функция решает, что сделать с пакетом – отбросить его или принять.
n int pf – протокол. Для IPv4 это значение равно PF_INET.
n int hooknum – точка подключения ловушки.
n int priority – приоритет. К одной точке может быть подключено несколько ловушек. Чтобы установить порядок их вызова, вводится приоритет. Ловушка с самым низким приоритетом первой обработает пакет.
Прототип функции-ловушки также определен в файле <linux/netfilter.h> и выглядит следующим образом:
typedef unsigned int nf_hookfn(unsigned int hooknum,