Справочник по IPFW
IPFIREWALL (IPFW) является поддерживаемым файрволлом FreeBSD, авторы и люди развивающие данное программное обеспечение являются добровольцами. Он использует правила наследования состояния и наследовние техники программирования для достижения того, что называется логикой Simple Stateful (простое состояние).
Пример набора правил для IPFW (находится в “/etc/rc.firewall”) в стандартной инсталляции FreeBSD довольно прост, и не предусматривается его прямое использование, без модификации. Примеры не используют фильтрацию состояния, которое необходимо в большинстве настроек, поэтому оно не будет использоваться как основа для этого раздела.
Правила состояний IPFW подразумевают технически сложные возможности выбора, которые могут превзойти уровень знания обычного пользователя брендмауэра. IPFW предназначен для профессионального пользователя, или для технически продвинутого человека, увлеченного своим хобби, которому требуются улучшенные возможности выбора пакетов. Высокий уровень знаний о том, как различные протоколы используют и создают свои уникальные заголовки пакетов, необходим перед тем, как будет выпущена сила IPFW. Предоставление такого рода объяснений, выходит за рамки данной раздела руководства.
IPFW составлен из семи компонентов, первичный компонент - брэндмауэр управляющий списком правил на уровне ядра и интегрированная в него возможность пакетного учета, возможность ведения логов, "divert" правила которые взаимодействуют с NAT, и улучшенные специальные средства, траффик dummynet, возможность шейпинга, возможность перенаправления "fwd rule", возможность бриджа, возможность ipstealth.
После перезагрузки вашей системы с “firewall_enable="YES"” в rc.conf, следующее собщение высветится на вашем экране как часть процесса загрузки:
Код: Выделить всё
ipfw2 initialized, divert disabled, rule-based forwarding disabled, default to deny, logging disabled
Код: Выделить всё
net.inet.ip.fw.verbose=1
net.inet.ip.fw.verbose_limit=5
Код: Выделить всё
options IPFIREWALL
Код: Выделить всё
options IPFIREWALL_VERBOSE
Код: Выделить всё
options IPFIREWALL_VERBOSE_LIMIT=5
Код: Выделить всё
options IPFIREWALL_DEFAULT_TO_ACCEPT
Код: Выделить всё
options IPV6FIREWALL
options IPV6FIREWALL_VERBOSE
options IPV6FIREWALL_VERBOSE_LIMIT
options IPV6FIREWALL_DEFAULT_TO_ACCEPT
Код: Выделить всё
options IPDIVERT
Примечание: если вы не включаете IPFIREWALL_DEFAULT_TO_ACCEPT или набор ваших правил позволяет входящие пакеты, вы блокируете все пакеты идущие к вам и от вашей машины.
Код: Выделить всё
firewall_enable="YES"
Код: Выделить всё
firewall_type="open"
Код: Выделить всё
[list]
тип значение
open пропускаем весь траффик
client будет защищать только эту машину
simple защита всей сети
closed полностью выключает весть IP траффик; исключая loopback интерфейс
UNKNOWN выключает загружаемые правила файрвола
filename абсолютный путь к файлу содержащему правила[/list]
Код: Выделить всё
add block in all
add block out all
Код: Выделить всё
#!/bin/sh
ipfw -q flush
ipfw add block in all
ipfw add block out all
Включаем протоколирование:
Код: Выделить всё
firewall_logging="YES"
Код: Выделить всё
net.inet.ip.fw.verbose_limit=5
Команды ipfw - обычное средство для создания одного правила, или добавления или удаления активного внутреннего правила файрвола, пока он загружен. Проблема использования данного метода состоит в том, что пока ваша система не выключится или зависнет, все правила которые были добавлены, или изменены, или удалены, потеряются. Запись всех правил в файл и использование этого файла для загрузки правил во время загрузки системы, или массовое замещения выполняемых в данный момент правил файрволла, изменениями которые вы записали в файл - рекомендованный метод, который здесь используется.
Комманда ipfw все еще очень полезна, для вывода используемых правил файрвола на консольный экран. Считывающее средство IPFW, динамически создает счетчик для каждого правила, которое считает каждый пакет, который совпадает с правилом. В течении процесса проверки правила, список правил с счетчиком является одним из способов определить функционирование правила.
Последовательный список всех правил:
Код: Выделить всё
ipfw list
Код: Выделить всё
ipfw -t list
Первая колонка, номер правил, сопровождаемая количеством совпавших исходящих пакетов, следующее за
номером входящих совпавших пакетов и затем, само правило.
Код: Выделить всё
ipfw -a list
Код: Выделить всё
ipfw -d list
Код: Выделить всё
ipfw -d -e list
Код: Выделить всё
ipfw zero
Код: Выделить всё
ipfw zero NUM
Когда пакет входит в файрволл, он сопоставляется с первым правилом в наборе и увеличивается на единицу за количество перемещений сверху вниз в списке по возрастанию номера правила в порядке следования. Когда пакет совпадает с выбранными правилами, значение области действия правил выбрано, для этого пакета поиск правил заканчивается. В поиске это упоминается как "первое совпадение побеждает". Если пакет не совпадает ни с одним из правил, он ловится принудительно правилом по умолчанию в ipfw, с номером 65535 которое отбрасывает все пакеты без отправления назад по тому же пути.
Примечание: Поиск будет продолжен, после count, skipto и tee правил.
Инструкции содержащиеся здесь базируются на использовании правил, которые содержат состояния "keep state", "limit", "in"/"out", а так же через опции. Это основа написания правил и включаемых типов в набор правил файрволла.
Включаемый набор правил файрволла только позволяет проходить сервисам через совпадения с правилами. Таким образом, вы можете контролировать какие сервисы пройдут от вас в интернет, и какие сервисы получат доступ к вашей частной сети из интернета. Все остальное будет отброшено по умолчанию. Включаемые наборы правил намного более безопасны, чем исключающие наборы, и это единственный тип правил рассматриваемый здесь.
Внимание: Когда работаете с правилами файрволла будьте внимательны, вы можеть заблокировать себя.
Синтаксис правил представленный тут, был упрощен потому, что необходимо создать стандарт правил файрволла включаемого типа. Для более полного описания синтаксиса правил смотрю5ю1справочную страницу ipfw.
Правила содержат ключевые значения: эти ключевые значения должны быть написаны в определенном порядке, слева направо в строчку. Ключевые слова выделены жирным. Некоторые ключевые слова имеют подопции, которые сами могут быть ключевыми словами и так же включать еще больше подопций.
# - используется для отметки начала комментария, и может следовать до конца строки правила или содержать собственные строки. Пустые строки игнорируются.
Код: Выделить всё
CMD RULE_NUMBER ACTION LOGGING SELECTION STATEFUL
Каждое новое правило, должно предворяться “add”, для того что бы добавить правило во внутреннюю таблицу.
Каждое правило должно иметь номер правила, для работы с ним.
Правило которое может быть ассоциировано с одним из следующих действий, которые будут запущены когда пакет совпадает с выбранным критерием правила.
Код: Выделить всё
allow | accept | pass | permit
Код: Выделить всё
check-state
Код: Выделить всё
deny | drop
Код: Выделить всё
log или logamount
Примечание: Протоколирование завершается после того, как состояние всех других пакетов будет успешно подтверждено и перед выполнением заключительного действия (“accept”, “deny”) над пакетом. Вам решать какое правило вы хотите протоколировать.
Ключевое слово описаное в данном разделе используется для описания атрибутов пакета, который будет опрошен при определении совпадает правило с пакетом или нет. Следующие признаки общего назначения, даны для соответствия и должны использоваться в таком порядке:
Код: Выделить всё
udp | tcp | icmp
Код: Выделить всё
from src to dst
Код: Выделить всё
port number
Код: Выделить всё
in | out
Код: Выделить всё
via IF
Код: Выделить всё
setup
Код: Выделить всё
keep-state
Код: Выделить всё
limit {src-addr | src-port | dst-addr | dst-port}
"check-state" используется для определения, в какой момент, в наборе правил IPFW, пакет должен быть проверен в таблице динамических правил. При совпадении, пакет покидает файрвол и продолжает свой путь, новое правило создается динамически для следующего ожидаемого пакета при обмене в течении этой двунаправленной сессии. При несовпадении, пакет продвигается к следующему правилу.
Динамические правила уязвимы для SYN-flood атак, которые открывают большое количество динамических правил. Для предотвращения подобного рода атак, во FreeBSD добавлена новая опция названная limit. Эта опция используется для ограничения числа одновременных сессий, путем опроса полей источника и полей назначения, указанных в опции limit и использования IP адресов пакетов найденых там же, в поиске открытых динамических правил подсчитывая количество правил и IP адресов, если количество больше, чем значение переменной limit, пакет отбрасывается.
Даже если возможность ведения логов включена, IPFW не создаст правила протоколирования сам. Администратор файрволла решает сам, какое правило в наборе он хочет протоколировать, и добавляет к этому правилу протоколирование. Обычно протоколируются только запрещающие правила, как например, правило запрещающее входящие ICMP пинги. Таким образом, вы увидите все пакеты, которые не совпадают ни с одним правилом, в наборе правил. Протоколирование - это палка о двух концах, если вы не осторожны, то вы потеряетесь в обилии логов и быстро заполните дисковое пространство расширяющимися лог файлами. DoS атаки которые быстро заполняют дисковый массив, одни из самых старых нападений. Эти логи пишутся не только в syslogd, но еще и на выводяться на главную консоль и быстро раздражают.
Опция ядра IPFIREWALL_VERBOSE_LIMIT=5 ограничивает количество сообщений посланных syslogd, относительно совпадения данного пакета правилу. Когда эта опция включена в ядро, число сообщений относительно определенного правила, заключено в определенном числе. Ничего не будет получено от 200 сообщений, которые говорят об одной и той же вещи. Например, 5 сообщений, относительно специфического правила были получены syslogd, остальные идентичные сообщения будут подсчитаны и переданы syslogd следующей фразой:
Код: Выделить всё
last message repeated 45 times
Синтаксис скрипта, который используется здесь, совместим c 'sh', 'csh', 'tcsh' оболочками. Поля с символической подменой, указываются в виде префикса, долларового знака '$' . Символические поля не имеют долларового знака. Значение записываемое в символическое поле должно быть заключено в "двойные кавычки".
Начните ваш файл с правилами, так:
Код: Выделить всё
############### начало примера скрипта с правилами ipfw #############
#
ipfw -q -f flush # Удаляем все правила
# Устанавливаем значения по умолчанию
oif="tun0" # выходной интерфейс
odns="192.0.2.11" # IP адрес DNS'а провайдера
cmd="ipfw -q add " # префикс создания правил
ks="keep-state" # слишком ломает писать это постоянно
$cmd 00500 check-state
$cmd 00502 deny all from any to any frag
$cmd 00501 deny tcp from any to any established
$cmd 00600 allow tcp from any to any 80 out via $oif setup $ks
$cmd 00610 allow tcp from any to $odns 53 out via $oif setup $ks
$cmd 00611 allow udp from any to $odns 53 out via $oif $ks
################### конец примера скрипта с правилами ipfw ############
Пример выше содержится в файле “/etc/ipfw.rules”, вы можете загрузить эти правила, набрав в командной строке следующее:
Код: Выделить всё
# sh /etc/ipfw.rules
Те же самое, могжет быть достигнуто загрузкой команд вручную:
Код: Выделить всё
ipfw -q -f flush
ipfw -q add check-state
ipfw -q add deny all from any to any frag
ipfw -q add deny tcp from any to any established
ipfw -q add allow tcp from any to any 80 out via tun0 setup keep-state
ipfw -q add allow tcp from any to 192.0.2.11 53 out via tun0 setup keep-state
ipfw -q add 00611 allow udp from any to 192.0.2.11 53 out via tun0 keep-state
Следующее не NAT набор правил - пример, как написать очень защищеный "включаемый" тип файрвола. Включаемый тип файрвола позволяет пройти через него только совпавшим сервисам, остальное он блокирует по умолчанию. Все файрволлы должены иметь, как минимум, два интерфейса которые должны иметь правила позволяющие файрволлу функционировать.
Все UNIX® подобные операционные системы разработаны для использования интерфейса lo0 и IP адреса 127.0.0.1 для внутреннего взаимодействия с операционной системой. Правила файрволла должны содержать правила, которые позволяют беспрепятственному хождению этих специальных, внутренних пакетов.
Интерфейс, который смотрит в интернет, один из тех, для которого вы пишите правила разрешают и управляют доступом в глобальную сеть, а так же запросами доступа из интернета. Это может быть вашим ppp tun0 интерфейсом или вашим NIC подсоединенным к DSL или кабельному модему.
В случаях, когда один, или более одного NIC, подключены к частному LAN'у за файрволлом, эти интерфейсы должны содержать правила для беспрепятственного хождения пакетов из LAN.
Сперва правила должны быть организованы в три разные секции, все беспрепятственные интерфейсы, публичные исходящие интерфейсы и публичные входящие интерфейсы.
В порядке построения правил, в каждой секции с публичным интерфейсом порядок следования правил следующий: часто используемые идут сначала, затем используемые реже, заключающим правилом должно быть блокирование и протоколирование всего на этом интерфейсе во всех направлениях.
Исходящая секция, в следующем наборе правил, содержит только правило "allow" , которое содержит значения выбора, которые точно идентифицируют сервис для публичного доступа в Интернет. Все правила имеют написанные опции proto, port, in/out, via и keep state. Правила "proto tcp" имеют опцию "setup" для идентификации запроса о начале сессии как сигнальный пакет который будет помещен в таблицу состояний keep-state.
Секция входящих, содержит вначале правила, блокирующие нежелательные пакеты, по двум разным причинам. Первая - блокированные пакеты могут быть частью, наоборот, правильного пакета который может быть пропущен дальнейшими правилами. Вторая - при наличии правила которое явно блокирует выбранные пакеты которые я получаю не часто, и не хочу видеть их в логах, это не дает пакету быть пойманым последним правилом, которое блокирует и протоколирует все пакеты которые не прошли правила. Последнее правило в секции, которое блокирует и протоколирует все пакеты дает вам возможность создать легальные улики для преследования людей, которые атакуют вашу систему.
Другая вещь, которую вы должны принять во внимание - никакого ответа нежелательным пакетам не возвращается, эти пакеты отбрасываются и исчезают. Таким образом, атакующие не имеют понятия, достиг ли пакет вашей системы. Чем меньше атакующий может узнать о вашей системе, тем более она защищена. Когда вы протоколируете пакеты с неизвестными вам номерами портов, посмотрите их номера в /etc/services или посетите http://www.securitystats.com/tools/portsearch.php и поищите номер порта, что бы понять для чего нужен данный номер порта. Посетите эту ссылку, что бы узнать какие номера портов используются троянцами: http://www.simovits.com/trojans/trojans.html.
Следующее не NAT набор правил, является полным набором правил включаемого типа. Не будет неправильным, использование данных правил для собственных целей. Всего лишь закоментируйте пропускающие правила для сервисов, которые вам не нужны. Если вы видите сообщения в лог файле, которые вы видеть не хотите, всего лишь добавьте deny правило в секцию входящих пакетов. Вам придется изменить имя интерфейса dc0 в каждом правиле на имя сетевой карты в вашей системе, которая смотрит в интернет. Для пользователя ppp имя будет tun0.
Вы увидите образец использования правил:
Все состояния которые запрашивают начало сессии с интернетом используют keep-state
Все разрешенные сервисы которые приходят из интернета имеют опцию limit для предотвращения флуда
Все правила используют in или out для определения направления
Все правила используют via имя интерфейса, для определения интерфейса через который будет проходить пакет.
Следующие правила идут в “/etc/ipfw.rules”.
[spoilerСледующие правила идут в “/etc/ipfw.rules”.]################ Начало файла правил IPFW ###############################
# Прежде, чем мы начнем, сбросим список
ipfw -q -f flush
# Установим префикс команды для набора правил
cmd="ipfw -q add"
pif="dc0" # имя сетевой карты, которая смотрит в Интернет
#################################################################
# Нет запретов внутри интерфейса смотрящего в локальную сеть
# не нужно до той поры, пока у вас нет локальной сети
# Измените имя xl0 на имя сетевой карты смотрящей в локальную сеть
#################################################################
#$cmd 00005 allow all from any to any via xl0
#################################################################
# Нет ограничений на Loopback интерфейсе
#################################################################
$cmd 00010 allow all from any to any via lo0
#################################################################
# Позволяем пакету проходить, если предыдущий был добавлен
# в "динамическую" таблицу правил с разрешением состояния keep-state.
#################################################################
$cmd 00015 check-state
#################################################################
# Интерфейс смотрящий в интернет (Исходящая секция)
# Опрашиваем запросы начала сессии идущие из-за файрвола
# в локальную сеть или от гейта в Интернет
#################################################################
# Разрешаем исходящий доступ к DNS моего провайдера.
# x.x.x.x должны быть IP адреса DNS вашего провайдера.
# Повторите эти строки, если ваш провайдер имеет более одного DNS сервера.
# Возмите IP адреса из файла /etc/resolv.conf
$cmd 00110 allow tcp from any to x.x.x.x 53 out via $pif setup keep-state
$cmd 00111 allow udp from any to x.x.x.x 53 out via $pif keep-state
# Разрешаем исходящий доступ к DHCP серверу моего провайдера для
# кабельных/DSL конфигураций.
# Это правило не потребуется для пользователя с ppp. соединением в Интернет.
# поэтому вы можете удалить целую группу.
# Используйте следующее правило и проверьте лог для выяснения IP адреса.
# Затем запишите IP адрес в закоментированное правило и удалите первое правило
$cmd 00120 allow log udp from any to any 67 out via $pif keep-state
#$cmd 00120 allow udp from any to x.x.x.x 67 out via $pif keep-state
# Разрешаем исходящие не безопасные стандартные www функции
$cmd 00200 allow tcp from any to any 80 out via $pif setup keep-state
# Разрешаем исходящие безопасные www функции https через TLS SSL
$cmd 00220 allow tcp from any to any 443 out via $pif setup keep-state
# Разрешаем исходящую функцию отправки и приема почты
$cmd 00230 allow tcp from any to any 25 out via $pif setup keep-state
$cmd 00231 allow tcp from any to any 110 out via $pif setup keep-state
# Разрешаем исходящие FBSD (make install & CVSUP) функции
# Проще говоря даем пользователю root "GOD" привилегии.
$cmd 00240 allow tcp from me to any out via $pif setup keep-state uid root
# Разрешаем исходящий пинг
$cmd 00250 allow icmp from any to any out via $pif keep-state
# Разрешаем исходящий Time
$cmd 00260 allow tcp from any to any 37 out via $pif setup keep-state
# Разрешаем исходящий nntp news (т.е. группы новостей)
$cmd 00270 allow tcp from any to any 119 out via $pif setup keep-state
# Разрешаем исходящую безопасные FTP, Telnet, and SCP
# Эта функция используется SSH (безопасным shell)
$cmd 00280 allow tcp from any to any 22 out via $pif setup keep-state
# Разрешаем исходящий whois
$cmd 00290 allow tcp from any to any 43 out via $pif setup keep-state
# Запрещаем и протоколируем все остальное пытающееся пройти.
# Это правило предписывает блокировать и протоколировать все по умолчанию.
$cmd 00299 deny log all from any to any out via $pif
#################################################################
# Интерфейс смотрящий в Internet (Входящая секция)
# Опрашиваем запросы начала сессии идущие из Интернета
# в локальную сеть или к гейту
#################################################################
# Запрещаем весь входящий траффик из зарезервированных адресных пространств
$cmd 00300 deny all from 192.168.0.0/16 to any in via $pif #RFC 1918 private IP
$cmd 00301 deny all from 172.16.0.0/12 to any in via $pif #RFC 1918 private IP
$cmd 00302 deny all from 10.0.0.0/8 to any in via $pif #RFC 1918 private IP
$cmd 00303 deny all from 127.0.0.0/8 to any in via $pif #loopback
$cmd 00304 deny all from 0.0.0.0/8 to any in via $pif #loopback
$cmd 00305 deny all from 169.254.0.0/16 to any in via $pif #DHCP auto-config
$cmd 00306 deny all from 192.0.2.0/24 to any in via $pif #reserved for docs
$cmd 00307 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster interconnect
$cmd 00308 deny all from 224.0.0.0/3 to any in via $pif #Class D & E multicast
# Запрещаем публичные пинги
$cmd 00310 deny icmp from any to any in via $pif
# Запрещаем ident
$cmd 00315 deny tcp from any to any 113 in via $pif
# Запрещаем весь сервис Netbios. 137=имя, 138=дейтаграмма, 139=сессия
# Netbios это сервис общего доступа MS/Windows .
# Блокируем MS/Windows hosts2 name server requests 81
$cmd 00320 deny tcp from any to any 137 in via $pif
$cmd 00321 deny tcp from any to any 138 in via $pif
$cmd 00322 deny tcp from any to any 139 in via $pif
$cmd 00323 deny tcp from any to any 81 in via $pif
# Запрещаем пакеты прибывшие позже
$cmd 00330 deny all from any to any frag in via $pif
# Запрещаем ACK пакеты которые не совпадают с динамической таблицей правил
$cmd 00332 deny tcp from any to any established in via $pif
# Разрешаем входящий траффик от DHCP сервера провайдера.
# Это правило должно содержать
# IP адрес DHCP сервера вашего провайдера, так как только
# он является авторизованым источником
# для отправки пакетов такого типа.
# Необходимо только для кабельных или DSL конфигураций.
# Это правило не нужно для пользователя с соединяющегося с интернетом по ppp.
# Это тот же IP адрес который мы получили и использовали в исходящей секции
#$cmd 00360 allow udp from any to x.x.x.x 67 in via $pif keep-state
# Разрешаем входящую www функцию потому что у меня стоит сервер apache
$cmd 00400 allow tcp from any to me 80 in via $pif setup limit src-addr 2
# Разрешаем входящие безопасные FTP, Telnet, and SCP из интернета
$cmd 00410 allow tcp from any to me 22 in via $pif setup limit src-addr 2
# Разрешаем входящие небезопасные Telnet сессии из интернета
# указано как небезопасные потому что ID & PW передаются через интернет
# открытым текстом
# Удаляем эту группу правил, если у вас нет работающего telnet сервера.
$cmd 00420 allow tcp from any to me 23 in via $pif setup limit src-addr 2
# Отбрасываем и протоколируем все входящие пакеты из внешнего мира
$cmd 00499 deny log all from any to any in via $pif
# Остальное отбрасывается по умолчанию
# отбрасываем и протоколируем все непрошедшие пакеты,
# что бы можно было увидеть какие они
$cmd 00999 deny log all from any to any
################ Конец файла правил IPFW ###############################[/spoiler]
Здесь приводятся дополнительные состояния конфигурации, для включения функции NAT в IPFW. В исходный код ядра должна быть добавлена опция 'option divert', к другим опциям IPFIREWALL, скомпилированым в произвольное ядро.
В дополнение к обычным опциям IPFW в файле “/etc/rc.conf”, должны быть добавлены следующие.
Код: Выделить всё
natd_enable="YES" # Включаем NATD функцию
natd_interface="rl0" # имя интерфейса который смотрит в интернет
natd_flags="-dynamic -m" # -m = preserve port numbers if possible
Cледующий, непрокоментированный пример, одного метода написания правил, выбранного для объяснения прохождения пакета через набор правил.
Процесс прохождения начинается с первого правила, в верхней строчки файла правил и увеличивается на одно правило за раз, ниже пока не достигнет конца, или пакет не будет проверен по критерию отбора на совпадение и пакет будет отпущен файрволлом. Важно заметить местоположение правил 100, 101, 450, 500, and 510. Эти правила управляют трансляцией исходящих и входящих пакетов и поэтому их keep-state записи в динамической таблице всегда регистрируют адрес частной локальной сети. Далее, обратите внимание на то, что все разрешающие и запрещающие правила определены в направлении движения пакета. Так же учтите, что исходящие запросы на начало сессии в правиле 500 для трансляции адресов.
Предположим, что пользователь локальной сети использует браузер для просмотра страниц. Web страницы используют 80 порт для соединений. Итак, пакет входит в файрволл, он не совпадает с правилом с номером 100, потому, что он выходит, а не входит. Он минует правило 101, потому что это первый пакет и у него нет keep-state записи в динамической таблице. Пакет наконец, добирается до правила 125, и совпадает с ним. Это исходящий пакет, идущий через интерфейс, смотрящий в интернет. Пакет все еще имеет адрес источника, который является адресом в частной локальной сети. При совпадении с правилом, производяться два действия. Опция keep-state запишет это правило в динамическую таблицу keep-state правил и выполнит указанное действие. Действие - это часть информации записаной в динамическую таблицу. В этом случае оно "skipto rule 500". Правило 500 транслирует сетевой IP адрес пакета и выпустит его. Запомните это, это очень важно. Этот пакет проделывает путь до пункта назначения и возвращается обратно, и попадает в начало набора правил. В этот раз, он совпадает с правилом 100 и IP адрес его пункта назначения транслируется обратно в его адрес в локальной сети. Затем он обрабатывается правилом check-state, он находится в таблице существующих сессий и выпускается в локальную сеть. Он идет к компьютеру в локальной сети, который посылал этот пакет и отправляет новый пакет запрашивая другой сегмент данных от удаленного сервера. В этот раз он проверяется правилом check-state, исходящая запись найдена, связанное действие выполняет "skipto 500". Пакет переходит к правилу 500, транслируется и выпускается наружу. С входящей стороны все что приходит, является частью существующей сессии и автоматически обрабатывается правилом check-state и должным образом помещается в правила divert natd. Все что мы должны сделать, это обратиться по адресу отбрасывающему пакеты и поддерживающему только авторизованные сервисы. Предположим, у нас есть сервер Apache работающий за файрволлом и мы хотим, что бы люди в интернете, могли получить доступ к веб сайту. Новый входящий пакет запроса совпадает с правилом 100, и его IP адрес в локальной сети транслируется для файрволла. Пакет проверяется на все гадкие штучки, на которые мы хотим его проверить и, наконец, совпадает с правилом 425. При совпадении, происходят две следующие вещи. Правило пакета записывается в динамическую таблицу keep-state, но на этот раз, все запросы о создании новой сессии, приходящие от исходного IP адреса, ограничены 2. Это защищает от DDoS атак на сервис работающий по определенному порту. Действие допускается, поэтому пакет отправляется в локальную сеть. По возвращению check-state правило расценивает пакет как принадлежащий существующей сессии и отправляет его на правило 500, для трансляции и последующего выпуска на выходной интерфейс.
Пример набора правил 1:
[spoilerПример набора правил 1]#!/bin/sh
cmd="ipfw -q add"
skip="skipto 500"
pif=rl0
ks="keep-state"
good_tcpo="22,25,37,43,53,80,443,110,119"
ipfw -q -f flush
$cmd 002 allow all from any to any via xl0 # exclude LAN traffic
$cmd 003 allow all from any to any via lo0 # exclude loopback traffic
$cmd 100 divert natd ip from any to any in via $pif
$cmd 101 check-state
# Разрешенные выходящие пакеты
$cmd 120 $skip udp from any to xx.168.240.2 53 out via $pif $ks
$cmd 121 $skip udp from any to xx.168.240.5 53 out via $pif $ks
$cmd 125 $skip tcp from any to any $good_tcpo out via $pif setup $ks
$cmd 130 $skip icmp from any to any out via $pif $ks
$cmd 135 $skip udp from any to any 123 out via $pif $ks
# Запрещаем весь входящий траффик из зарезервированных адресных пространств
$cmd 300 deny all from 192.168.0.0/16 to any in via $pif #RFC 1918 private IP
$cmd 301 deny all from 172.16.0.0/12 to any in via $pif #RFC 1918 private IP
$cmd 302 deny all from 10.0.0.0/8 to any in via $pif #RFC 1918 private IP
$cmd 303 deny all from 127.0.0.0/8 to any in via $pif #loopback
$cmd 304 deny all from 0.0.0.0/8 to any in via $pif #loopback
$cmd 305 deny all from 169.254.0.0/16 to any in via $pif #DHCP auto-config
$cmd 306 deny all from 192.0.2.0/24 to any in via $pif #reserved for docs
$cmd 307 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster
$cmd 308 deny all from 224.0.0.0/3 to any in via $pif #Class D & E multicast
# Разрешенные входящие пакеты
$cmd 400 allow udp from xx.70.207.54 to any 68 in $ks
$cmd 420 allow tcp from any to me 80 in via $pif setup limit src-addr 1
$cmd 450 deny log ip from any to any
# Местоположение skipto для исходящих правил состояния
$cmd 500 divert natd ip from any to any out via $pif
$cmd 510 allow ip from any to any
######################## конец правил ##################[/spoiler]
Написанное ниже, в значительной степени похоже, на написанное выше, но используется прокоментированный стиль написания правил, дабы помочь неопытным писателям правил IPFW, что правила делают.
Пример набора правил 2:
[spoilerПример набора правил 2]#!/bin/sh
################ Начало файла правил IPFW ###############################
# Прежде, чем мы начнем, сбросим список
ipfw -q -f flush
# Установим префикс команды для набора правил
cmd="ipfw -q add"
skip="skipto 800"
pif="rl0" # имя сетевой карты, которая смотрит в Интернет
#################################################################
# Нет запретов внутри интерфейса смотрящего в локальную сеть
# не нужно до той поры, пока у вас нет локальной сети
# Измените имя xl0 на имя сетевой карты смотрящей в локальную сеть
#################################################################
$cmd 005 allow all from any to any via xl0
#################################################################
# Нет ограничений на Loopback интерфейсе
#################################################################
$cmd 010 allow all from any to any via lo0
#################################################################
# проверяем если пакет входящий и транслирван ли он
#################################################################
$cmd 014 divert natd ip from any to any in via $pif
#################################################################
#Позволяем пакету проходить, если предыдущий был добавлен
# в "динамическую" таблицу правил с разрешением состояния keep-state.
#################################################################
$cmd 015 check-state
#################################################################
#Интерфейс смотрящий в интернет (Исходящая секция)
# Опрашиваем запросы начала сессии идущие из-за файрвола
# в локальную сеть или от гейта в Интернет
#################################################################
# Разрешаем исходящий доступ к DNS моего провайдера.
# x.x.x.x должны быть IP адреса DNS вашего провайдера.
# Повторите эти строки, если ваш провайдер имеет более одного DNS сервера.
# Возмите IP адреса из файла /etc/resolv.conf
$cmd 020 $skip tcp from any to x.x.x.x 53 out via $pif setup keep-state
# Разрешаем исходящий доступ к DHCP серверу моего провайдера для
# кабельных/DSL конфигураций.
$cmd 030 $skip udp from any to x.x.x.x 67 out via $pif keep-state
# Разрешаем исходящие не безопасные стандартные www функции
$cmd 040 $skip tcp from any to any 80 out via $pif setup keep-state
# Разрешаем исходящие безопасные www функции https через TLS SSL
$cmd 050 $skip tcp from any to any 443 out via $pif setup keep-state
# Разрешаем исходящую функцию отправки и приема почты
$cmd 060 $skip tcp from any to any 25 out via $pif setup keep-state
$cmd 061 $skip tcp from any to any 110 out via $pif setup keep-state
# Разрешаем исходящие FBSD (make install & CVSUP) функции
# Проще говоря даем пользователю root "GOD" привилегии.
$cmd 070 $skip tcp from me to any out via $pif setup keep-state uid root
# Разрешаем исходящий пинг
$cmd 080 $skip icmp from any to any out via $pif keep-state
# Разрешаем исходящий Time
$cmd 090 $skip tcp from any to any 37 out via $pif setup keep-state
# Разрешаем исходящий nntp news (т.е. группы новостей)
$cmd 100 $skip tcp from any to any 119 out via $pif setup keep-state
# Разрешаем исходящую безопасные FTP, Telnet, and SCP
# Эта функция используется SSH (безопасным shell)
$cmd 110 $skip tcp from any to any 22 out via $pif setup keep-state
# Разрешаем исходящий whois
$cmd 120 $skip tcp from any to any 43 out via $pif setup keep-state
# Разрешаем прохождение пакетов от ntp time server
$cmd 130 $skip udp from any to any 123 out via $pif keep-state
#################################################################
# Интерфейс смотрящий в Internet (Входящая секция)
# Опрашиваем запросы начала сессии идущие из Интернета
# в локальную сеть или к гейту
#################################################################
# Запрещаем весь входящий траффик из зарезервированных адресных пространств
$cmd 300 deny all from 192.168.0.0/16 to any in via $pif #RFC 1918 private IP
$cmd 301 deny all from 172.16.0.0/12 to any in via $pif #RFC 1918 private IP
$cmd 302 deny all from 10.0.0.0/8 to any in via $pif #RFC 1918 private IP
$cmd 303 deny all from 127.0.0.0/8 to any in via $pif #loopback
$cmd 304 deny all from 0.0.0.0/8 to any in via $pif #loopback
$cmd 305 deny all from 169.254.0.0/16 to any in via $pif #DHCP auto-config
$cmd 306 deny all from 192.0.2.0/24 to any in via $pif #reserved for docs
$cmd 307 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster
$cmd 308 deny all from 224.0.0.0/3 to any in via $pif #Class D & E multicast
# Запрещаем ident
$cmd 315 deny tcp from any to any 113 in via $pif
# Запрещаем весь сервис Netbios. 137=имя, 138=дейтаграмма, 139=сессия
# Netbios это сервис общего доступа MS/Windows .
# Блокируем MS/Windows hosts2 name server requests 81
$cmd 320 deny tcp from any to any 137 in via $pif
$cmd 321 deny tcp from any to any 138 in via $pif
$cmd 322 deny tcp from any to any 139 in via $pif
$cmd 323 deny tcp from any to any 81 in via $pif
# Запрещаем пакеты прибывшие позже
$cmd 330 deny all from any to any frag in via $pif
# Запрещаем ACK пакеты которые не совпадают с динамической таблицей правил
$cmd 332 deny tcp from any to any established in via $pif
# Разрешаем входящий траффик от DHCP сервера провайдера.
# Это правило должно содержать
# IP адрес DHCP сервера вашего провайдера, так как только
# он является авторизованым источником
# для отправки пакетов такого типа.
# Необходимо только для кабельных или DSL конфигураций.
# Это правило не нужно для пользователя с соединяющегося с интернетом по ppp.
# Это тот же IP адрес который мы получили и использовали в исходящей секции
$cmd 360 allow udp from x.x.x.x to any 68 in via $pif keep-state
# Разрешаем входящую www функцию потому что у меня стоит сервер apache
$cmd 370 allow tcp from any to me 80 in via $pif setup limit src-addr 2
# Разрешаем входящие безопасные FTP, Telnet, and SCP из интернета
$cmd 380 allow tcp from any to me 22 in via $pif setup limit src-addr 2
# Разрешаем входящие небезопасные Telnet сессии из интернета
# указано как небезопасные потому что ID & PW передаются через интернет
# открытым текстом
# Удаляем эту группу правил, если у вас нет работающего telnet сервера.
$cmd 390 allow tcp from any to me 23 in via $pif setup limit src-addr 2
# Отбрасываем и протоколируем все входящие пакеты из внешнего мира
$cmd 400 deny log all from any to any in via $pif
# # Отбрасываем и протоколируем все исходящие пакеты во внешний мир
$cmd 450 deny log all from any to any out via $pif
# Местоположение skipto для исходящих правил состояния
$cmd 800 divert natd ip from any to any out via $pif
$cmd 801 allow ip from any to any
# Остальное отбрасывается по умолчанию
# отбрасываем и протоколируем все непрошедшие пакеты,
# что бы можно было увидеть какие они
$cmd 999 deny log all from any to any
################ Конец файла правил IPFW ###############################[/spoiler]
Источники:
http://www.lissyara.su