Принципы построения Firewalls в операционных системах Windows NT и Linux

Принципы реализации Firewalls, общая структура драйвера, стек протоколов в операционных системах Windows и Linux. Технологии и пользовательский режим сетевой фильтрации трафика. Процедуры отправки и получения данных TCP/IP, точки входа драйверов.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 05.06.2011
Размер файла 2,9 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

1.10 Анализ порядка загрузки драйверов

1.10.1 Порядок загрузки драйверов в различных версиях ОС Windows

Ниже приведены таблицы с результатами исследований относительно порядка загрузки различных драйверов. В первой из них отображен порядок загрузки драйверов группы «PNP_TDI» в таких операционных системах, как WinXP(SP1), WinXP(SP1) + Outpost, WinXP(SP2), Windows 2000 Server(SP4).

Таблица 1.1 Порядок загрузки драйверов группы «PNP_TDI» в различных ОС:

WinXP(SP1)

WinXP(SP1) + Outpost

WinXP(SP2)

Windows 2000 Server(SP4)

1

QoS Packet Scheduler

(psched.sys)

QoS Packet Scheduler

(psched.sys)

IPSEC driver (ipsec.sys)

Generic Packet Classifier (msgpc.sys)

2

IPSEC driver (ipsec.sys)

IPSEC driver (ipsec.sys)

Generic Packet Classifier (msgpc.sys)

TCP/IP Protocol Driver (tcpip.sys)

3

Generic Packet Classifier (msgpc.sys)

Generic Packet Classifier (msgpc.sys)

TCP/IP Protocol Driver (tcpip.sys)

NetBios over Tcpip (netbt.sys)

4

TCP/IP Protocol Driver (tcpip.sys)

TCP/IP Protocol Driver (tcpip.sys)

QoS Packet Scheduler (psched.sys)

NWLink IPX/SPX/NetBIOS Compatible Transport Protocol (nwlnkipx.sys)

5

NetBios over Tcpip (netbt.sys)

NetBios over Tcpip (netbt.sys)

VMware Bridge Protocol (vmnetbridge.sys)

NWLink NetBIOS (nwlnknb.sys)

6

Outpost Firewall Kernel Driver (\??\C:\Program Files\Agnitium\OUTPOST\ kernel\2000\FLTNT.sys)

NetBios over Tcpip (netbt.sys)

QoS Packet Scheduler (psched.sys)

7

MAC Bridge Miniport (bridge.sys)

8

MAC Bridge (bridge.sys)

В таблице 1.2 приведен порядок загрузки драйверов в группе «NDIS»

Таблица 1.2 Порядок загрузки драйверов группы «NDIS» в различных ОС:

WinXP(SP1)

WinXP(SP1) + Outpost

WinXP(SP2)

Windows 2000 Server(SP4)

1

VMware Ethernet Adapter Driver (vmxnet.sys)

VMware Ethernet Adapter Driver (vmxnet.sys)

Driver for VMware's Virtual Ethernet Adapters Ver. 2 (vmnetadapter.sys)

NDIS Usermode I/O Protocol (ndisuio.sys)

2

AMD PCNET Compatable Adapter Driver (pcntpci5.sys)

AMD PCNET Compatable Adapter Driver (pcntpci5.sys)

ATM ARP Client Protocol (atmarpc.sys)

ATM ARP Client Protocol (atmarpc.sys)

3

ATM ARP Client Protocol (atmarpc.sys)

ATM ARP Client Protocol (atmarpc.sys)

NDIS Usermode I/O Protocol (ndisuio.sys)

Intel(R) PRO Adapter Driver (e100bnt5.sys)

4

NDIS Usermode I/O Protocol (ndisuio.sys)

NDIS Usermode I/O Protocol (ndisuio.sys)

NVIDIA nForce Networking Controller DriverDriver (NVENETFD.sys)

5

Microsoft TV/Video Connection (ndisIP.sys)

Описание драйверов:

QoS Packet Scheduler (psched.sys)

Quality of Service(QoS) позволяет приложениям указывать минимальную ширину полосы пропускания и максимальные задержки, которые могут быть удовлетворены только в том случае, если все сетевое программно-аппаратное обеспечение на пути между отправителем и получателем поддерживает стандарты QoS. Поддержка QoS в Windows 2000 основана на наборе Winsock-функций, определенных Microsoft и позволяющих приложениям запрашивать QoS для трафика через свои сокеты Winsock, а также на API управления трафиком (ТС API), который позволяет административным приложениям более точно контролировать трафик через сети.

Центральное место в реализации QoS в Windows 2000 занимает протокол RSVP (Resource Reservation Setup Protocol), представляющий собой Win32-cepвис (\Winnt\System32\Rsvp.exe), как показано на рис. 13-24. Компонент доступа к службе RSVP (\Winnt\System32\Rsvp.dll) передает QoS-запросы приложений через RPC службе RSVP. Та в свою очередь контролирует сетевой трафик с помощью ТС API. ТС API, реализованный в \Winnt\System32\Traffic.dll, посылает команды управления вводом-выводом драйверу GPC (Generic Packet Classifier) (\Winnt\System32\Drivers\Msgpc.sys).

Рис. 1.8 - Архитектура QoS

Generic Packet Classifier (msgpc.sys)

Драйвер GPC -- в тесном взаимодействии с планировщиком пакетов QoS (промежуточным драйвером NDIS) (\Winnt\System32\Drivers\Psched.sys) - контролирует поток пакетов с компьютера в сеть, гарантируя уровни QoS, обещанные конкретным приложениям. При этом он вставляет в пакеты соответствующие заголовки QoS.

IPSEC driver (ipsec.sys)

IP-безопасность (Internet Protocol Security, IPSec) интегрирована со стеком TCP/IP и обеспечивает защиту IP-данных от перехвата и несанкционированных манипуляций, а также оборону от сетевых атак. Обе цели реализуются за счет сервисов защиты на основе шифрования, протоколов безопасности и динамического управления ключами. Для защищенной коммуникационной связи IPSec поддерживает следующую функциональность:

- аутентификацию -- проверку подлинности источника IP-сообщения;

- целостность -- защиту IP-данных от несанкционированного изменения при передаче, обеспечивающую получение информации в том виде, в каком она была отправлена;

- конфиденциальность -- содержимое сообщения может быть расшифровано только указанным адресатом;

- защиту от повторений -- гарантирует уникальность каждого IP-пакета и невозможность его повторного использования. Злоумышленник, перехватывая IP-пакеты, не может повторно использовать их для установления сеанса или незаконного получения информации.

Поддержка IPSec включает драйвер IPSec (\Winnt\System32\Drivers\Ipsec.sys), интегрируемый с драйвером TCP/IP. Агент политики в пользовательском пространстве получает информацию о конфигурации IPSec из Active Directory и передает информацию о фильтрации IPSec (фильтры IP-адресов, для которых следует использовать защищенную коммуникационную связь) драйверу IPSec, a параметры защиты -- модулю Internet Key Exchange (IKE). Модуль IKE ожидает от драйвера IPSec запросов на сопоставление безопасности и согласовывает их, возвращая ему результаты для использования при аутентификации и шифровании.

Драйвер TCP/IP (tcpip.sys)

Драйвер TCP/IP (tcpip.sys) реализует TCP, UDP, IP, ARP, ICMP, IGMP. TDI-транспорты обычно создают объекты-устройства, реализующие конкретный протокол так, чтобы клиенты могли открыть объект-файл, представляющий протокол, и выдать сетевой запрос ввода/вывода этому протоколу, используя IPR-пакеты. TCP/IP-драйвер создает три объекта-устройства, которые представляют различные протоколы: \Device\Tcp, \Device\Udp, \Device\Ip.

NetBios over Tcpip (netbt.sys)

NetBIOS полагается на соглашение об именах, согласно которому компьютерам и сетевым сервисам назначаются 16-байтные имена, называемые NetBIOS-именами. Сетевой сервис WINS (Windows Internet Name service) поддерживает отображение между NetBIOS-именами и адресами протокола TCP/IP. NetBIOS-функции, как и Net-функции, экспортируются приложениям библиотекой Netapi32.dll. Эта библиотека открывает описатель драйвера уровня ядра, называемого эмулятором NetBIOS - NetBIOS.sys (драйвер файловой системы NetBIOS), и вызывает функцию DeviceloControl по команде приложения. Эмулятор NetBIOS транслирует NetBIOS-команды, выданные приложениями, в TDI-команды, которые посылаются драйверам протоколов. NetBIOS поверх TCP/IP - это сетевой сервис сессионного уровня, который выполняет отображение имен в IP-адреса. Если приложение хочет использовать NetBIOS поверх протокола TCP/IP, эмулятор NetBIOS требует присутствия драйвера NetBT.sys. Этот драйвер отвечает за поддержку семантики NetBIOS, присущей протоколу NetBEUI, а не протоколу TCP/IP. NetBIOS полагается на передачу NetBEUI-сообщений и средство разрешения имен NetBIOS, поэтому драйвер NetBT реализует их в вершине протокола TCP/IP. Подобно этому, драйвер NwLinkNB реализует семантику NetBIOS поверх протокола IPX/SPX.

Рис. 1.9 - Интерфейс NetBIOS

Драйвер FLTNT.sys

При применении firewall Outpost Firewall Pro основную часть работы по защите компьютера берет на себя filtnt.sys - драйвер режима ядра. Этот модуль является сердцем firewall, он также реализует систему плагинов (расширений), что обеспечивает наращивание функциональности, без существенного изменения самого ядра.

NWLink IPX/SPX/NetBIOS Compatible Transport Protocol (nwlnkipx.sys)

Протокол Internetwork Packet Exchange/Sequenced Packet Exchange (IPX/SPX) используется в ОС NetWare фирмы Novell. Реализация этого протокола фирмой Microsoft называется NWLink. IPX/SPX базируется на протоколе Xerox Network System (XNS), разработанном Xerox Corp. Протокол XNS, который больше не используется, определял коммуникационные уровни от физического до прикладного. Novell использовала часть этого стека, а именно два компонента: IDP (Internet Datagram Protocol) and SPP (Sequenced Packet Protocol). IPX (nwlnkipx.sys) базируется на IDP, SPX (nwlnkspx.sys) - на SPP.

IPX/SPX - высокопроизводительный протокол для локальных сетей, и легче реализуется и администрируется, чем TCP/IP. Как и TCP/IP IPX/SPX является маршрутизируемым, и, следовательно, может использоваться для реализации глобальных сетей.

NWLink NetBIOS (nwlnknb.sys)

В Windows NT существует также встроенный протокол NWLink NetBIOS (nwlnknb.sys), который предоставляет возможность пересылки Novell NetBIOS-пакетов между NetWare-сервером, исполняющим Novell NetBIOS, и Windows NT компьютером, или между двумя Windows NT компьютерами.

MAC Bridge Miniport (bridge.sys)

MAC Bridge Miniport является сетевым мостом для Windows XP. Функция сетевого моста позволяет объединить устройства различных типов в единую локальную вычислительную сеть.

VMware Bridge Protocol (vmnetbridge.sys)

Данный драйвер поддерживает функцию сетевого моста VMware. Служит для организации локальной сети между виртуальной машиной и локальным компьютером.

VMware Ethernet Adapter Driver (vmxnet.sys)

Драйвер сетевой карты VMware.

AMD PCNET Compatable Adapter Driver (pcntpci5.sys)

Драйвер сетевой карты.

NVIDIA nForce Networking Controller DriverDriver (NVENETFD.sys)

Драйвер сетевой карты.

Intel(R) PRO Adapter Driver (e100bnt5.sys)

Драйвер сетевой карты.

ATM ARP Client Protocol (atmarpc.sys)

ATM - Asynchronous Transfer Mode (ATM) (протокол асинхронного режима передачи) - протокол, ориентированный на передачу голоса, видео. ATM - высокоскоростная сетевая технология, которая обеспечивает передачу данных фрагментами фиксированной длины.

IP поверх ATM - небольшой уровень между ATM и TCP/IP протоколами. Клиент эмулирует стандартный IP в TCP/IP протокол на его верхней границе и использует родные ATM команды в своей нижней части. IP over ATM поддерживается двумя компонентами: IP поверх ATM сервер (Atmarps.sys) и IP поверх ATM клиент (Atmarpc.sys). Оба сервиса поддерживают базу данных IP адресов. IP поверх ATM сервер сформирован ATMARP сервером и Multicast Address Resolution Service (MARS). Оба сервиса поддерживают базу данных IP адресов.

NDIS Usermode I/O Protocol (ndisuio.sys)

Это драйвер протокола, который поддерживает отправку и получение Ethernet кадров используя ReadFile и WriteFile. NDISUIO получает доступ к NDIS устройствам процессам через IOCTL_NDISUIO_OPEN_DEVICE, и получает только те кадры, которые имеют тип NDIS_MEDIUM.

Microsoft TV/Video Connection (ndisIP.sys)

NdisIP.sys минипорт драйвер устанавливается как виртуальный NDIS минипорт. Отсылает IP данные к NDIS.

1.11 Точки интеграции Firewalls

Рис. 1.10 - Точки интеграции драйверов-фильтров

1 - Данный вариант можно использовать, когда необходимо обеспечить безопасный обмен данными по сети между приложениями, использующими конкретный транспортный протокол, или анализ трафика по этому протоколу. Например, можно устанавливать фильтры на устройства:

\Device\RawIp, \Device\Udp, \Device\Tcp, \Device\Ip.

Минус данного варианта в том, что невозможно отследить обмен данными по сети между всеми приложениями.

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

На данном уровне возможна реализация шифрования, мониторинга сети.

3 - Данный метод является очень эффективным. В данном случае заменяются адреса необходимых функций библиотеки NDIS (NdisRegisterProtocol, NdisDeregisterProtocol, NdisOpenAdapter, NdisCloseAdapter), в результате чего можно получить контроль над всеми сетевыми операциями в системе. Можно будет проследить загрузку сетевого драйвера, а затем, установив адреса своих обработчиков для точек входа MiniportXxx-процедур и ProtocolXxx-процедур контролировать все сетевые операции ввода/вывода, проходящие через него.

Но важно, что реализуемому драйверу, который должен заменить адреса NDIS-функций в таблице экспорта библиотеки NDIS на адреса собственных обработчиков, следует загружаться сразу после загрузки драйвера Ndis.sys. Иначе, к моменту загрузки вашего драйвера может уже произойти инициализация некоторых сетевых драйверов.

К минусам данного метода можно отнести недокументированность этой реализации.

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

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

Можно сделать кое-какие выводы по поводу интеграции firewalls.

От расположения средства защиты (в нашем случае Firewall) относительно иерархии сетевых компонентов, зависит количество проходящих через это средство данных, и следовательно, возможность контроля и защиты этих данных. В 1ом случае есть возможность контроля только данных приложений, использующих этот транспорт и взаимодействующих с другими транспортами напрямую. Во 2-ом контролируются данные приложений, использующих транспорты, привязанные снизу к этому промежуточному драйверу и приложений, взаимодействующих с этим промежуточным драйвером напрямую. В 3-ем и 4-ом случае существует возможность контроля данных всех приложений.

2. Анализ open-source firewall tdi_fw

2.1 Параметры реестра вносимые open-source firewall tdi_fw

Рис. 2.1 - Сведения из реестра ветка [HKEY_LOCAL_MACHINE\ SYSTEM\ CurrentControlSet\Services\tdifw_drv]

Проанализируем эти сведения.

Итак, параметр "Start"=dword:00000001;

"Start" == 1 - драйверы первого кольца (SERVICE_SYSTEM_START)

загружаются при инициализации ядра модулем ntoskrnl.exe (самим ядром).

"Group"="PNP_TDI" - относится к драйверам группы pnp_tdi.

"Tag"=dword:0000000d(13). В нашем случае (XP SP2) параметр "Tag" показывает на порядок загрузки в группе. Просмотрев ветку [HKEY_LOCAL_MACHINE\ SYSTEM\CurrentControlSet\Control\GroupOrderList] видно, что данный драйвер стартует после ipsec.sys, tcpip.sys, но перед netbt.sys и ws2ifsl.sys.

Можно сделать выводы, что данный драйвер загружается диспетчером ввода-вывода после инициализации компонентов исполнительной системы, но после драйверов ipsec и tcpip и перед драйвером netbt.

Ниже будет приведен программный код, в котором и осуществляется инсталляция и внедрение драйвера tdifw_drv.sys между tcpip.sys и netbt.sys

2.2 Взаимодействие драйвера tdifw с транспортом

Рис 2.2. - Порядок загрузки драйверов в группе “PNP_TDI” до и после инсталляции драйвера tdifw_drv

Инсталляция драйвера:

1. При помощи функции CreateService происходит установка нашего драйвера в систему tdifw_drv.sys. Вместе с этой функцией передаются параметры DRIVER_NAME, DRIVER_GROUP, &tdifw_tag и т.д.

2. Получаем значение ключевого поля GroupOrderList при помощи функции RegOpenKey(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\GroupOrderList", &reg_key);

3. Резервируем место для 3-х новых значений Tag (tcpip, tdi_fw, netbt).

n = sizeof(tags) - sizeof(DWORD) * 3;

Функция RegQueryValueEx(reg_key, DRIVER_GROUP, NULL, &type, (LPBYTE)tags, &n) выдает список Tag для конкретной группы драйверов, в нашем случае - группы “PNP_TDI”.

4. Затем нехитрым методом получив значение Tag для драйверов tcpip и netbt, присваиваем нашему драйверу такое значение Tag, чтобы он встраивался между ними. Таким образом наш драйвер устанавливается после tcpip, но перед netbt.

Деинсталляция:

Деинсталляция драйвера осуществляется путем удаления параметра tag, соответствующего нашему драйверу, из реестра.

Стек драйверов:

Стек организован порядком загрузки драйверов.

Для объединения драйверов в стек используется функция IoGetDeviceObjectPointer. Функция вызывается драйвером вышележащего уровня для получения указателя на объект-устройство драйвера нижележащего уровня по его имени.

IoGetDeviceObjectPointer(&str, FILE_ALL_ACCESS, &fileobj, devobj);

где &str- имя требуемого объекта-устройства;

FILE_ALL_ACCESS - требуемый доступ к объекту-устройству;

&fileobj - указатель на объект-файл, который будет использоваться для обращения к устройству;

Devobj - указатель на объект-устройство с именем &str

Если надо передать пакет с более высокого уровня на более низкий, вызывается функция IoCallDriver

IoCallDriver(devobj, irp)

Где 1-ый параметр - указатель на объект-устройство, принадлежащий драйверу нижележащего уровня в стеке драйверов, которому должен быть послан запрос;

2ой- указатель на irp, который будет послан драйверу нижележащего уровня.

При помощи функции IoAttachDevice драйвер привязывается к стеку

status = IoAttachDevice(*fltobj, &str, oldobj);

здесь: *fltobj - указатель на объект-устройство драйвера фильтра;

&str- имя устройства, к которому будет прикреплен объект-устройство драйвера фильтра;

oldobj- объект-устройство, к которому прикрепляется объект-устройство драйвера фильтра.

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

Передача пакетов осуществляется только от вышестоящих драйверов к нижестоящим.

Выгрузка драйвера-фильтра происходит с помощью ф-ции IoDetachDevice(oldobj);

Events(События)

Для сигнализации об интересующих клиента событиях, драйвер транспорта может вызывать функции, указатели на которые передаются клиентом-TDI драйверу транспорта в самом начале сетевых операций в пакете IRP_MJ_INTERNAL_DEVICE_CONTROL с контрольным кодом TDI_SET_EVENT_HANDLER, и регистрируются драйвером транспорта.

Опишем более подробно работу с событиями:

Вышестоящий драйвер(например, netbt) создает объект Event.

Затем формирует пакет TDI_SET_EVENT_HANDLER и передает его в драйвер tcpip (на более низкий уровень). Драйвер tcpip регистрирует Event у себя во внутренних структурах данных. Когда происходит это событие, tcpip устанавливает Event. И вышестоящий драйвер формирует запрос и передает его в tcpip.

Вот список этих событий, на которые реагирует tcpip:

1) TDI_EVENT_CONNECT:

Вызывается, когда запрашивается конечное соединение от удаленного хоста.

2) TDI_EVENT_DISCONNECT

Вызывается, когда установленное конечное соединение закрывается удаленным хостом.

3) TDI_EVENT_RECEIVE_DATAGRAM

Вызывается, когда приходит дейтаграмма от удаленного узла, после чего транспорт предоставляет клиенту возможность скопировать полностью или частично данный буферизованный блок данных(TSDU)

4) TDI_EVENT_RECEIVE

Вызывается, когда приходит обычный пакет данных от удаленного узла, после чего транспорт предоставляет клиенту возможность скопировать полностью или частично данный буферизованный блок данных(TSDU)

5) TDI_EVENT_RECEIVE_EXPEDITED

Вызывается когда происходит получение срочных данных от удаленного узла, после сего транспорт предоставляет клиенту возможность скопировать полностью или частично данный буферизованный блок данных(TSDU)

6) TDI_EVENT_CHAINED_RECEIVE

Вызывается когда приходят обычные данные от удаленного узла и транспорт может предоставить этому клиенту только права на чтение полного буферизованного блока данных(TSDU), до тех пор, пока клиент не вызовет TdiReturnChainedReceives с TsduDescriptor.

7) TDI_EVENT_CHAINED_RECEIVE_EXPEDITED

Вызывается когда получены срочные данные от удаленного узла и транспорт может предоставить этому клиенту только права на чтение полного буферизованного блока данных(TSDU), до тех пор, пока клиент не вызовет TdiReturnChainedReceives с TsduDescriptor.

Функционирование драйвера:

В данном Firewall реализовано 2 механизма защиты:

1. Перехват обращений к устройствам Device\Tcp, Device\Udp, Device\RawIp

2. Подмена указателей функции диспетчеризации на свои функции.

Рис. 2.3 - Перехват обращений к устройствам Device\Tcp, Device\Udp, Device\RawIp

Подмена указателей функции диспетчеризации на свои функции.

При помощи функции ObReferenceObjectByName получаем указатель на объект драйвер. В нашем случае на драйвер tcpip(L"\\Driver\\Tcpip").

Для каждого устройства регистрируются функции диспетчеризации. То есть, заменив их на свои, можно спокойно регистрировать все запрашиваемые действия, например, на получение и отправку данных. И в соответствии с нашими требованиями решать разрешать или запрещать эти действия.

DeviceDispatch работает с кодами ввода/вывода(ioctls) и управляет устройством.

Предварительно сохранив оригинальные функции, происходит замена указателей ф-ций диспетчеризации на новые.

DeviceDispatch вешается на все функции. После чего можно отслеживать и регистрировать все действия данных функций.

Рис. 2.4 - Подмена указателей функции диспетчеризации на свои функции

Функции диспетчеризации, используемые в данном Firewall:

1) tdi_associate_address - Когда клиент режима ядра выдает запрос TDI_ASSOCIATE_ADDRESS, он просит нижележащий TDI транспорт (драйвер транспортного протокола) связать определенный открытый адрес локального узла с конечной точкой соединения.

2) tdi_connect - Когда клиент режима ядра выдает запрос TDI_CONNECT, он просит нижележащий TDI транспорт (драйвер транспортного протокола) организовать связь между конечной точкой локального узла и удаленным узлом.

3) tdi_disassociate_address - Когда клиент режима ядра выдает запрос TDI_DISASSOCIATE_ADDRESS, он просит нижележащий TDI транспорт разорвать установившуюся связь между определенным открытым адресом локального узла и конечной точкой соединения.

4) tdi_set_event_handler - когда клиент режима ядра выдает запрос TDI_SET_EVENT_HANDLER, он просит нижележащий TDI транспорт (драйвер протокола) вызвать специализированную ClientEventXxx процедуру всякий раз, когда происходит соответствующее сетевое событие.

5) tdi_send_datagram - Когда клиент TDI выдает запрос TDI_SEND_DATAGRAM, он просит нижележащий TDI транспорт (драйвер протокола) передать TSDU, как дейтаграмму, на надлежащий адрес удаленного узла.

6) tdi_receive_datagram - Когда клиент режима ядра выдает запрос TDI_RECEIVE_DATAGRAM, он просит нижележащий TDI транспорт (драйвер протокола) отобразить TSDU, как дейтаграмму, по надлежащему адресу.

7) tdi_disconnect - Когда клиент режима ядра выдает запрос TDI_DISCONNECT, он просит нижележащий TDI транспорт осуществить указание отключения от удаленного узла, и получить подтверждение разрыва соединения с удаленным узлом.

8) tdi_send - Когда клиент TDI выдает запрос TDI_SEND, он просит нижележащий TDI транспорт осуществить передачу обычного или срочного TSDU на определенную точку соединения удаленного узла.

9) tdi_receive - Когда клиент TDI выдает запрос TDI_RECEIVE, он просит нижележащий TDI транспорт отобразить обычный или срочный TSDU установленного конечного соединения.

10) tdi_accept - Когда клиент TDI выдает запрос TDI_ACCEPT, он просит нижележащий драйвер транспортного протокола подтвердить входящее предложение соединения от удаленного узла, для создания возможности передачи сетевых данных между клиентом локального узла и удаленным узлом.

11) tdi_listen - Когда клиент режима ядра выдает запрос TDI_LISTEN, он просит нижележащий драйвер транспортного протокола ждать предложения создания соединения от удаленного узла.

При помощи данного программного кода осуществляется процесс установки драйвера tdifw_drv.sys

Тут также устанавливается порядок загрузки нашего драйвера между tcpip.sys & netbt.sys

Код взят из файла tdi_install.c

#include <windows.h>

#include <stdio.h>

static void install_driver(void);

static void uninstall_driver(void);

int

main(int argc, char **argv)

{

if (argc!= 2) {

fprintf(stderr, "use: %s install|remove\n", argv[0]);

return 0;

}

if (strcmp(argv[1], "install") == 0)

install_driver();

else if (strcmp(argv[1], "remove") == 0)

uninstall_driver();

else

fprintf(stderr, "Invalid command line! \"%s\" is not \"install\" or \"remove\"\n", argv[1]);

return 0;

}

#define DRIVER_NAME "tdifw_drv" //описание для подстановки

#define DRIVER_BINARY "system32\\drivers\\tdifw_drv.sys"

#define DRIVER_GROUP "PNP_TDI"

#define DRIVER_DEPENDS "tcpip\0\0"

#define swap_dword(a, b) \

do { \

DWORD c =(a); \

(a) = (b); \

(b) = c; \

} while(0)

//функция инсталляции драйвера

void

install_driver(void)

{

SC_HANDLE sch, tdifw, tcpip, netbt;

DWORD tdifw_tag, tcpip_tag, netbt_tag, n, tags[100], type, i;

char buf[2048];

QUERY_SERVICE_CONFIG *cfg = (QUERY_SERVICE_CONFIG *)buf;

HKEY reg_key;

LONG status;

int n_type;

BOOL has_tcpip, has_netbt, has_tdifw;

// сама инсталляция драйвера

sch = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

if (sch == NULL) {

fprintf(stderr, "OpenSCManager: %d\n", GetLastError());

return;

}

tdifw = CreateService(sch, // база данных sch

DRIVER_NAME, //при подстановке имя у нас "tdifw_drv"

DRIVER_NAME, // отображаемое имя "tdifw_drv"

SERVICE_ALL_ACCESS, // доступ

SERVICE_KERNEL_DRIVER, // тип сервиса

SERVICE_SYSTEM_START, // тип запуска

SERVICE_ERROR_NORMAL, //если драйвер сообщает об ошибке, выводится предупреждение

DRIVER_BINARY, //заменяется на "system32\\drivers\\tdifw_drv.sys"

DRIVER_GROUP, // в нашем случае "PNP_TDI"

&tdifw_tag, //параметр Tag

DRIVER_DEPENDS, // "tcpip\0\0"

NULL,

NULL

);

if (tdifw == NULL) {

fprintf(stderr, "CreateService: %d\n", GetLastError());

return;

}

// Получаем значение tag для tcpip

tcpip = OpenService(sch, "tcpip", SERVICE_ALL_ACCESS);

if (tcpip == NULL) {

fprintf(stderr, "OpenService(tcpip): %d\n", GetLastError());

return;

}

if (!QueryServiceConfig(tcpip, cfg, sizeof(buf), &n)) {

fprintf(stderr, "QueryServiceConfig(tcpip): %d\n", GetLastError());

return;

}

tcpip_tag = cfg->dwTagId;

// Получаем значение tag для netbt

netbt = OpenService(sch, "netbt", SERVICE_ALL_ACCESS);

if (netbt == NULL) {

fprintf(stderr, "OpenService(netbt): %d\n", GetLastError());

return;

}

if (!QueryServiceConfig(netbt, cfg, sizeof(buf), &n)) {

fprintf(stderr, "QueryServiceConfig(tcpip): %d\n", GetLastError());

return;

}

netbt_tag = cfg->dwTagId;

// изменяются значения поля tag

// 1. tcpip

// 2. tdifw

// 3. netbt

// получаем значение из реестра

status = RegOpenKey(HKEY_LOCAL_MACHINE,

"SYSTEM\\CurrentControlSet\\Control\\GroupOrderList", &reg_key);

if (status!= ERROR_SUCCESS) {

fprintf(stderr, "RegOpenKey: %d\n", status);

return;

}

n = sizeof(tags) - sizeof(DWORD) * 3; // резервируем место для 3х новых значений

status = RegQueryValueEx(reg_key, DRIVER_GROUP, NULL, &type, (LPBYTE)tags, &n);

if (status!= ERROR_SUCCESS) {

fprintf(stderr, "RegQueryValueEx: %d\n", status);

return;

}

// находим номер каждого

n /= sizeof(DWORD);

// пытаемся найти tag для tdifw, если не находится, добавляем

has_tdifw = FALSE;

for (i = 1; i < n; i++)

if (tags[i] == tdifw_tag) {

has_tdifw = TRUE;

break;

}

if (!has_tdifw)

tags[n++] = tdifw_tag;

has_tcpip = has_netbt = FALSE;

n_type = 1;

for (i = 1; i < n; i++)

if (tags[i] == tcpip_tag || tags[i] == netbt_tag || tags[i] == tdifw_tag) {

switch (n_type) {

case 1:

// 1. tcpip

tags[i] = tcpip_tag;

has_tcpip = TRUE;

break;

case 2:

// 2. tdifw

tags[i] = tdifw_tag;

break;

case 3:

// 3. netbt_tag

tags[i] = netbt_tag;

has_netbt = TRUE;

break;

}

n_type++;

}

if (!has_tcpip) {

printf("Warning! tcpip with tag %d not found! Trying to restore registry GroupOrderList key...\n", tcpip_tag);

// вставляем в начало списка

memmove(&tags[1], &tags[2], (n - 1) * sizeof(DWORD));

tags[1] = tcpip_tag;

n++;

}

if (!has_netbt) {

printf("Warning! netbt with tag %d not found! Trying to restore registry GroupOrderList key...\n", netbt_tag);

// добавляем в конец списка

tags[n++] = netbt_tag;

}

tags[0] = n - 1;

// сохраняем новый порядок

status = RegSetValueEx(reg_key, DRIVER_GROUP, 0, type, (LPBYTE)tags, n * sizeof(DWORD));

if (status!= ERROR_SUCCESS) {

fprintf(stderr, "RegSetValueEx: %d\n", status);

return;

}

// ok

RegCloseKey(reg_key);

CloseServiceHandle(tcpip);

CloseServiceHandle(tdifw);

CloseServiceHandle(netbt);

CloseServiceHandle(sch);

printf("success\n");

}

//удаление драйвера

void

uninstall_driver(void)

{

SC_HANDLE sch, service;

DWORD tags[100], n, type, i, service_tag;

char buf[2048];

HKEY reg_key;

QUERY_SERVICE_CONFIG *cfg = (QUERY_SERVICE_CONFIG *)buf;

int status;

sch = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

if (sch == NULL) {

fprintf(stderr, "OpenSCManager: %d\n", GetLastError());

return;

}

// получаем tag драйвера

service = OpenService(sch, DRIVER_NAME, SERVICE_ALL_ACCESS);

if (service == NULL) {

fprintf(stderr, "OpenService: %d\n", GetLastError());

return;

}

if (!QueryServiceConfig(service, cfg, sizeof(buf), &n)) {

fprintf(stderr, "QueryServiceConfig(tcpip): %d\n", GetLastError());

return;

}

service_tag = cfg->dwTagId;

// удаляем tag из реестра

status = RegOpenKey(HKEY_LOCAL_MACHINE,

"SYSTEM\\CurrentControlSet\\Control\\GroupOrderList", &reg_key);

if (status!= ERROR_SUCCESS) {

fprintf(stderr, "RegOpenKey: %d\n", status);

return;

}

n = sizeof(tags);

status = RegQueryValueEx(reg_key, DRIVER_GROUP, NULL, &type, (LPBYTE)tags, &n);

if (status!= ERROR_SUCCESS) {

fprintf(stderr, "RegQueryValueEx: %d\n", status);

return;

}

n /= sizeof(DWORD);

for (i = 1; i < n; i++)

if (tags[i] == service_tag) {

memmove(&tags[i], &tags[i + 1], (n - i - 1) * sizeof(DWORD));

n--;

break;

}

tags[0] = n - 1;

status = RegSetValueEx(reg_key, DRIVER_GROUP, 0, type, (LPBYTE)tags, n * sizeof(DWORD));

if (status!= ERROR_SUCCESS) {

fprintf(stderr, "RegSetValueEx: %d\n", status);

return;

}

RegCloseKey(reg_key);

// удаляем сервис

if (!DeleteService(service)) {

if (GetLastError()!= ERROR_SERVICE_MARKED_FOR_DELETE) {

fprintf(stderr, "DeleteService: %d\n", GetLastError());

return;

}

printf("Restart Windows to changes has effect\n");

}

CloseServiceHandle(service);

CloseServiceHandle(sch);

printf("success\n");

}

3. Принципы реализации Firewalls в Linux

3.1.1 Структура стека протоколов TCP/IP под Linux

Сетевая подсистема ОС Linux состоит из большого числа компонентов, относящиеся к уровням модели OSI с канального по транспортный. Основной единицей данных в сетевой подсистеме ОС Linux является структура sk_buff, представляющая собой кадр канального уровня с выделенными заголовками канального, сетевого и транспортного уровней и блоком данных сеансового уровня. Также там содержится информация об устройстве, через которое пакет был принят или должен быть отправлен, флаги правильности контрольной суммы и прочая служебная информация.

Стек протоколов Linux является частью ядра и встроен в код ядра. Структура стека протоколов позволяет поддерживать несколько протоколов в одно и то же время. На рисунке 1 показана сетевая архитектура Linux.

Рис. 3.1 - Архитектура стека протоколов Linux

Эта архитектура позволяет поддерживать многосетевые протоколы в ядре Linux. Протокол TCP/IP состоит из 5 уровней:

1) SOCKET

2) INET

3) TCP(UDP)

4) IP

5) Network device driver (уровень сетевых драйверов устройств)

Уровень SOCKET является интерфейсом между программными приложениями и нижними уровнями, он скрывает разницу между разнообразными сетевыми протоколами и программными приложениями.

3.1.2 Канальный уровень - драйвер сетевого устройства

На нижнем уровне сетевой подсистемы работают сетевые устройства. Каждое устройство представляет собой структуру net_device и содержит указатели на функции отправки кадров, изменение параметров устройства, получение статистики. Кроме того, каждое устройство содержит процедуру инициализации и удаления (последняя применяется только для устройств, скомпилированных в качестве модулей ядра, для устройств, встроенных в ядро, она никогда не вызывается). Также драйвер устройства содержит набор процедур, специфичных для устройства и недоступных извне.

При инициализации устройства в список сетевых устройств, хранящихся в ядре, с помощью функции register_netdev() добавляется новый экземпляр структуры net_device. Затем драйвер захватывает себе определенные аппаратные прерывания, в первую очередь - прерывание по приходу нового кадра. Среди процедур драйвера имеется обработчик прерывания, который привязывается к захваченному прерыванию.

Всякий раз, когда модуль ядра загружается в память, он начинает запрашивать необходимые для своего функционирования ресурсы, такие как порты ввода/вывода, векторы прерываний и т.п. Аналогично, в момент регистрации драйвера, он размещает структуры данных, соответствующие каждому из обнаруженных сетевых интерфейсов, в глобальном списке сетевых устройств.

Каждый интерфейс определяется структурой struct net_device. Так, например, объявление устройства rtl8139 будет выглядеть следующим образом:

struct net_device rtl8139 = {init: rtl8139_init};

Определение структуры struct net_device находится в заголовочном файле linux/net_device.h. Код, представленный выше, инициализирует только одно поле структуры -- 'init', что соответствует функции инициализации модуля драйвера. Всякий раз, когда происходит регистрация устройства, ядро вызывает эту функцию, а она, в свою очередь, должна инициализировать аппаратную часть устройства и заполнить поля структуры struct net_device. Сама по себе структура struct net_device достаточно велика и содержит ссылки на все функции, необходимые для обеспечения взаимодействия с аппаратурой.

Далее опишем структуру sk_buf, процедуру отправки и получения данных TCP/IP, организацию очереди TCP/IP протокола Linux, а также взаимодействие стека протоколов с операционной средой.

3.1.3 Организация SK_BUF

Организация буферизации данных сетевого протокола Linux называется sk_buff. Структура sk_buff является основной единицей данных в сетевой подсистеме ОС Linux, представляющая собой кадр канального уровня с выделенными заголовками канального, сетевого и транспортного уровней и блоком данных сеансового уровня. Также там содержится информация об устройстве, через которое пакет был принят или должен быть отправлен, флаги правильности контрольной суммы и прочая служебная информация.

Структура sk_buff определяет набор полей данных, которые используются ядром Linux при обработке сетевых пакетов. Принятые сетевыми интерфейсами пакеты помещаются в буферы sk_buff, которые передаются сетевому стеку, использующему буфер в течение всего процесса обработки пакета.

В многоуровневых протоколах, таких как TCP/IP заголовок более высоких уровней добавляется к данным, когда они проходят от с высокого уровня на более низкий, и заголовок нижнего уровня отбрасывается когда данные следуют от нижнего уровня к верхнему.

Основное преимущество sk_buff структуры, описание которой находится в файле /usr/include/linux/skbuff.h, заключается в предоставлении совместимого и эффективного метода обработки буфера на всех сетевых уровнях. Эта совместимость дает право всем протоколам поддерживать средства сокетной обработки, а также предоставляет всем протоколам возможности sk_buff более высоких уровней.

Отличительная черта структуры sk_buff заключается в том факте, что sk_buff - управляющая структура с присоединенным блоком памяти. Существует две основные функциональные составляющие, предусмотренные в библиотеке sk_buff. Первая - процедура управлении списками sk_buff с двойной связью. Вторая - функции по управлению присоединенной памятью. Буферы, находятся в связанных списках, оптимизированных для общих сетевых операций добавления в конец и удаления из начала. Так как большая сетевая функциональность приходится в моменты прерываний, эти процедуры выполняются автоматически. Целый список операций используется для управления датаграмами (или пакетами) по их прибытию из сети, и когда они отсылаются физическим интерфейсам. С другой стороны, процедура управления памятью используется для поддержания содержимого пакетов в стандартизированном и рациональном виде.

Рис. 3.2 - Обычное расположение структур sk_buff.

3.1.4 Процедуры отправки и получения данных TCP/IP

Процедура отправки и получения данных абсолютно идентична для TCP и UDP. Единственная разница в процессе обработки TCP и UDP уровней. Итак, покажем всю процедуру на примере UDP. Рисунок 3 показывает процедуру отправки и получения. Эта процедура может быть разделена на 5 частей описанных ниже:

1) уровень SOCKET. Это интерфейс между приложениями и ядром. Он реализовывает системные сокетные вызовы от операционной системы. Уровень SOCKET активизирует сопутствующие нижнему уровню функции с параметрами, предоставляемыми пользовательскими программами. В случае с TCP/IP нижним слоем SOCKET является INET.

Рис. 3.3 - Процедуры отправки и получения UDP пакетов

2) уровень INET. Его функция заключается в предоставлении объединенного интерфейса для TCP и UDP.

3) TCP, UDP уровень. Протоколы TCP и UDP реализованы тут. TCP более сложный и он требует операции установления соединения, в то время как, UDP, нет.

4) уровень IP. Он реализует IP протокол. Уровень IP - ключевой компонент TCP/IP стека протоколов. Его основные задачи - сегментация и сборка IP пакетов, создание sk_buf, просмотр таблиц маршрутизации, выстраивание в очередь и буферизация IP пакетов, распределение и направление IP пакетов и т.д. Еще ряд функций реализуется на IP уровне: учет сетевых ресурсов, фильтрация, маскарадинг.

5) Уровень сетевых драйверов-устройств. Его функции очень просты: отправка данных от IP уровня к физической среде и получение данных от физической линии и предоставление их IP уровню. Можно добавить, что в Linux принципам уровневых протоколов не придерживаются уж очень строго. Уровень TCP выполняет некоторую работу IP, например, просмотр таблицы маршрутизации, сегментацию пакетов. А часть работы UDP, такая как, подсчет контрольной суммы выполняется на уровне IP при помощи обратного вызова процедур предоставляемых UDP.

Другие отличия в реализации TCP и UDP в том, что для UDP отправляемая пользовательская информация копируется из пользовательского режима в режим ядра на уровне IP при помощи обратного вызова процедур UDP, а для TCP копирование осуществляется на уровне TCP.

Итак, если упростить, то получение кадра выглядит следующим образом - сетевая карта (физическое устройство) получает кадр данных и посылает прерывание. Вызывается обработчик, который из определенных участков памяти читает полученную информацию. Затем этот кадр (возможно за несколько этапов) разбивается на части и загружается в структуру sk_buff. Готовая структура с помощью вызова netif_rx() передается на верхние уровни.

Для отправки кадра ядро вызывает процедуру аппаратной отправки, указатель на которую прописан в структуре net_device под именем hard_start_xmit() и передает в нее указатель на структуру sk_buff, содержащую кадр, который требуется передать. После отправки кадра, драйвер удаляет его и освобождает память.

3.1.5 Организация очереди TCP/IP протокола Linux

TCP/IP- протокол с промежуточным хранением данных, и в данном стеке протоколов, существует такое понятие как очередь. Размещение и граничная длина очереди, обработка необработанных пакетов, планирование, будет влиять на эффективность протокола, и также обуславливать возможность поддержки QoS.

На рисунке 3.4 представлена модель организации очереди TCP/IP протокола в Linux. Очереди организованы в двух местах на отсылающей и получающей стороне стека протоколов соответственно. Для TCP существует 2 очереди на отправляющей стороне, которые находятся на уровне TCP и уровне сетевых драйверов-устройств, и две очереди на получающей стороне, которые расположены на IP уровне и TCP уровне. Очереди UDP отличные от TCP, на уровне UDP нет очередей, потому что нет необходимости в управлении потоками. Очереди на TCP(UDP) уровне основаны на общем количестве байт, а очереди на IP уровне и уровне драйверов устройств на количестве пакетов. Очереди на TCP(UDP) существуют для буферизации и управления потоком данных(только для TCP). Очередь на отправляющей стороне сетевого драйвера предназначена для временной буферизации данных, когда скорость генерации пакетов IP уровня превышает скорость отправки с физического устройства. Максимальное количество пакетов для каждого драйвера устройства - tx_queue_len. На принимающей стороне все полученные пакеты собираются в так называемые backlog очереди. Все драйверы устройств имеют уникальную собственную исходящую очередь, но, в то же время, одну общую входящую backlog очередь. Максимальный размер входящей backlog очереди равен 300. Дальше мы увидим, что это достаточно большое значение, потому что на уровне IP вообще нет очереди на принимающей стороне.

Рис. 3.4 - Модель организации очереди TCP/IP протокола в Linux

При получении кадра вызов netif_rx() помещает кадр в общую очередь, откуда его извлекает процедура process_backlog(). После извлечения из входящей очереди кадр проходит последовательно через цепочку обработчиков протоколов, (процедура netif_receive_skb()) и в итоге попадает на сетевой уровень.

Каждый обработчик представляет собой структуру packet_type и содержит номер протокола (записанный в сетевом порядке), указатель на устройство, с которого получен кадр, (если указатель равен NULL, то все устройства) и указатель на функцию-обработчик. Для каждого обработчика кадр клонируется и к клону применяется обработчик. Последнему обработчику дается исходный кадр, поэтому после прохождения цепочки обработчиков кадр полностью покидает канальный уровень.

При отправке кадр также проходит через цепочку обработчиков (процедура dev_xmit_nit()). Цепочка обработчиков для отправки и получения одна и та же, но каждый обработчик может определить является пакет входящим или исходящим по полю pkt_type в структуре sk_buff - для исходящих пакетов она равна PACKET_OUTGOING.

Система управления очередями стека протоколов работает по принципу первым пришел, первым обслужен (First Come First Serve(FCFS)).

Стеком используются политика отбраковки пакетов для отсеивания всех пакетов, когда достигается максимальное граничное значение вне зависимости от содержимого пакета. В связи, с чем TCP/IP протокол в Linux не поддерживает QoS для сетей интегрального обслуживания.

3.1.6 Взаимодействие с операционной системой

Реализация TCP/IP протокола требует поддержки операционной системы, и эффективность стека протоколов в основном относится к операционной системе. Операционная система предоставляет множество функций для стека протоколов, например таких, как составление списка протоколов, управление памятью, управление прерываниями, работа с аппаратными средствами.

Распределение протоколов имеет большое влияние на эффективность работы протоколов в реальном масштабе времени. Разобьем этот вопрос на 3 составляющие: инициализация протокола, сокетный системный вызов и составление списка протоколов.

1) Инициализация протокола.

Стек протоколов инициализируется в конце инициализации ядра Linux на этапе загрузки. Основная функция инициализации в запуске структур данных каждого уровня стека протоколов, регистрация выбранных протоколов, таких как IP, IPX, которые отмечены как части ядра перед компиляцией ядра Linux, и установка взаимосвязей между процедурами нижних и верхних уровней на принимающей стороне стека протоколов. Например, для UDP/IP протоколов, вначале драйвер устройств получает данные с физического уровня, потом процедура ip_rcv, которая была зарегистрирована при инициализации протокола, будет вызвана для продолжения обработки IP пакета, затем будет вызвана процедура udp_rcv для обработки UDP пакета. Взаимосвязь отсылающих процедур каждого из уровней устанавливается во время создания сокета.

2) Системный вызов сокета.

Linux вводит системный вызов sys_socketcall для предоставления интерфейса программным приложениям. Этот интерфейс поддерживает 17 подпроцедур:

sys_socket, sys_bind, sys_listen, sys_accept, sys_connect, sys_send, sys_recv, sys_getsockopt, sys_setsockopt и т.д. Он представляет собой стандартный BSD сокетный интерфейс для осуществления разделения пользовательских программ и сетевых функций ядра Linux. Проще говоря, данные пользовательского уровня должны быть скопированы в режим ядра. Это требуется не только для защищенного режима операционной системы, но и семантикой сокетного интерфейса. Пользовательские программы и программы уровня ядра - различные элементы, и ведут себя по-разному. Для защиты общих данных пользовательская программа и ядро должны хранить копии своих данных раздельно.

3) Составление списка протоколов

Linux использует механизм, называемый bottom_half_handler, для согласования операций, предназначенных драйверам устройств, но не применяемых в них. Процедуры в bottom_half_handler устанавливаются на запуск операционной системой перед планировщиком процессов и в конце каждого системного вызова. Когда данные будут отосланы, пользовательская программа будет вызывать сокетный интерфейс ядра. После прохода по стеку TCP/IP, будет вызываться передаточная процедура соответствующего сетевого драйвера устройств для передачи данных. Если драйвер устройств занят передачей, данные будут помещены в отправляемую очередь драйвера устройства, и будут переданы операционной системой в соответствующее время. Когда пакеты принимаются аппаратными средствами, сетевой контроллер осуществляет прерывание, адресованное ЦПУ. Операционная система отвечает на прерывание, помещает пакет в sk_buf и помечает net_bh, как активную. Net_bh будет запущено в надлежащее время и данные будут переданы стеку протоколов TCP/IP, после чего он будет доставлен пользовательской программе.

В net_bh Linux вначале проверит, нет ли необходимости доставить какой-либо пакет. То есть сначала будут отправлены пакеты, которые стоят в очереди на отправку, а потом уже обработаны полученные пакеты. Это говорит о том, что пакеты на отправку имеют больший приоритет, чем принятые пакеты.

3.2.1 Общие сведения о NETFILTER

NETFILTER - это механизм фильтрации сетевых пакетов, появившийся в составе ядра Linux версий 2.4. Данный механизм позволяет отслеживать прохождение пакетов по стеку IP-протокола и при необходимости перехватить, модифицировать, блокировать любой пакет. Именно на базе NETFILTER построен iptables - пакетный фильтр, широко использующийся при построении межсетевых экранов.

Для того чтобы включить NETFILTER в состав ядра необходимо:

в конфигурационном файле установить опцию CONFIG_NETFILTER = у, а затем пересобирается ядро.

После этого все пакеты, проходящие по стеку IРv4-протокола, будут обработаны NETFILTER. Теперь, для примера, следует рассмотрим приемную функцию IРv4-протокола 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 при написании собственных модулей фильтрации сетевого трафика.

3.2.2 Точки перехвата

Рассмотрим схему прохождения пакета по стеку IPv4-протокола (рис.3.5). Поступивший на сетевой интерфейс пакет попадает в точку PRE_ROUTING. Если пакет адресован локальному хосту, ядро передает его для обработки локальному процессу (точка LOCAL_IN). Если пакет транзитный, из точки PRE_ROUTING он попадает в точку FORWARD и из нее двигается дальше в точку POST_ROUTING. В этой точке объединяются в один поток исходящие пакеты, сформированные локальными процессами (LOCAL_OUT), и транзитные пакеты, поступившие из точки FORWARD.

Рис. 3.5 - Схема прохождения пакета по стеку IPv4-протокола

При помощи NETFILTER можно перехватить пакет в любой из этих точек. С этой целью к точке перехвата подключается ловушка (hook).

Перечислим все места использования netfilter hooks или nethooks:

1. На входной очереди (NF_IP_PRE_ROUTING);

2. На очереди принятых пакетов (NF_IP_LOCAL_IN);

3. На выходе из маршрутизирующего кода (NF_IP_FORWARD);

4. Перед помещением локально созданных пакетов в исходящую очередь (NF_IP_LOCAL_OUT);

5. На исходящей очереди (NF_IP_POST_ROUTING).

Итак, если есть желание отслеживать все пакеты, поступающие на хост (включая транзитные), то следует подключиться к точке PRE_ROUTING.

Если интересуют пакеты, адресованные непосредственно локальному хосту, то необходимо подключиться к точке LOCAL_IN и т. д.

Каждый фильтр представляет собой структуру, содержащую:

- Семейство протоколов, для которого данный фильтр будет применяться (PF_INET в случае IPv4, также существует поддержка сетевых фильтров для IPv6 и DECNet);

- Номер сетевого крюка, на который данный фильтр будет помещен.

- Указатель на функцию, которая будет применяться к пакету.

- Два неиспользуемых поля.

Функция, применяемая к пакету должна возвращать одно из следующих значений:

1. NF_ACCEPT - пропустить пакет.

2. NF_DROP - удалить пакет.

3. NF_STOLEN - не удалять пакет, но извлечь его из очереди.

4. NF_QUEUE - переместить пакет из очереди в пользовательскую очередь.

5. NF_REPEAT - применить еще раз данный фильтр.

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


Подобные документы

  • История создания и общая характеристика операционных систем Windows Server 2003 и Red Hat Linux Enterprise 4. Особенности установки, файловых систем и сетевых инфраструктур данных операционных систем. Использование протокола Kerberos в Windows и Linux.

    дипломная работа [142,7 K], добавлен 23.06.2012

  • Основные сходства и отличия операционных систем Microsoft Windows и GNU/Linux: конфигурации, цена и широта технической поддержки; оценка стоимости владения и статистика использования на настольных компьютерах; простота инсталляции и наличие драйверов.

    курсовая работа [294,9 K], добавлен 12.05.2011

  • Назначение серверных операционных систем. Сравнительный анализ серверных операционных систем Windows и Linux и сравнение их по важным показателям таким как: пользовательский графический интерфейс, безопасность, стабильность работы, возможность и цена.

    курсовая работа [50,1 K], добавлен 03.07.2012

  • Назначение команды "diskcomp". Текст и запуск командного файла. Сравнение команды в Windows 7 и Windows XP. Разработка файла-сценария в ОС Linux. Создание файла в подкаталоге. Создание файла "oglavlenie.txt" с отсортированным по времени списком файлов.

    курсовая работа [1,6 M], добавлен 22.08.2012

  • Основные понятия об операционных системах. Виды современных операционных систем. История развития операционных систем семейства Windows. Характеристики операционных систем семейства Windows. Новые функциональные возможности операционной системы Windows 7.

    курсовая работа [60,1 K], добавлен 18.02.2012

  • Понятие и внутренняя структура операционных систем, их классификация и разновидности, предъявляемые требования, этапы становления и развития, функциональные особенности. Описание и назначение базовых компьютерных систем: DOS, Windows, Linux, Mac.

    курсовая работа [44,9 K], добавлен 14.12.2013

  • История развития операционных систем семейства Windows и основные понятия системного администрирования. Определение востребованности операционных систем Windows, сравнительная характеристика их функции и возможностей, особенности применения на практике.

    курсовая работа [38,5 K], добавлен 08.05.2011

  • Основные моменты истории операционных систем, связывающих аппаратное обеспечение и прикладные программы. Характеристика операционной системы Microsoft Windows Seven, анализ операционной системы Linux. Преимущества и недостатки каждой операционной системы.

    курсовая работа [63,0 K], добавлен 07.05.2011

  • Основные классификации операционных систем. Операционные системы семейства OS/2, UNIX, Linux и Windows. Разграничение прав доступа и многопользовательский режим работы. Пользовательский интерфейс и сетевые операции. Управление оперативной памятью.

    реферат [22,8 K], добавлен 11.05.2011

  • Графические интерфейсы и расширения для DOS. История развития операционной системы Microsoft Windows. Новшества ее современных версий: пользовательский интерфейс, языковая интеграция, системы защиты. Хронология развития и архитектура системы GNU/Linux.

    реферат [38,9 K], добавлен 25.10.2010

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.