IPF Howto
Перевод: Сгибнев Михаил
Источник: http://dreamcatcher.ru/2009/11/27/ipf-howto/
Оглавление:
1. Введение
2. Оговорка
3. Авторское право
4. Где получить
5. Начальное использование систем фильтрации
6. Файл конфигурации: порядок следования директив
7. Основы обработки правил
8. Управление обработкой правил
9. Основы фильтрации по IP адресу
10. Управление интерфейсами
11. Совместное использование IP адреса и интерфейса
12. Двунаправленная фильтрация. Ключевое слово «out»
13. Регистрация событий. Ключевое слово «log»
14. Полная двунаправленная фильтрация на интерфейсе
15. Управление протоколами. Ключевое слово «proto»
16. Фильтрация ICMP с помощью ключевого слова «icmp-type». Обьединение наборов правил.
17. TCP и UDP порты; ключевое слово «port»
18. Введение в расширенную фильтрацию
19. Необузданная паранойя; или политика запрета по умолчанию
20. Неявное разрешение. Правило «keep state»
21. Stateful UDP
22. Stateful ICMP
23. Обнаружение FIN-сканирования. Ключевое слово «flags» и «keep frags»
24. Ответ на блокированный пакет
25. Представление о методах регистрации
26. Объединение всего этого
27. Увеличение производительности с помощью групп правил
28. Ключевое слово «Fastroute»
29. NAT и прокси
30. Отображение нескольких IP адресов в один
31. Отображение нескольких IP адресов в пул адресов
32. Отображение один к одному
33. Правила NAT
34. Spoofing Services
35. Поддержка прозрачных прокси. Польза перенаправления
36. Фильтрация перенаправления
37. Волшебство, скрытое в NAT. Прокси-серверы приложений
38. Еще немного волшебства; использование NAT для балансировки нагрузки
39. Загрузка и управление правилами фильтрации. Утилита ipf
40. Загрузка и управление правилами NAT. Утилита ipnat
41. Мониторинг и отладка
42. Утилита ipfstat
43. Утилита pmon
44. Keep State With Servers and Flags
45. Копирование с FTP
46. Работа FTP сервера
47. Работа FTP клиента
48. Различные переменные ядра
49. Наслаждайтесь с ipf!
50. Фильтрация на своей машине
51. Какой фаерволл? Прозрачная фильтрация
52. Использование прозрачной фильтрации для обнаружения ошибок проектирования сети
53. Drop-Safe Logging с использованием методов dup-to и to.
54. Метод dup-to
55. Метод to
56. Фильтрация поддельных сетей, вершина технологии anti-spoofing
IP Filter Based Firewalls HOWTO
Brendan Conoboy
Erik Fichtner
Wed Dec 11 12:42:58 EST 2002
Резюме:
Этот документ предназначен для того, чтобы познакомить пользователя с пакетнымфильтром IP Filter и дать некоторые основные принципы построения качественных систем сетевой защиты.
1. Введение
IP Filter — это маленький по размеру, но не по возможностям пакетный фильтр. Он делает почти все, что и другие свободно распространяемые системы сетевой защиты (ipfwadm, ipchains, ipfw), обладает дополнительными возможностями и хорошей переносимостью. Этот документ предназначен для того, чтобы придать некоторую связность разрозненным сведениям, имеющимся по ipfilter. В дальнейшем, этот документ будет также служить документацией для синтаксически совместимых пакетных фильтров (особенно pf), с указанием важных различий. Этот документ предназначен для описания синтаксиса и языка правил и не является платформозависимым. Было бы полезно, если читатель уже имел знакомство с пакетными фильтрами, однако, слишком большое знание может превратить чтение этого документа в обычную трату времени. Для большего понимания систем сетевой защиты, авторы рекомендуют Building Internet Firewalls, Chapman & Zwicky, O’Reilly and Associates; и TCP/IP Illustrated, Volume 1, Stevens, Addison-Wesley.
2. Оговорка
Авторы этого документа и переводчик не ответственны за любые убытки, которые были понесены вследствие предпринятых действий, основанных на прочтении этого документа. Этот документ предназначен как введение в формирование системы сетевой защиты, основанной на ipfilter. Если Вы не чувствуете себя готовым взвалить на себя такую ответственность, наймите профессионала, который сделает все за вас.
3. Авторское право
Если не заявлено иное, то HOWTO документы находятся под защитой авторских прав и принадлежат их авторам. HOWTO может быть приведен полностью или частично, на электронных и бумажных носителях с сохранением авторства. Коммерческое распространение позволяется и поощряется; однако, авторы хотели бы быть уведомленными относительно таких распространений.
Все переводы, производные работы, или работы, включающие любые HOWTO должны быть охвачены этим объявлением об авторском праве. То есть Вы не можете сделать работу, основанную на HOWTO и наложить дополнительные ограничения на ее распространение. Исключения к этим правилам можно предоставить при некоторых условиях; пожалуйста войдите в контакт с координатором HOWTO.
Короче говоря, мы желаем распространить эту информацию всеми возможными способами. Однако, мы действительно желаем сохранить авторское право на этот HOWTO, и хотели бы быть уведомленными относительно любых планов распространения HOWTO.
4. Где получить
Официальная страница IPF: http://coombs.anu.edu.au/~avalon/ip-filter.html
Распространяемый по лицензии BSD пакетный фильтр pf: http://www.benzedrine.cx/pf.html
Наиболее современная версия этого документа может быть найдена здесь: http://www.obfuscation.org/ipf/
5. Начальное использование систем фильтрации
Этот раздел предназначен для ознакомления Вас с синтаксисом ipfilter и общей теорией системы сетевой защиты.Функции, обсуждаемые здесь, вы можете найти в любом хорошем пакетном фильтре. Этот раздел даст Вам возможность более легко понять и освоить раздел расширенных возможностей.
Необходимо подчеркнуть, что прочтения только этого раздела недостаточно для построения хорошей системы сетевой защиты и изучения раздела расширенных возможностей действительно необходимо.
6. Файл конфигурации: порядок следования директив
IPF (IP Filter) имеет файл конфигурации. Он традиционен для Unix: одно правило в строке, знак # считается комментарием и символы справа от него до конца строки игнорируются, правило и комментарий могут находиться в одной строке, лишние пробелы и пустые строки игнорируются и поощряются для сохранения читабельности.
7. Основы обработки правил
Правила обрабатываются сверху вниз, каждое, одно за другим. Это весьма просто и означает что, если Ваш файл конфигурации состоит из строк:
block in all
pass in all
Они будут просмотрены в таком порядке:
block in all
pass in all
В этом случае к входящему пакету сперва применяется правило:
block in all
И если IPF сочтет нужным перейти на следущую строку, применяется правило:
pass in all
В этом месте Вы возможножно зададите себе вопрос: «будет ли IPF переходить ко второму правилу?» Если Вы знакомы с ipfwadm или ipfw, то такой вопрос, скорее всего и не возникнет. Но вскоре Вы будете несказанно удивлены, обнаружив, что все пакеты, которые должны быть заблокированными, успешно проходят. Большинство пакетных фильтров прекращают сравнивать пакет с набором правил в момент первого соответствия. IPF — не принадлежит их числу.
В отличие от других пакетных фильтров, IPF только устанавливает флаг, соответствующий действию над пакетом. Если порядок прохождения правил не будет прерван, то будут пройдены все правила и основываясь на последнем соответствии будет принято решение о том, пропустить или отбросить пакет.
Сцена: работающий IP filter, ресурсы CPU, буфер для контрольных точек, набор правил:
block in all
pass in all
Пакет входит в интерфейс и работа закипела.
Рассматривается пакет и берется первое правило:
block in all
«Пока я думаю, что я блокирую этот пакет » говорит IPF. Рассматривается второе правило:
pass in all
«Пока я думаю, что я передам этот пакет » говорит IPF. Будем смотреть третье правило. А третьего правила нет, поэтому будем действовать в соответствии с последней инструкцией, следовательно, пакет будет пропущен. Самое время указать, что даже если бы набор правил был таким:
block in all
block in all
block in all
block in all
pass in all
То пакет по прежнему бы проходил. Нет никакого накопительного эффекта. Последнее правило всегда имеет приоритет.
8. Управление обработкой правил
Если у Вас есть опыт работы с другими пакетными фильтрами, то Вы можете найти такой порядок весьма запутывающим и размышлять о портируемости списка правил и скорости обработки правил. Представьте себе, что у Вас есть 100 правил и большинство пакетов соответствовало бы первым 10. Было бы ужасно, если бы каждый пакет, имеющий окончательное соответствие, проходил бы все 100 правил. К счастью есть простое ключевое слово, которое может быть добавлено к любому правилу, для принятия именно этого решения при соответствии. Это слово quick.
Вот немного измененный набор правил:
block in quick all
pass in all
В этом случае IPF смотрит на первое правило:
block in quick all
Сравнения пакета и правил закончены. Пакетнемедленно блокирован. Нет никаких примечаний и никаких записей в файлах регистрации. Так что там со следующим правилом?
pass in all
Это правило не будет рассматриваться, с тем же успехом его могло вообще не быть в файле конфигурации. Наличие таких ключевых слов как all и quick позволит нам с уверенностью утверждать, что никакие другие нижеследующие правила рассматриваться не будут.
Положение, когда зря пропадает половина файла конфигурации едва ли можно назвать удачным. С другой стороны, IPF должен сдесь блокировать все пакеты и справляется с этой работой хорошо. Тем не менее, IPF должен также позволить проходить некоторым пакетам, так что необходимо сделать некоторые изменения в наборе правил.
9. Основы фильтрации по IP адресу
IPF должен сравнивать пакеты по многим критериям. Наиболее часто вспоминаемым из них является IP адрес. Есть некоторые блоки адресного пространства, из которых мы никогда не должны получать трафик. Один такой блок – диапазон частных сетей 192.168.0.0/16 (/16 – CIDR представление сетевой маски, Вы можете быть знакомы с десятичным форматом 255.255.0.0. , таки IPF понимает оба). Если Вы хотите блокировать трафик из сети 192.168.0.0/16, есть способ сделать это:
block in quick from 192.168.0.0/16 to any
pass in all
Теперь мы имеем не такой категоричный набор правил, но он выполняет уже какую-то полезную работу. Давайте представим, что к нам приходит пакет от 1.2.3.4. Применяем первое правило:
block in quick from 192.168.0.0/16 to any
Пакет — от 1.2.3.4, не 192.168.*. *, так что соответствия нет. Применяем второе правило:
pass in all
Пакет от 1.2.3.4 — определенно часть all, поэтому пакет невозбранно отправляется в пункт назначения.
С другой стороны, предположите, что мы имеем пакет, который входит от 192.168.1.2. Применяем первое правило:
block in quick from 192.168.0.0/16 to any
Есть соответствие, пакет отброшен, и это — конец. Первое правило применяться не будет, поскольку соответсвие произошло и имелось ключевое слово quick.
Сейчас Вы можете сформировать довольно обширный список адресов, которые будут пропускаться или блокироваться. Так как мы уже установили блокировку одного диапазона частных сетей, то давайте позаботимся и об остальных:
block in quick from 192.168.0.0/16 to any
block in quick from 172.16.0.0/12 to any
block in quick from 10.0.0.0/8 to any
pass in all
Первые три диапазона сетей принадлежат частному адресному пространству.
См. rfc1918 http://www.faqs.org/rfcs/rfc1918.html и
http://www.ietf.org/internet-drafts/draft-manning-dsua-06.txt.
10. Управление интерфейсами
Довольно распространенной ситуацией является, когда сеть компании содержит адреса из частной сети, перед тем, как выйти в Интернет. Фактически, это основная причина рассмотрения систем сетевой защиты. Машина соединяющая внешнюю и внутреннюю сети называется маршрутизатором.
Отличить его от обычного компьютера довольно просто — он имеет больше чем один сетевой интерфейс.
Каждый пакет, который Вы получаете, приходит с сетевого интерфейса, каждый пакет, который Вы отправляете, уходит с сетевого интерфейса. Скажем, Ваша машина имеет 3 интерфейса: lo0 (loopback), xl0 (3com ethernet), и tun0 (туннель FreeBSD’s для работы с PPP), но Вы не хотите получать пакеты, приходящие на tun0?
block in quick on tun0 all
pass in all
В этом случае ключевое слово on будет означать входящие данные. Если пакет входит на tun0, первое правило блокирует его. Если пакет входит на lo0 или на xl0, первое правило не будет соответствовать, второе правило будет, пакет будет пропущен.
11. Совместное использование IP адреса и интерфейса
Весьма странное состояние дел, когда у нас есть интерфейс, но данные с него заблокированы. Чем больше критериев используется для построения системы сетевой защиты, тем она становится надежней (или дырявей). Возможно Вы хотите получать данные от tun0, но запретить сеть 192.168.0.0/16? Это — начало мощной системы сетевой защиты.
block in quick on tun0 from 192.168.0.0/16 to any
pass in all
Сравните это с нашим предыдущим правилом:
Compare this to our previous rule:
block in quick from 192.168.0.0/16 to any
pass in all
В этом случае, весь трафик от 192.168.0.0/16 независимо от интерфейса был бы блокирован. В новом варианте предусматривается блокировка этой сети, только в том случае, если пакет пришел с интерфейса tun0 . Если бы пакет прибыл в интерфейс xl0 от 192.168.0.0/16, то он был бы пропущен.
Сейчас Вы можете сформировать довольно обширный список адресов, подлежащих блокировке или пропускаемых. Давайте озаботимся о блокировке частного диапазона сетей с интерфейса tun0:
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
block in quick on tun0 from 0.0.0.0/8 to any
block in quick on tun0 from 169.254.0.0/16 to any
block in quick on tun0 from 192.0.2.0/24 to any
block in quick on tun0 from 204.152.64.0/23 to any
block in quick on tun0 from 224.0.0.0/3 to any
pass in all
Вы уже видели первые три блока, но остальные нам еще не встречались. Четвертый — в значительной степени потраченная впустую сеть класса A, используемая для кольцевого интерфейса. Много программного обеспечения используют для работы 127.0.0.1, поэтому блокировка этого адреса из внешнего источника — хорошая идея. Пятый, 0.0.0.0/8, никогда не должен присутствовать в internet. Большинство стеков IP обрабатывает «0.0.0.0/32″ как заданный по умолчанию шлюз, и остальная часть сетей 0.*.*.* обрабатывается так, как этого пожелали разработчики программного обеспечения. Вы должны обработать 0.0.0.0/8 точно так же как и 127.0.0.0/8. 169.254.0.0/16 был назначен IANA для использования при автоматической конфигурации, когда IP адрес не может быть получен через DHCP или ему подобный протокол. Microsoft Windows будет использовать адреса из этого диапазона, если включена опция получения IP адреса от DHCP сервера и этот сервер недоступен. 192.0.2.0/24 был также зарезервирован для использования в качестве примеров авторами технической документации.
Мы намеренно не используем этот диапазон, поскольку это вызвало бы замешательство при использовании его в дальнейших примерах, поэтому мы будем использовать в качестве примера сеть 20.20.20.0/24.
204.152.64.0/23 — блок, зарезервированный Sun Microsystems для частных кластерных решений. Наконец, 224.0.0.0/3 охватывает «Класс D и E», используемые главным образом для группового трафика. хотя определение «Класса E» может быть найдено в rfc1166.
Довольно много программного обеспечения, производящего аутентификацию на базе IP адреса пакета. Если у Вас имеется внутренняя сеть 20.20.20.0/24, то Вы знаете, что трафик находится только в локальной сети и если пакет с таким адресом приходит с PPP, то вполне разумным будет отбросить этот пакет. Нельзя позволить ему пройти к пункту назначения. Вы можете легко достичь поставленной цели с текущими знаниями о IPF. Новый набо правил будет выглядеть так:
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
block in quick on tun0 from 0.0.0.0/8 to any
block in quick on tun0 from 169.254.0.0/16 to any
block in quick on tun0 from 192.0.2.0/24 to any
block in quick on tun0 from 204.152.64.0/23 to any
block in quick on tun0 from 224.0.0.0/3 to any
block in quick on tun0 from 20.20.20.0/24 to any
pass in all
12. Двунаправленная фильтрация. Ключевое слово «out»
До сего момента мы пропускали или блокировали приходящий трафик. Для ясности уточним — приходящий трафик — весь трафик, который входит в систему сетевой защиты с любого интерфейса. Исходящий трафик — весь трафик, который покидает машину с любого интерфейса (сгенерированный локально или транзитный). Мы можем предположить, что правило pass out all может пропускать и не желательный трафик. Точно также, как Вы можете пропускать или блокировать входящий на интерфейс трафик, Вы можете пропускать или блокировать исходящий трафик.
Вооруженные этим знанием, найдем ему применение. Одно из возможных применений — препятствовать spoofed пакетам выходить из вашей собственной сети. Вместо того, чтобы передавать любой трафик на маршрутизатор, ограничим разрешенный трафик пакетами, исходящими из сети 20.20.20.0/24.
Сделать это можно примерно так (можно, конечно, использовать DIPFILTER_DEFAULT_BLOCK при компилировании ipfilter на вашей системе):
pass out quick on tun0 from 20.20.20.0/24 to any
block out quick on tun0 from any to any
Если пакет исходит из сети 20.20.20.1/32, то он будет пропущен в соответствии с первым правилом. Если пакет исходит с адреса 1.2.3.4/32, то он блокируется вторым правилом.
Также Вы можете применять подобные правила к немаршрутизируемым адресам. Если некоторая машина пробует переслать пакет через IPF с адресом назначения 192.168.0.0/16, почему мы должны его пропускать? Вы можете даже сэкономить полосу пропускания за счет отсутствия паразитного трафика.
block out quick on tun0 from any to 192.168.0.0/16
block out quick on tun0 from any to 172.16.0.0/12
block out quick on tun0 from any to 10.0.0.0/8
block out quick on tun0 from any to 0.0.0.0/8
block out quick on tun0 from any to 127.0.0.0/8
block out quick on tun0 from any to 169.254.0.0/16
block out quick on tun0 from any to 192.0.2.0/24
block out quick on tun0 from any to 204.152.64.0/23
block out quick on tun0 from any to 224.0.0.0/3
block out quick on tun0 from !20.20.20.0/24 to any
С одной стороны, эти правила не улучшают Вашу защиту, они улучшают защиту других сетей, но это хороший поступок, который стоит сделать. С другой стороны ваша сеть не сможет использоваться взломщиками для атаки на другую сеть и никто не сможет послать spoofed пакеты из Вашей сети.
Вы, вероятно, найдете много способов применить блокировку исходящих пакетов.
13. Регистрация событий. Ключевое слово «log»
До этого момента все блокированные и переданные пакеты были тихо блокированы и тихо переданы. Обычно Вы хотите знать, атакуют ли Вас, а не задаетесь вопросом, окупает ли себя система сетевой защиты. В то время как я не хотел бы регистрировать каждый переданный пакет, и в некоторых случаях каждый блокированный пакет, я буду хотеть знать о блокированных пакетах из сети 20.20.20.0/24. Чтобы сделать это, мы добавляем ключевое слово «log»:
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
block in quick on tun0 from 0.0.0.0/8 to any
block in quick on tun0 from 169.254.0.0/16 to any
block in quick on tun0 from 192.0.2.0/24 to any
block in quick on tun0 from 204.152.64.0/23 to any
block in quick on tun0 from 224.0.0.0/3 to any
block in log quick on tun0 from 20.20.20.0/24 to any
pass in all
Пока, наша система сетевой защиты довольно хороша при блокировании подозрительных пакетов, приходящих извне, но поле для работы еще есть. С одной стороны, мы принимаем пакеты, у которых в качастве адреса назначения указано что угодно. Единственное, в чем мы должны удостовериться, что блокируются пакеты с адресами назначения 20.20.20.0/32 и 20.20.20.255/32, иначе наша сеть становится доступна для smurf атаки. Эти две строки препятствовали бы нашей гипотетической сети быть используемой в качестве ретранслятора smurf.
block in log quick on tun0 from any to 20.20.20.0/32
block in log quick on tun0 from any to 20.20.20.255/32
Теперь наш список правил выглядел бы следующим образом:
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
block in quick on tun0 from 0.0.0.0/8 to any
block in quick on tun0 from 169.254.0.0/16 to any
block in quick on tun0 from 192.0.2.0/24 to any
block in quick on tun0 from 204.152.64.0/23 to any
block in quick on tun0 from 224.0.0.0/3 to any
block in log quick on tun0 from 20.20.20.0/24 to any
block in log quick on tun0 from any to 20.20.20.0/32
block in log quick on tun0 from any to 20.20.20.255/32
pass in all
14. Полная двунаправленная фильтрация на интерфейсе
Пока мы только представили фрагменты законченного набора правил. Когда Вы пишете набор правил в реальных условиях, Вы должны установить правила для каждого интерфейса и каждого направления. По умолчанию, ipfilter будет пропускать пакеты, как будто прописаны два правила pass in all и pass out all. Вместо того, чтобы полагаться на небольшое количество правил, заданных по умолчанию, делайте все настолько определенно, насколько это возможно, интерфейс за интерфейсом, пока не будет охвачено все.
Начнем мы с интерфейса lo0. Так как множество программ на локальной машине работают с этим интерфейсом, то и правила будут соответствующими:
pass out quick on lo0
pass in quick on lo0
Затем следует интерфейс xl0. Позже мы начнем помещать ограничения на интерфейс xl0, но пока мы будем действовать, как будто в нашей локальной сети мы доверяем всем и поэтому правила будут такие же, как и для lo0:
pass out quick on xl0
pass in quick on xl0
Наконец, имеется интерфейс tun0.
block out quick on tun0 from any to 192.168.0.0/16
block out quick on tun0 from any to 172.16.0.0/12
block out quick on tun0 from any to 127.0.0.0/8
block out quick on tun0 from any to 10.0.0.0/8
block out quick on tun0 from any to 0.0.0.0/8
block out quick on tun0 from any to 169.254.0.0/16
block out quick on tun0 from any to 192.0.2.0/24
block out quick on tun0 from any to 204.152.64.0/23
block out quick on tun0 from any to 224.0.0.0/3
pass out quick on tun0 from 20.20.20.0/24 to any
block out quick on tun0 from any to any
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
block in quick on tun0 from 0.0.0.0/8 to any
block in quick on tun0 from 169.254.0.0/16 to any
block in quick on tun0 from 192.0.2.0/24 to any
block in quick on tun0 from 204.152.64.0/23 to any
block in quick on tun0 from 224.0.0.0/3 to any
block in log quick on tun0 from 20.20.20.0/24 to any
block in log quick on tun0 from any to 20.20.20.0/32
block in log quick on tun0 from any to 20.20.20.255/32
pass in all
У нас имеется уже довольно существенное количество правил фильтрации, защита сети 20.20.20.0/24 от спуфинга или быть используемым для спуфинга. Будущие примеры также будут работать только с одним интерфейсом, что необходимо для краткости изложния, но при написанни Вашего собственного набора правил не забывайте добавлять правила для каждого направления и каждого интерфейса.
15. Управление протоколами. Ключевое слово «proto»
Атаки типа Denial of Service (Отказ в обслуживании) являются столь же распространенными, как и переполнение буфера. Множество таких атак полагаются на сбои в стеке TCP/IP операционной системы. Часто DoS атаки принимают форму ICMP пакетов. Почему бы не блокировать их полностью?
block in log quick on tun0 proto icmp from any to any
Теперь любой ICMP трафик, приходящий на tun0 будет зарегистрирован и отброшен.
16. Фильтрация ICMP с помощью ключевого слова «icmp-type». Обьединение наборов правил.
Конечно, блокировать весь трафик ICMP — не самый лучший вариант. Почему? Да ведь если Вы хотите использовать утилиты ping и traceroute, Вы должны разрешить ICMP пакеты типов 0 и 11. Если Вы взвесили защиту и удобство, то IPF позволяет Вам сделать это:
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
Помните, что порядок следования правил очень важен, особенно при использовании ключевого слова quick, поэтому разрешающие правила должны стоять перед запрещающими:
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
block in log quick on tun0 proto icmp from any to any
Добавление этих 3 правил к anti-spoofing правилам имеет один тонкий момент. Одна ошибка могла бы состоять в том, чтобы поместить новые правила ICMP вначале:
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
block in log quick on tun0 proto icmp from any to any
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
block in quick on tun0 from 0.0.0.0/8 to any
block in quick on tun0 from 169.254.0.0/16 to any
block in quick on tun0 from 192.0.2.0/24 to any
block in quick on tun0 from 204.152.64.0/23 to any
block in quick on tun0 from 224.0.0.0/3 to any
block in log quick on tun0 from 20.20.20.0/24 to any
block in log quick on tun0 from any to 20.20.20.0/32
block in log quick on tun0 from any to 20.20.20.255/32
pass in all
Проблема с этим состоит в том, что ICMP пакеты типа 0 от сети 192.168.0.0/16 обойдут первое правило и никогда не будут блокироваться четвертым правилом. Таким же образом, так как мы передаем ICMP ECHO_REPLY (тип 0) к сети 20.20.20.0/24 используя quick, то мы только что открыли лазейку для проведения smurf атак. Ой. Чтобы избежать этого, мы разместим правила ICMP после правил anti-spoofing:
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
block in quick on tun0 from 0.0.0.0/8 to any
block in quick on tun0 from 169.254.0.0/16 to any
block in quick on tun0 from 192.0.2.0/24 to any
block in quick on tun0 from 204.152.64.0/23 to any
block in quick on tun0 from 224.0.0.0/3 to any
block in log quick on tun0 from 20.20.20.0/24 to any
block in log quick on tun0 from any to 20.20.20.0/32
block in log quick on tun0 from any to 20.20.20.255/32
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
block in log quick on tun0 proto icmp from any to any
pass in all
Поскольку мы блокируем spoofed трафик прежде, чем будут обработаны правила ICMP, spoofed пакет никогда не до них не дойдет. Очень важно сохранить такие ситуации в памяти при объединении правил.
17. TCP и UDP порты; ключевое слово «port»
Теперь, когда мы запустили блокировку пакетов, основанные на типе протокола, мы можем запустить блокировку пакетов, основанную на определенных аспектах каждого протокола. Наиболее часто используемый из этих аспектов — номер порта. Иметь такие сервисы, как rsh, rlogin, и telnet довольно удобно, но они довольно уязвимы для спуфинга и снифинга. Единственным приемлемым будет блокировка этих портов для доступа извне и разрешение доступа к этим портам изнутри. Это просто сделать, потому что rlogin, rsh, и telnet используют определенные порты TCP (513, 514, и 23 соответственно). Правила, блокирующие данные порты, довольно просты:
block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513
block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514
block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23
Удостоверьтесь, что все три правила находятся перед правилом pass in all и закрывают доступ снаружи (для краткости пропустим спуфинг).
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
block in log quick on tun0 proto icmp from any to any
block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513
block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514
block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23
pass in all
Возможно Вы захотите блокировать такие порты, как 514/udp (syslog), 111/tcp & 111/udp (portmap), 515/tcp (lpd), 2049/tcp and 2049/udp (NFS), 6000/tcp (X11) и т.д. и т.п. Вы можете просмотреть список открытых портов, используя утилиту используя netstat -a (или, если установлена, lsof -i).
Блокирование UDP вместо TCP только требует замены proto tcp на proto udp. Правило для syslog выглядит так:
block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 514
IPF имеет также сокращенную запись при одновременном блокировании proto tcp и proto udp, таком, как NFS или portmap. Правило для portmap будет выглядеть так:
block in log quick on tun0 proto tcp/udp from any to 20.20.20.0/24 port = 111
18. Введение в расширенную фильтрацию
Этот раздел является продолжением предидущего, начального раздела. Ниже рассматриваются расширенные методы построения сетевой защиты и возможности, присущие только ipfilter. После освоения этого раздела Вы будете способны разработать очень сильную систему сетевой защиты.
19. Необузданная паранойя; или политика запрета по умолчанию
Есть большая проблема с блокированием сервисов по номерам портов: иногда номера портов изменяются. Программы базирующиеся на RPC — ужасны, lockd, statd и даже nfsd могут слушать порты, отличные от 2049. Довольно тяжело проводить все время корректировку правил. А что если вы пропустите какую-либо службу? Итак, давайте начнем с чистого листа. Наш набор правил теперь будет выглядеть так:
block in all
Трафик не проходит. Никакой. Никуда. Гарантия абсолютной безопасности. Не очень полезно, но очень безопасно. Самая примечательная вещь состоит в том, что не потребуется слишком много усилий, для того чтобы сделать этот набор правил приносящим пользу. Пусть, на этой машине запущен web-сервер и ничего более, мы даже не используем DNS. Как следствие, мы хотим принимать соединения к 80/tcp. Мы разрешим это вторым правилом и Вы уже знаете как:
block in on tun0 all
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80
Теперь этот маршрутизатор передаст на порт 80 трафик для 20.20.20.1, и будет блокировать все остальное, включая ответы от порта 80 нашего web-сервера. Необходимо разрешить ответы:
block in on tun0 all
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80
pass out quick on tun0 proto tcp from 20.20.20.1/32 port = 80 to any
Для основного использования систем защиты сетей сделано все необходимое. Однако, есть более простой путь; мы будем использовать stateful правила.
20. Неявное разрешение. Правило «keep state»
Задачей любой системы сетевой защиты является предотвращение лишнего трафика из точки В точку А. Мы в настоящее время имеем правила, говорящие:т «если пакет идет к порту 23, то все хорошо» и «если у пакета установлен флаг FIN, то все хорошо». Наша система сетевой защиты ничего не знает о начале, середине, или конце любого TCP/UDP/ICMP сеанса. Просто у нас имеются неопределенные правила, которые являются применимыми ко всем пакетами. Ним остается только надеяться, что пакет с установленным флагом FIN не является FIN-сканированием, выясняющем имеющиеся у нас сервисы. Мы надеемся, что пакет, направленный к 23 порту — не атака на наш telnet-сервис. Возможное решение данной проблемы состоит в том, чтобы идентифицировать и пропускать пакеты индивидуальных TCP/UDP/ICMP сеансов и отличать их от сканирования портов и DoS атак. Это называется keeping state.
Мы хотим иметь одновременно и удобство и защиту. Этого хотят все, поэтому у Cisco есть критерий «established», для того, чтобы пропускать пакеты уже установленного tcp сеанса. Ipfw имеет опцию established. Ipfwadm имеет опции setup/established. все имеют эту особенность, но имя опции может вводить в заблуждение. Мы могли бы предположить, что данные пакетные фильтры действительно следят за установленными сессиями, но это не так. Они анализируют раздел флагов TCP пакета и не работают с UDP/ICMP, поскольку у этих пакетов таких флагов нет. Любой, кто может модифицировать флаги пакета, может обойти эту систему сетевой защиты.
В отличие от других систем сетевой защиты, IPF действительно способен следить за установленным соединением и работает с протоколами TCP, UDP и ICMP. Ключевое слово в наборе правил, служащее для реализации данной возможности называется keep state.
Вплоть до сего момента, мы считали, что пакет проверяется набором правил на входе и проверяется на выходе. Фактически же, входящий пакет проверяется сперва табицей состояний, и только тогда, может быть он будет проверен набором правил. Таблица состояний — это список TCP/UDP/ICMP сессий, установленных после прохода всего набора правил системы сетевой защиты. Думаете. что это дыра в защите? Держитесь крепче, это лучшее, что могло случиться с вашим фаерволлом!
Все TCP/IP сеансы имеют начало, середину, и конец (даже если все это в одном пакете). Не может быть конца без середины, и не может быть середины без начала. Это означает, что все, что Вы действительно должны фильтровать — начало TCP/UDP/ICMP сеанса. Если начало сеанса позволяется вашими правилами системы сетевой защиты, то следовательно будут пропущены пакеты середены и конца сеанса (это делается во избежание переполнения стека IP маршрутизатора). Keeping state позволяет игнорировать середину и конец сессии и сосредоточиться на блокировани/пропуске новых сеансов. Если блокирован пакет начала сеанса, то отбрасываются и все остальные. Вот пример, как можно получить доступ к ssh серверу:
block out quick on tun0 all
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 22 keep state
Первая вещь, на которую Вы можете обратить внимание, это то, что нет условия «pass out». Фактически, правилом на выход является только «block out». Несмотря на это, набор правил является законченным и полным, это связано с использованием ключевого слова keep state. Как только первый SYN пакет поступает в адрес ssh сервера, создается запись в таблице состояний и все остальные пакеты ssh сеанса проходят без вмешательства системы сетевой защиты. Вот другой пример:
block in quick on tun0 all
pass out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state
В этом случае на сервере не запущены никакие сервисы. И вообще, это — не сервер, это — клиент. И этот клиент не хочет иметь непрошенных пакетов вообще на своих интерфейсах никогда ни за что! Однако, клиент хочет иметь полный доступ к internet и получать ответные пакеты, что вполне объяснимо. Этот простой набор правил создает записи в таблице состояний для каждой новой исходящей TCP сессии. Как только такая запись будет создана, пакеты, принадлежащие сеансу смогут ходить, не подвергаясь проверке набором правил системы сетевой защиты. Как мы упоминали ранее, это работает для UDP и ICMP:
block in quick on tun0 all
pass out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state
pass out quick on tun0 proto udp from 20.20.20.1/32 to any keep state
pass out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state
Мы сделали это! Теперь у нас есть сохранение состояний сеансов TCP, UDP, ICMP. Теперь мы можем делать исходящие соединения, как будто вообще нет никакой системы сетевой защиты и в то же время, ни один злоумышленник не может соединиться с нами. Это очень удобно, потому что нет никакой необходимости выяснять, какие порты у нас открыты и мы можем предоставить доступ только к тем портам, к которым мы хотим.
Сохранение состояний — довольно хитрая штука. Могут происходить странные и таинственные вещи. Рассмотрим следующий пример:
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23
pass out quick on tun0 proto tcp from any to any keep state
block in quick all
block out quick all
На первый взгляд, все хорошо. Мы позволяем входящие сеансы на порт 23 и исходящие куда угодно. Естественно пакеты, идущие к порту 23 будут иметь ответные пакеты и набор правил установлен таким образом, что pass out будет делать записи в таблице состояний и все будет работать замечательно. Но есть одна маленькая мелочь.
Вся проблема состоит в том, 60 секунд запись будет удалена из таблицы состояния по таймауту в случае простоя (в отличии от положенных 5 дней). Это происходит потому, что Обработчик состояний никогда не видел оригинал SYN пакета, поступившего на порт 23, а видел только пакет SYN ACK. IPF очень хорош в отслеживании сеансов от начала до конца, но не с середины сеанса. Перепишите это правило следующим образом:
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state
pass out quick on tun0 proto tcp from any to any keep state
block in quick all
block out quick all
Ключевое слово keep state в первом правиле сделает необходимую запись в таблице состояний и все будет работать как ожидалось. Просмотреть текущие записи в таблице состояний Вы можете командой ipfstat -s.
21. Stateful UDP
UDP является протоколом без установления соединения, поэтому реализовать контроль за состоянием довольно сложно. Тем не менее, ipf делает это более-менее хорошо. Когда машина А посылает UDP пакет машине B с исходным портом X, и портом назначения Y, ipf разрешит ответ от машины B на машину А с исходным портом Y и портом назначения X. Эта запись будет действовать 60 секунд.
Вот пример использования утилиты nslookup для определения IP адреса узла www.3com.com:
$ nslookup www.3com.com
Будет сгенерирован пакет DNS:
17:54:25.499852 20.20.20.1.2111 > 198.41.0.5.53: 51979+
Пакет от 20.20.20.1, порт 2111, предназначен для 198.41.0.5, порт 53. На 60 секунд создано правило. Если пакет возвращается с 198.41.0.5 порт 53 для 20.20.20.1 порт 2111 в пределах этого периода времени, пакет будет пропущен. Чуть позже Вы можете увидеть:
17:54:25.501209 198.41.0.5.53 > 20.20.20.1.2111: 51979 q: www.3com.com
Ответный пает соответствует записи в таблице состояний и будет пропущен. После получения этого пакета запись будет удалена из таблицы и никакие другие паеты пропущены не будут, даже если у них будет прежний источник.
22. Stateful ICMP
IPFilter обрабатывает состояния ICMP таким же способом, как TCP и UDP, используя keep state. Есть два общих типа ICMP сообщений; запросы и ответы. Когда Вы записываете правило типа:
pass out on tun0 proto icmp from any to any icmp-type 8 keep state
для разрешения исходящих echo-запросов (утилита ping), то результатом будет icmp пакет типа 0, которому будет разрешено пройти. Для такой записи в теблице состояний таймаут установлен в 60 секунд. Таким образом Вы сохраняете состояние сеанса на любом исходящем icmp пакете с помощью правила типа proto icmp [...] keep state.
Однако, большинство ICMP сообщений — сообщения об ошибке, связанные с работой UDP (и иногда TCP), и в версиях IPFilter начиная с 3.4.x все ICMP сообщения об ошибках (такие как icmp-type 3 — порт недоступен, или icmp-type 11 — превышено время ожидания), пропускаются, в том случае, если IPF может найти запись в таблице состояния о сессии, которая могла повлечь появление такого сообщения. Например, в старых версиях IPFilter для работы traceroute Вам необходимо было использовать конструкцию:
pass out on tun0 proto udp from any to any port 33434><33690 keep state
pass in on tun0 proto icmp from any to any icmp-type timex
А сейчас сделать это можно используя только таблицу состояния UDP:
pass out on tun0 proto udp from any to any port 33434><33690 keep state
Для обеспечения защиты Вашей сети от посторонних ICMP сообщений, проверяется также не только адреса источника и назначения (и порты, когда это возможно), но и его содержимое.
23. Обнаружение FIN-сканирования. Ключевое слово «flags» и «keep frags»
Давайте вернемся к четырем правилам из предыдущего раздела:
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state
pass out quick on tun0 proto tcp from any to any keep state
block in quick all
block out quick all
Эти правила не совсем хороши тем, что могут позволить пройти на 23 порт не только пакетам SYN, но и любым старым пакетам. Изменить эту ситуацию мы можем следующим способом:
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state
pass out quick on tun0 proto tcp from any to any flags S keep state
block in quick all
block out quick all
Теперь пропущен будет только пакет TCP на 23 порт IP адреса 20.20.20.1/32 с установленным флагом SYN и по нему откроется запис