UNИX, весна 2009, 03 лекция (от 11 марта)

Материал из eSyr's wiki.

Версия от 18:02, 11 марта 2009; ESyr01 (Обсуждение | вклад)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

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

Чтобы было понятно, о чём идёт речь. Само название довольно старое, т. к. функц., ip firewall, была реализована ещё в bsd 2.2 или около того, что касается реализации, во фрибсд оно явл. самой старой. Правда, он обладал недостатками, и в какой-то момент во freebsd из кажется oipenbsd другой вариант, под названием ipf, потом в 2002 году появилось сразу два новшества, а именно, ipfw был дополнен большим количеством функйц. и стал назыв. ipfw2, и был спортирован из openbsd pf. Так что линейчатых фаерволлов только три штуки. Самый крутой это pf, но ipfw2 тоже достаточно крутой.

Лектор немного будет поглядывать бумажку.

ipfw имеет строго линейатую структуру, это список правил, которые применяются к пакету, проходящему через tcp/ip стек, причём применяются сразу в нескольких местах. В мане по ipfw эта картинка есть в ascii-art. Есть как минимум два случая, когда нужно обр. пакеты: входящие и исходящие. В первом случае — непосредственно когда вошёл в интерфейс, во втором — перед тем, как выйти из интерфейса. Картинка примерно следующая:

К ipfw приходит пакет, возм. из верхних уровней, например, из tcp, но его это не касается. Это не значит, что с tcp ipfw не работает, эта информация всё равно есть внутри пакета. Ещё есть уровень eth. Можно включить у себя в фаероволле опцию bridge, и тогда появится пятое действие, собственно bridge. Вот на всех этих 5 участках ipfw работает. Чаще всего исп. ip уровень, интерфейсный уровень обычно исп. bridge.

В чём при этом хитрость линейного фарволла: все эти пакеты ставятся на все очереди правил, в не зависимости от того, какие это пакеты. С точки зрения польз. выглядит, что он проходит по всем областям. Если нельзя выковырять информацию (например, на ip-уровне нельзя получить инф. о mac), то правило не сработает, но если включили уровень соотв., то сработает.

Правила линейны, но чем-то похожи на программу на бейские, поск. у правила есть свой номер, от 1 до 65535, и принято при ручном задании делать шаг 100. Одно из правил всегда пробито, это 65535, в зависимости от того, с какими параметрами собрано ядро (всё убивать или всё принимать), то и правило будет всё пропускать или убивать. Почему так: поск. в ipfw действует правило 1st wins, и если ни одно из правил не смогло примениться, то применчяется последнее.

Прммерный упрощённый вид правил:

[номер] [действие] [тело]

Тело — обычная фильтрация, но это не всегда так. Например, пометка пакетов, проверка на присутствие в таблицах и так далее, так что нельзя с точностью определить, что делается в последней части. Если в случае iptables это цепочка-условие-действие, то ipfw это штука монолитная. Что мы можен делать с пакетами, проходящими через ipfw:

  • allow
  • drop
  • reject
  • fwd

Эти правила приводят к тому, что пакет так или иначе куда-то там девается. Либо он проходит, либо не проходит, либо перенапр. на другой адрес.

Что касается allow, то всё очевидно. Тело будет условием на пакет, и означает следующие: если данное правило — первое, где усл. совп. со свойствами пактеа, если его к тому моменту модифицировали, то значит так.

Про условие поговорим чуть позже, а пока посм. на два других правила, drop и reject:

Что касается drop, то пакет просто исчезает, вот пришёл он и исчез. Чем это плохо: если мы честные люди, то если мы не хотим, чтобы он был доставлен,Э то надо отвечать по icmp какое-то усмное слово, например, host unreachable. И если польз. будет ломиться к нам, особенно по udp, где нета обр. связи, то он даже не узнает, дошли пакеты или не дошли.

В случае reject будет сгенерирован icmp-пакет host unreachable. Чем то правило плохо: если вы защищаетесь от flood-атак, то ответов флудер слать не надо.

Относительно fwd: fwd <куда>. При этом пакет не меняется, и действует на выходе, указывая в сопроводительной информации, куда олжен быть отправлен пакет. Если машина не настроена на получение пакетов для чужих ip, то она его просто выбросит. Зачем это гужно: например, на той машине висит демон, который все пакеты принимает и журнализирует.

Пример:

65535 deny ip form any to any # ip form any to any — тело

Достаточно понятный формат, не изучая досколнально все правила, можно понять, что выбрю все пакеты. Можно добавить правила:

100 allow ip from any to any via lo0

lo0, если кто не знает, интерфейс loopback в bsd. В bsd интерфейсы называются не eth, а по имени драйвера, такое legacy. Если учесть, что там одним из первых появилось переименование интерфейсом, ноо не мешает.

Что означает это правило: ктобы что бы не собирался послать что через lo, пусть шлёт. Но у лектора есть пример, когда человек режет пакеты на 127.0.0.0/8:

200 deny all from any to 127.0.0.0/8

То есть, всё остальное надо убить.

Пример с fwd лектор приводить не будет, это довольно редкая штука, но она полезна, с той разницей, что та машина, куда fwd, не должна из пугаться.

В принципе, слово ip лишь синоним для all. Можно писать ip6 или ip4, но на уровне ipfw предп., что мы поерирруем пакетами именно такого сорта.

Разумеется, вместо any можно написать лбюой адрес или сеть, а также me. Довольно удобно, когда интерфейсов много и разных.

В случае, когда мы оперируем пакетами подобным родом,выбор у нас довольно небольшой, указать тип пакета, откуда и куда.

Помимо тех действий, которые лектор рассказал, может быть что ещё.

Про nat. В ipfw2 появилась встроенная поддержка nat, но лектор никогда её не пользовался. Лектор лучше расскажет, как был устроен nat изначально. Как лектор говорил на предыдущей лекции, nat делался в юзерспейсе. В bsd есть такие divert sockets, которые позволяют иметь сокет изх ядра в юзерспейс. Как это реализуется:

{divert tee } <port>

То есть, мы пренаправляем пакет в указанный divert-сокет. При этом в userspace должна быть запущенна некая программа, которая слушает его, и оттуда стандартными командами (recvfrom) будет читать. Она эти пакеты обрабатывает, и потом стандартными командами (sendto). Что она с ними делает, это её личная проблема. В результате пакет попадает сразу за правилом и обр. дальше.

В отличие от бейсика, можно иметь несколько правил за одним номером, чотбы можно было удалять блоками. идея в чём: если таких правил много, то они, даже те, которые идут под одним и тем же номером, и пакет будет обр. след. правилом в таблице.

Зачем нужен divert сокет? Чтобы делать с пакетами что угодно, не занимаясь написанием ядерного могуля. Кстати сказать, если на сокете никто не сидит, то пакет просто пропадает. Кроме того, эта команда асинхронная: фаерволл работает дальше, в это время юзерспейс-программа прочухается, что-то запишет обратно и тогда дальше обр. этот пакет.

Чем отл. divert от tee: divert просто перенаправляет, а tee его раздваивает.

В станд. поставке лектор обнаружил ровно один демон, natd, и догадайтесь, что он делает. natd это просто юзерспейс-программа, у него в районе 2 десятков ключей, делает всё, что полагается нату, может натить на входе, на выходе.

По всей видимости, это направление развиолсь бы и дальше, поск. если мы хотим произвольным обр. пакеты, ... например, присобачить netgraph, даже action есть:

netgraph <надпись>

Исп. divert и netgrapha отл. тем, что netgraph работает очень быстро.

Помимо netgraph есть ещё ngtee.

Правило типа count это понятно что. Довольно забавно: у каждого такого правила есть счётчик, сколько оно применялось, это особенно полезно, чтобы посмотреть, применялось оно или нет. И count ничег о не делает, только считает.

Очень важная вещь, это правило checkstate...

Очень страшная вещь: правило skipto <номер>. Это goto, как в настоящем бейсике. Поск. табличка линейчатая, то нужно делать переходы, можно, например, делать преходы назад, тода он не вылезет из kernelspace и зависнет к чертям. Но без этой штуки обойтись нельзя, поск. пакеты, прох. через эти 5 точек, обр. ровно этим списком. Есть флаги, которые позв. фильтровать, и иногда удобно проверить флаги и и сделать skipto.

Чего лектор не сказал: как работать с stateful firewall. Очень часто, особенно из сообр. быстродействия полезно делать вот что: мы наш пакет прогнали по всему своду правил, и в какой-то момент приняли решение, что этот пакет и все подобного класса надо пропускать, например, если уст. tcp-соединение, то надо все его пакеты пропускать. Как это делается: есть правило checkstate, у которого нет параметров. Правило типа check-state приводит к тому, что все пакеты, дошедшие досюда, проверяются частью фаерволла, хранящей состояние.

500 check-state

почему это делается не сразу: поскольку проверка сост. это довольно тяжёлая процедура, и если можно отфильтровать пакет без неё, то лучше это сделать.

правило checkstate делает ещё одну вещь: ещё при этом проверяются пресловутые состояния, то есть,. если у вас пакет принаддл. потоку данных, у которого сохр. состояние, то это правило будет ему применено. Как правило, это allow.

510 deny all from any to any astablished
520 allow tcp from any to any ...

Stateful ашкуцфдд ecnhjty cktl. образом: есть флаг keep state, которые запоминаен состояние, что такой уже пропускали. Это сост. проверяется checkstate, и если среди этих сост. есть такое правило, то оно применяется, в противном случае он проваливается дальше.

stateful firewall это способ его убыстрить сильно, одной командой проверить, не имеет ли данный пакет отношения к таим, которые мы уже рповеряли.

ОБщая идея состоит в том, что мы допускаем пакты типа setup, то есть начала tcp-сессий, после чего говорим сохр. сост., после чего новаорим, чот ве такие пакеты проходили.

Что касается огр. трафика: есть каманда pipe, queue. Чтобы оно работало, нужно, чтобы в ядро был вкопилирован модуль ..., это такой эмулятор сети. Идея том, чтобы прежде, чем пакет отсылать, оно сначлаа засовывается в трубу с соотв. номером, труба с точки зрения польз. предст. сосбой некий конвейер, у которого опр. пропуск. способность, кроме того, у него есть другие параметры: опр. процент потери пакетов, длина очереди и так далее. У queue такого нет, зато есть разные политики.

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

Можно делать дерево труб и так далее. Там есть ещё qos.

Относительно флагов. Мы помним из прошлого раза, что основной способ рабоыт фаерволла состоит в том, что при прохождении через стек пакеты снабжаются разнообр. инф., и фаерволл на основании её решает, что с ним делать. Можно перед действием вставить tag #, это аналог -j MARK iptables, тегов может быть не более 65534 (0 и 1 заняты), и если у пакета есть тег, то можно с ним сделать что-то. теги не отклеиваются, когда он отправляется в divert socket, то теги с него снимаются, поск. это искл. kernel-space штука, а пока он ходит по ядру, они на нём висят.

Вкусности: можно укзаать вероятность применения правила.

Вопрос: откуда берётся энтропия?

Ответ: вероятно, исп. не /dev/urandom, а что-то более простое.

Ещё у каждого фаерволла можно указать set #, и можно выкючать и включать правила блоками. После его упр. ими по крону, эмулируя два режима, например, дневной и ночной.

Какие флаги: помимо типа, откуда и куда, может быть большой список разных флагов — дополн. св-в пакета:

  • Если это исх. пакет, то можно затребовать uid, pid, gid и прочая (только в ipfw2)
  • Если пакет ходил через divert, ходил чреез bridge, получил таг, то можно всё это проверить (diverted и так далее)
  • Фрагментированые пакеты
  • Есть in и out
  • Во freebsd есть простая вирт. подназванием jail, чтобы запустить процесс в изолированном файл. пространстве и ipc. Если пакет пришёл из jail, то можно узнать, из какого. Ближайший аналог в линукс — vserver(?)

В общем, тут чёрте сколько флагом, можно указывать виды icmp-трафик.

Могут быть счётчики, напр. правило применяется не более чем столько-то раз, это актуально для stateful firewall-ов.

В ipfw2 есть также встроенный nat.

Чтобы закончить эту лекцию, что есть для поддержки со стороны юзерспейса: есть утилита ipfw, которая позв. делать всё, о чём говорили, из ком. строки. В rc-скриптах есть скрипты по запуску фаерволла, там указ. типа фаерволла, который пропис. правила по умолч и куда можно указ. путь к скрипту.

ipfw нужен не только для настр. правил, но и для настр. пайпов, очередей. В ipfw2 можно настр. таблицы адресов. Можно отдельно задать таблицу ip-адресов и исп. её в кач. адреса. Этим занимается ipfw table.

Чтобы закончить, лектор скажет так: ещё один способ. исп. set-ов след: заводите два сета, текушее и новое. Текущая табл. включена, новая выключена. Но когда работает ipfw, то он обр. все правила. В таком случае можно проверить неск. раз правила, как минимум на синтаксис, и только после этого сказать ipfw set swap.

В след раз про check-state, nat и очереди.


UNИX, весна 2009


Лекции

01 02 03 04 05 06 07 08 09 11


Календарь

Февраль
25
Март
04 11 18 25
Апрель
01 08 15 22
Май
06


Эта статья является конспектом лекции.

Эта статья ещё не вычитана. Пожалуйста, вычитайте её и исправьте ошибки, если они есть.
Личные инструменты
Разделы