Показаны сообщения с ярлыком ipfw. Показать все сообщения
Показаны сообщения с ярлыком ipfw. Показать все сообщения

вторник, 4 апреля 2017 г.

Новые модули ядра ipfw_pmod, ipfw_nptv6 и ipfw_nat64

Вчера я закоммитил новый модуль для ipfw - ipfw_pmod, а так же смержил в stable/11 модули ipfw_nptv6 и ipfw_nat64.
Во FreeBSD 11.0 в ipfw было добавлено много нового, и среди прочего - поддержка "внешних действий", или external action. Она представляет собой интерфейс, который даёт возможность в рантайме добавлять и удалять в ipfw дополнительные действия для правил (actions, такие как allow, deny, count и прочие) . 
Как это планировалось использовать в теории. Предположим, у нас имеется стоковая FreeBSD, и ряд задач для ipfw, которые строго специфичны для нашей организации, и всем другим людям такие функции вряд ли потребуются. Чтобы не добавлять подобные функции в базовую систему, и в то же время, чтобы упростить поддержку внутри организации (адаптацию патчей с каждой новой версией), были добавлены несколько новых опкодов.
Этих опкодов (сначала их было два, теперь стало три) достаточно, чтобы реализовать практически любую новую функцию в ipfw. Имеются в виду опкоды типа action. Достаточно только подгрузить модуль ядра и правила, использующие эти новые действия будут работать. Даже стоковый бинарник ipfw(8) способен с некоторыми ограничениями отображать такие правила. Для добавления и модификации таких правил необходимо стороннее приложение, исходный код которого менять при обновлении нет необходимости.
В случае если подобный модуль достаточно полезен и для всех других людей, то достаточно включить код для добавления и отображения правил в состав ipfw(8). Ядерная же составляющая остаётся без изменений.
Используя этот интерфейс были созданы три, перечисленные в начале, модуля. Модуль ipfw_pmod предназначен для модификации пакетов различных протоколов. На данный момент он содержит в себе только опкод "tcp-setmss", который как нетрудно догадаться, модифицирует опцию TCP пакета MSS. Правило использующее это действие может выглядеть, например, так:
ipfw add tcp-setmss 1400 tcp from any to any
Работает оно примерно так же, как netgraph модуль ng_tcpmss. Но ещё и поддерживает IPv6. После обработки правилом, действие продолжается со следующего правила. Т.е. правило не прерывает поиск.

Модуль ipfw_nptv6 реализует транслятор IPv6 префиксов и работает по алгоритму, описанному в  RFC6296. Сразу хочу заметить, что трансляция IPv6 префиксов происходит несколько иначе, как можно было бы ожидать. Адреса не транслируются 1 в 1, например 2001:1000::1 не будет оттранслирован в 2a02:6b8::1. Согласно RFC адреса транслируются таким образом, что у транслятора нет необходимости делать пересчёт контрольных сумм. Поэтому в адрес добавляется некоторое число, которое делает вид адреса менее читаемым.
Использование этого модуля несколько отличается от ipfw_pmod. Здесь применяется концепция именованных экземпляров (instance) со своими собственными настройками. Прежде чем использовать nptv6 в правилах, необходимо создать именованный экземпляр и настроить его. После этого уже можно добавлять правила в ipfw:
ipfw nptv6 NPT create int_prefix fd00:dead:c0de:: ext_prefix 2001:470:7ad7:: prefixlen 48
ipfw add nptv6 NPT ip6 from any to any

Модуль ipfw_nat64 реализует транслятор IPv6 в IPv4. Он содержит две реализации stateful и stateless, и тоже использует концепцию именованных экземпляров. NAT64 без отслеживания состояний настраивается при помощи ключевого слова nat64stl. Он использует две таблицы, содержащие отображение IPv6->IPv4 и IPv4->IPv6. Согласен, это не очень удобно, но пока так.
NAT64 с отслеживанием состояний использует ключевое слово nat64lsn. Для его настройки нужен только используемый IPv4 префикс, который определяет количество ресурсов необходимых транслятору.
Оба транслятора используют Well-Known IPv6 префикс для NAT64 64:ff9b::/96. Ну и для работы конечно же нужен работающий DNS64.

воскресенье, 2 декабря 2012 г.

Что нового?

Начнём с того, что я сменил работу, и теперь она напрямую связана с FreeBSD. Теперь у меня больше времени и возможностей, которые можно направить на улучшение системы. Правда, работодатель рассчитывает, что я буду прикладывать их в другое русло - оптимизация сетевой подсистемы и ipfw. Чем я и занимаюсь :)

Первой ласточкой стало то, чего давно хотелось. Ещё когда я не был коммитером, хотелось чтобы ipfw fwd работало без перекомпиляции ядра. Но тогда на моё предложение возразили, что этот функционал значительно снижает быстродействие сетевой подсистемы. Но как показали испытания, никакого снижения замечено не было. В системе хватает других мест, которые вносят значительные "тормоза".

Итак, вероятно некоторые уже заметили, что в src/UPDATING появилась запись, информирующая об удалении опции IPFIREWALL_FORWARD. Теперь этот функционал работает "из коробки", достаточно просто загрузить модуль ядра ipfw.ko. В stable/9 это изменение уже тоже есть, но в релиз оно не попадёт.

Другим крупным шагом был MFC изменений в загрузчике в stable/9. Теперь код загрузчиков в 9-ке практически идентичен тому, что в 10-ке. Я ещё думаю о переносе изменений в 8-ку, но, честно говоря не хочется этого делать. Уж очень сильно в 8-ке он отличается и придётся сделать MFC ещё для кучи ревизий. Так же, можно поблагодарить Андрея avg@ за исправление проблемы в загрузочном коде, которая обнаруживалась на некоторых "кривых" BIOS.

Кроме того, был осуществлён первых подход к изучению и тестированию IPv6 стека на производительность. Который показал плачевное состояние в этой области. Правда, благодаря профилированию и нескольким небольшим изменениям, удалось улучшить результаты почти в три раза. Не буду озвучивать цифры, они сильно зависят от железа. Но факт в том, что оптимизация IPv6 во FreeBSD - это ещё "напахано поле". Впрочем, в IPv4 базовая система тоже не блещет результатами и всего несколько строк в /boot/loader.conf и /etc/sysctl.conf может улучшить эти результаты в разы.

четверг, 30 июня 2011 г.

ipfw call / return

28 июня официально начался "Code Slush for 9.0-RELEASE", который так же известен как "Feature Freeze". Т.е. теперь в head/ бранч не разрешается вносить новый функционал. Цель этого мероприятия - стабилизировать состояние системы и сосредоточиться на поиске и исправлении ошибок. На 17-ое июля запланирован "Code Freeze" после которого последует выход первой бета версии FreeBSD 9.0.

Теперь о теме. Вадим Гончаров, узнав о предстоящем "Code Slush", выдал очередной патч для ipfw, который во что бы то ни стало должен оказаться в 9.0-RELEASE. :)
Патч добавляет два новых действия в ipfw: "call" и "return". Первая команда выполняет "вызов" подпрограммы, вторая - возврат из подпрограммы к следующему правилу. На практике, конечно, никаких подпрограмм не вызывается. Команда "call" принимает в качестве аргумента номер правила, к которому нужно выполнить переход. Переход осуществляется аналогично тому, как это делается для команды "skipto", только он может осуществляться в любом направлении по отношению к текущему правилу. Кроме того, перед выполнением перехода команда "call" сохраняет во внутреннем стеке номер своего правила в качестве точки возвращения. Размер стека ограничен 16 элементами. Это значит, что "подпрограмма" может содержать в себе другие вызовы "call" в другие "подпрограммы".
Возврат из "подпрограммы" осуществляется размещением правила с командой "return". У неё нет аргументов. Она находит в стеке первый элемент (по дисциплине LIFO), извлекает сохранённый номер правила и осуществляет возврат к следующему правилу с номером большим на 1.

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

Кстати, Hiroki Sato сообщил о возобновлении сборки снепшотов FreeBSD CURRENT на ресурсе allbsd.org. Что является отличной новостью, для меня по крайней мере. Обычно для тестирования чего-либо бывает быстрее скачать образ и установить систему, чем обновляться из исходников.

пятница, 24 июня 2011 г.

Что нового?

Последние несколько недель в свободное время занимался обработкой открытых PR. В основном они были связаны с ipfw, dummynet и ipfw_nat, но не все. В общем, сократил количество открытых проблем где-то на полтора десятка, может даже на два. Считать, если честно - лень :)

Что хотелось бы отметить - это несколько исправлений и патчей, добавляющих новую функциональность. Желательно бы их получше оттестировать перед MFC. И, кстати говоря, вот уже почти неделю назад должен был начаться "code slush" в связи с подготовкой к выпуску 9.0-RELEASE.

Итак, первое исправление затрагивает kern/136695, kern/147720 и kern/150798. Связано оно с функцией форвардинга пакетов в ipfw и использованием динамических правил. Теперь реализация аналога reply-to из PF не должна составить труда и в ipfw (описание этого случая можно найти у Вадима Гончарова в блоге).

Следующее исправление связано с kern/122109, kern/129093 и kern/157379. Оно делает поведение ipfw_nat более похожим на natd. Возможно, те кто говорил, что ipfw_nat работает не так с правилами, с которыми работает natd, теперь вздохнут с облегчением. Теперь ipfw_nat будет более "гуманно" относится к пакетам, которые libalias не захотела обрабатывать. Раньше такие пакеты просто отбрасывались, что приводило к симптомам, хорошо показанным в перечисленных PR.

Теперь о новом функционале в ipfw_nat - kern/157867. Это аналог опции globalport для natd. Если у вас сконфигурировано несколько NAT'ов, то теперь можно одним правилом заставить ipfw проверять пакет сразу для всех таблиц трансляций. Для этого добавлено новое "кодовое слово"- nat global. Пакет будет обрабатываться в соответствии с конфигурацией той таблицы, в которой найдётся подходящее состояние.


В модуль libalias, обрабатывающий FTP соединения внесены изменения kern/157957, благодаря которым он корректно работает при использование опции redirect_port для ipfw_nat. Кстати, Глеб Смирнов изменил обработку опций NAT для ipfw(8). Теперь командная строка не ограничена длиной NAT_BUF_LEN и при настройках NAT можно указывать сколько угодно опций.

Кроме того, для ipfw setfib добавлена поддержка tablearg - kern/156410.

Еще было несколько мелких исправлений, которые не так интересны. Но в общем, за большинство из этих изменений и исправлений можно поблагодарить Александра Черникова. Именно у него хватило терпения и желания, копаться в коде, который местами далеко не очевиден, писать патчи и продвигать их, чтобы они оказались в системе.

Да, ещё. По проблеме с загрузкой с ZFS. Вчера John Baldwin добавил исправление в загрузочный код, которое, вероятно исправит большинство проблем.

четверг, 18 февраля 2010 г.

Баг с отображением активных наборов правил в ipfw

Общаясь в IRC RusNet узнал, что в 8-ой версии FreeBSD странно работает команда ipfw set show, которая должна показывать, номера активных и заблокированных наборов правил. А именно - не смотря на явное отключение наборов, вывод команды не изменяется. Т.е. другими словами, команда всегда показывает одно и то же - все наборы активны.

После небольшого исследования исходного кода подтвердилось наличие проблемы. Немного порывшись в истории коммитов нашёлся и источник - r200855. Проблема заключается в том, что код операции IP_FW_GET был переписан (в рамках подготовки к вливанию новой версии ipfw3), но не достаточно оттестирован, как это обычно и случается :).

О проблеме сразу же сообщил виновнику, но воз и ныне там, так что нужно будет заняться исправлением, как только времени побольше появится...