Содержание первой части:
Содержание второй части:
2.1 — Введение во вторую часть. Смотрим на сеть и протоколы. Wireshark.
2.2 — Таблицы Firewall. Transport Layer. Структуры TCP, UDP. Расширяем Firewall.
2.3 — Расширяем функциональность. Обрабатываем данные в user space. libnetfilter_queue.
2.4 — Бонус. Изучаем реальную Buffer Overflow атаку и предотвращаем с помощью нашего Firewall'а.
В предыдущей части мы написали простой kernel module, char device driver, оснастили его интерфейсом для связи с user space через операции read/write char device и sysfs, а главное -добавили упорядоченный перехват всего трафика. В этой части мы немного углубимся в тему firewall, а также рассмотрим, как сделать нашу программу более продвинутой.
Внимание! Если для вас слова «протоколы», TCP\IP, Wireshark не новы — вам тут делать нечего :)
Прежде, чем мы продолжим, хотелось бы сказать буквально пару слов о работе сети (так как информации по теме тонны), для тех, кто совсем не занимался данной темой.
Для того, чтобы один пакет попал с одного устройства (компьютер, телефон, раутер…) на другое, необходимы определенные правила, определяющие порядок его транспортировки. Данные правила называют протоколами. Как пример, если вы хотите лететь из Санкт-Петербурга в Тель-Авив, вы едете в аэропорт, подходите к стойке, там вас регистрируют, направляют к другой стойке, там тоже делают нужные вещи, отправляют вас дальше, и так, пока вы не выходите в славном Тель-Авиве. В сетях пакет тоже проходит разные стадии, в зависимости от сети и других факторов. Теоретически, определена OSI model (читать тут), которая описывает все стадии, практически же все немного по другому. Посмотрим на картинку:
(источник картинки)
Когда клиент посылает пакет серверу, то пакет проходит несколько инстанций (опять же в классических теоретических случаях). Application – например, браузер. Он добавляет какие-то данные, например, фото, которое вы хотите загрузить в соц. сеть. Transport – тут распространены два протокола – TCP и UDP. У них есть большие отличия, но на данном этапе нам важно, что каждый из них добавляет информацию для того, чтобы выполнить свои функции (например, чтобы все пакеты дошли в посланном порядке). Network – тут самый распространенный протокол – IP, он отвечает за то, чтобы пакеты передавались через разные раутеры в больших сетях. Он перешлет пакет вашему провайдеру, потом другому серверу, потом еще одному, и в конце — в конечную точку. Link используется для направления пакетов в маленьких сетях, а Physical – очень низкий уровень, больше связанный с отдельными битами в вашей сетевой карте.
То же самое происходит и в нашей виртуальной сети. На уровне протокола IP нам будут важны только два поля: IP source – кто посылает пакет, IP destination – куда пакет послан. На уровне TCP нам будет интересно только source port, destination port. Порт – это определенный идентификационный номер соединения (например, когда ваш браузер соединяется с удаленным сервером, то он это делает с source port = 12345 на destination port = 80. Destination port для известных сервисов зарезервирован и известен заранее.
Пример:
Host2 посылает пакет host1 с порта 12345 на порт 80:
Пакет данных попал на сетевую карту 10.0.3.1, после чего firewall переправил его на 10.0.2.1(да-да, все тот же forwarding из первой части, как fw знал куда именно его пересылать – отдельная тема, легко находится в интернете).
И наконец, host1 получает пакет данных, видит, что в поле src ip прописан его IP адрес, поэтому забирает его себе (и никуда больше не пересылает).
Важно отметить! Srp ip, des tip, src port, dest port, TCP/UDP – пять этих данных достаточно для того, чтобы уникальным образом идентифицировать любую сессию связи (часто говорят о четырех данных, без протокола, что не совсем верно, потому что номера портов tcp и udp могут совпадать). То есть не может быть в нормальной сети, где все по правилам, два соединения с одинаковыми 5-ю выше описанными данными одновременно!
Я думаю, этого пока достаточно для того, чтобы читатель, не владеющий знаниями о работе сетей, продолжил чтение статьи.
Важно 2! Написанное выше призвано дать минимум интуиции и далеко от полной и точной картины, хотя и отражает главные основы сетей (например — Internet).
В качестве практики можно воспользоваться широко распространённой программой для прослушивания сети (которая, кстати, работает по тем же принципам, что и firewall в этом цикле статей). Она есть как под linux, так и под windows, и распространяется бесплатно.
Давайте смотреть вживую на пакет. Итак, запускаем wireshark и слушаем наш DHCP выход:
Я запустил браузер и пошел в Google:
Вообще, для тех, кто ни разу не пробовал, очень советую тут поиграться, потому что, кроме подключения к google.com, можно увидеть все-все-все, что происходит в сети, все протоколы, которые в ней работают и обеспечивают ее стабильную работу, включая DNS и более низкого уровня. Можно увидеть, что, еще ничего не делая, я уже владею больше чем 1000 пакетами. Я воспользуюсь фильтром, чтобы найти те, что относятся напрямую к подключению к google.com
И двойным нажатием открываем в отдельном окне:
Вот так вот он выглядит. Сверху видны все используемые OSI уровни (то, о чем я писал выше), а внизу я выделил те данные, что касаются IP протокола, включая самые для нас важные IP source, IP destination. На уровне аппликации(браузера), самого верхнего, можно увидеть, что мы посылаем запрос GET /HTTP/1.1 на google.com, то есть запрашиваем страницу (подробности HTTP протокола можно также легко найти в интернете), а также различные настройки нашей системы (язык, кодировки и т.д.).
На уровне TCP мы видим source port = 52983, destination port = 80 и некоторые другие флаги о которых можно почитать в интернете.
В завершении: статья написана главным образом для тех, кто совсем не разбирается в сетях, и предназначена для подготовки к следующим частям. Практическая же ее часть может быть отправной точкой для тех, кто никогда не «щупал» сеть, но при этом всегда хотел это сделать.
В следующей части мы поговорим про таблицы firewall, разницу между statefull vs stateless firewall, а также посмотрим, как из нашего модуля можно получить доступ к тем полям, о которых я писал выше.
Создание лаборатории, архитектура Netfilter, char device, sysfs
1.1 — Создание виртуальной лаборатории (чтобы нам было где работать, я покажу, как создать виртуальную сеть на вашем компьютере. Сеть будет состоять из 3х машин Linux ubuntu).
1.2 – Написание простого модуля в Linux. Введение в Netfilter и перехват трафика с его помощью. Объединяем все вместе, тестируем.
1.3 – Написание простого char device. Добавление виртуальной файловой системы — sysfs. Написание user interface. Объединяем все вместе, тестируем.
1.2 – Написание простого модуля в Linux. Введение в Netfilter и перехват трафика с его помощью. Объединяем все вместе, тестируем.
1.3 – Написание простого char device. Добавление виртуальной файловой системы — sysfs. Написание user interface. Объединяем все вместе, тестируем.
Содержание второй части:
2.1 — Введение во вторую часть. Смотрим на сеть и протоколы. Wireshark.
2.2 — Таблицы Firewall. Transport Layer. Структуры TCP, UDP. Расширяем Firewall.
2.3 — Расширяем функциональность. Обрабатываем данные в user space. libnetfilter_queue.
2.4 — Бонус. Изучаем реальную Buffer Overflow атаку и предотвращаем с помощью нашего Firewall'а.
Часть 2
В предыдущей части мы написали простой kernel module, char device driver, оснастили его интерфейсом для связи с user space через операции read/write char device и sysfs, а главное -добавили упорядоченный перехват всего трафика. В этой части мы немного углубимся в тему firewall, а также рассмотрим, как сделать нашу программу более продвинутой.
Часть 2.1 Введение в сети. От теории к практике.
Внимание! Если для вас слова «протоколы», TCP\IP, Wireshark не новы — вам тут делать нечего :)
Прежде, чем мы продолжим, хотелось бы сказать буквально пару слов о работе сети (так как информации по теме тонны), для тех, кто совсем не занимался данной темой.
Для того, чтобы один пакет попал с одного устройства (компьютер, телефон, раутер…) на другое, необходимы определенные правила, определяющие порядок его транспортировки. Данные правила называют протоколами. Как пример, если вы хотите лететь из Санкт-Петербурга в Тель-Авив, вы едете в аэропорт, подходите к стойке, там вас регистрируют, направляют к другой стойке, там тоже делают нужные вещи, отправляют вас дальше, и так, пока вы не выходите в славном Тель-Авиве. В сетях пакет тоже проходит разные стадии, в зависимости от сети и других факторов. Теоретически, определена OSI model (читать тут), которая описывает все стадии, практически же все немного по другому. Посмотрим на картинку:
(источник картинки)
Когда клиент посылает пакет серверу, то пакет проходит несколько инстанций (опять же в классических теоретических случаях). Application – например, браузер. Он добавляет какие-то данные, например, фото, которое вы хотите загрузить в соц. сеть. Transport – тут распространены два протокола – TCP и UDP. У них есть большие отличия, но на данном этапе нам важно, что каждый из них добавляет информацию для того, чтобы выполнить свои функции (например, чтобы все пакеты дошли в посланном порядке). Network – тут самый распространенный протокол – IP, он отвечает за то, чтобы пакеты передавались через разные раутеры в больших сетях. Он перешлет пакет вашему провайдеру, потом другому серверу, потом еще одному, и в конце — в конечную точку. Link используется для направления пакетов в маленьких сетях, а Physical – очень низкий уровень, больше связанный с отдельными битами в вашей сетевой карте.
То же самое происходит и в нашей виртуальной сети. На уровне протокола IP нам будут важны только два поля: IP source – кто посылает пакет, IP destination – куда пакет послан. На уровне TCP нам будет интересно только source port, destination port. Порт – это определенный идентификационный номер соединения (например, когда ваш браузер соединяется с удаленным сервером, то он это делает с source port = 12345 на destination port = 80. Destination port для известных сервисов зарезервирован и известен заранее.
Пример:
Host2 посылает пакет host1 с порта 12345 на порт 80:
Пакет данных попал на сетевую карту 10.0.3.1, после чего firewall переправил его на 10.0.2.1(да-да, все тот же forwarding из первой части, как fw знал куда именно его пересылать – отдельная тема, легко находится в интернете).
И наконец, host1 получает пакет данных, видит, что в поле src ip прописан его IP адрес, поэтому забирает его себе (и никуда больше не пересылает).
Важно отметить! Srp ip, des tip, src port, dest port, TCP/UDP – пять этих данных достаточно для того, чтобы уникальным образом идентифицировать любую сессию связи (часто говорят о четырех данных, без протокола, что не совсем верно, потому что номера портов tcp и udp могут совпадать). То есть не может быть в нормальной сети, где все по правилам, два соединения с одинаковыми 5-ю выше описанными данными одновременно!
Я думаю, этого пока достаточно для того, чтобы читатель, не владеющий знаниями о работе сетей, продолжил чтение статьи.
Важно 2! Написанное выше призвано дать минимум интуиции и далеко от полной и точной картины, хотя и отражает главные основы сетей (например — Internet).
Часть 2.1 Введение в сети. Практика
В качестве практики можно воспользоваться широко распространённой программой для прослушивания сети (которая, кстати, работает по тем же принципам, что и firewall в этом цикле статей). Она есть как под linux, так и под windows, и распространяется бесплатно.
Давайте смотреть вживую на пакет. Итак, запускаем wireshark и слушаем наш DHCP выход:
Я запустил браузер и пошел в Google:
Вообще, для тех, кто ни разу не пробовал, очень советую тут поиграться, потому что, кроме подключения к google.com, можно увидеть все-все-все, что происходит в сети, все протоколы, которые в ней работают и обеспечивают ее стабильную работу, включая DNS и более низкого уровня. Можно увидеть, что, еще ничего не делая, я уже владею больше чем 1000 пакетами. Я воспользуюсь фильтром, чтобы найти те, что относятся напрямую к подключению к google.com
И двойным нажатием открываем в отдельном окне:
Вот так вот он выглядит. Сверху видны все используемые OSI уровни (то, о чем я писал выше), а внизу я выделил те данные, что касаются IP протокола, включая самые для нас важные IP source, IP destination. На уровне аппликации(браузера), самого верхнего, можно увидеть, что мы посылаем запрос GET /HTTP/1.1 на google.com, то есть запрашиваем страницу (подробности HTTP протокола можно также легко найти в интернете), а также различные настройки нашей системы (язык, кодировки и т.д.).
На уровне TCP мы видим source port = 52983, destination port = 80 и некоторые другие флаги о которых можно почитать в интернете.
В завершении: статья написана главным образом для тех, кто совсем не разбирается в сетях, и предназначена для подготовки к следующим частям. Практическая же ее часть может быть отправной точкой для тех, кто никогда не «щупал» сеть, но при этом всегда хотел это сделать.
В следующей части мы поговорим про таблицы firewall, разницу между statefull vs stateless firewall, а также посмотрим, как из нашего модуля можно получить доступ к тем полям, о которых я писал выше.