12 Июля, 2019

ipfw в FreeBSD.

Денис Забияко
Хая.

Итак, сегодня будем настраивать ipfw в FreeBSD. В NetBSD он тоже используется, и, я думаю,не сильно отличается от Фришного. Для начала нужно перекомпилировать ядро с поддержкой ipfwи нескольких других функций. Стандартное cd /usr/src/sys/i386/conf. Далее открываем имеющийся конфиг ядра или же создаем новый. Все прелести сего занятия я расписывать не буду, расскажу только самое нужное.

Следующие строки необходимо добавить в ядро:
pseudo-device   bpf
Сие чудо по идее занимается фильтровкои пакетов. Если будешь сниффить, то сотри нафиг.
options IPFIREWALL
options IPFIREWALL_FORWARD

Включение firewall'а в ядро и  поддержка оным transparent proxy
options IPFIREWALL_VERBOSE

Для логов работы фаиервола
options DUMMYNET

Если собираешься накладывать лимиты на траффик(толщина,задержка etc.) то обязательно добавь это
options IPFIREWALL_DEFAULT_TO_ACCEPT

По умолчанию все пакеты будут пропускаться. Думай сам -если загрузка идет с использованием сети,
то есть шанс не загрузиться ВООБЩЕ.
options IPFIREWALL_VERBOSE_LIMIT=xxx

Установка лимита. Актуально при частых DoS'ах на твои хост.
options IPDIVERT

Если собираешься пускать народ из своей локалки, то это необходимо для правильной работы ipfw
options ICMP_BANDLIM

Поможет при DoS'ах.
Основные компоненты добавлены. Теперь Скомпилим новое ядро.
/usr/sbin/config <имя конфига ядра>
cd ../. ./compile/
make depend
make
make install
Перед тем как перезагрузиться, необходимо сделать некоторые изменения в конфигах системы
В /etc/rc.conf добавляем следующие строки:
firewall_enable="YES"
firewall_script="/etc/rc.firewall"
firewall_mode="open"
firewall_quiet="YES"
firewall_logging="NO"
Теперь можно перезагрузиться. Если bsdbox загрузился нормально(странно...-)), то можно переити
непосредственно к настроике рулесов. Я умалчиваю то, что все операции нужно делать под рутом.
Для пущей наглядности представим следующую схему сети. У нас есть локальная сеть с IP от 192.168.0.1
до 192.168.0.10 (т.е. 10 компов в ней). Все соединение в локали идет через сет. интерфеис rl0(карточка Realtek).
Подключение к Инету идет через интерфеис tun0 и имеется постоянный IP 212.94.25.78(брал наугад).
Также мы хотим пускать на свои FTP-сервер друзей от проваидера kewlprov.ru и разрешить ssh-соединения
с ourserver.com. Апач будет работать и на локальную сеть и на инет. У нас имеется httpd(80), ftpd(21), sshd(22), identd(113), smbd(139). Предполагается полная функциональность
всех имеющихся сервисов.
Настроика производится из командной строки указанием параметров. Стандартный вид команды для фильтровки пакетов
без особых условий имеет такои вид:
ipfw [action] [no. of rule] [protocol] [address] [sour. port] [dest. addr.] [dest. prot] [direction]
Также есть несколько ключей для команды:
-N      -производить обработку имен хостов в ИП-адреса на выходе
-q      -вести себя тихо; очень удобно при написании скриптов настроики ipfw
-a      -при выводе всех правил показывать значение счетчика
-t       -при выводе показывать последнее время использования правила
Насчет того, чтов rc.conf выбрали тип open, не переживай-все настроится в виде отдельного скрипта
(что гораздо удобнеи). Исключение можеть составлять лишь случаи с полноценным сервером, когда при загрузке должны
инициализироваться все рулесы-придется править rc.firewall, но смысл не меняется.
Можно создать скрипт в домашней директории рута, пожно прописать все в .profile. Я предпочел первое.
Вообще вся суета с внешними скриптами исключительно по моему нежеланию возиться в большом rc.firewall и загружаться в
single mode из-за маленькой ошибочки. Я еще раз повторяю-куда прописывать рулесы дело добровольное. Набираем vi .fw и начинаем править
#!/bin/sh
#Будет у нас шелл-скрпт
`ipfw -q add 1 allow tcp from any to 212.94.25.78 80,113 in`
#Разрешим соединение по http и идент-запросы(в основном для ИРС)
`ipfw -q add 2 allow tcp from kewlprov.ru/24 to 212.94.25.78 20,21 in`
#Соединение по ФТП разрешим только с подсети kewlprov.ru
`ipfw -q add 3 allow tcp from ourserver.com to 212.94.25.78 22 in`
#SSH-соединения с  ourserver.com
`ipfw -q add 4 allow udp from any to any`
#DNS запросы как к нашему серверу, так и от нашего сервера на более крупные. Можно ограничить  запросы только с
#локальной сети
`ipfw -q add 5 allow tcp from 192.168.0.0 to 192.168.0.1 20,21,22,139 in via rl0`
#Для локалки разрешим обращение к шарам, ФТП и SSH
`ipfw -q add 50 reset tcp from any to 212.94.25.78 1-1024 in`
#Мааленький фокус: если заместо reset написать deny, то портсканеры будут видеть это(диапазон портов закрытый фаиерволом)
#что не есть хорошо. А так в ответ на все запросы будет посылаться tcp-пакет с командным битом RST
`ipfw -q add 51 reset tcp from any to any 6000 in`
#Спброс всех соединении на 6000 порт. Актуально когда есть Иксы
`ipfw -q add 52 drop udp from any to any 1-1024,6000 in`
#Запрещать входящие UDP-соединения по 1-1024 и 6000 портам
Далее можно инициализировать скрипт как вручную, так и при входе в систему под рутом. Но есть и третии вариант.
В .profile прописываем следующую строку
alias fwstart='~/.fw'
Теперь по вводе команды fwstart будет инициализироваться наша схема. Посмотреть текущие установки можно по команде
ipfw l
Можно использовать ключи at. Я обычно ввожу ipfw -a l . Также можно установить несколько дополнительных мер защиты
1. Т.к. фаиервол инициализируется с параметром open(при загрузке системы), то сразу же присутствует такои рулес:
65000 allow ip from any to any
Все входящие соединения по основным службам мы вроде ограничили, теперь осталось обезопасить от входящих
соединений по 1024-65535 портам, дабы предотвратить установку руткита в случае взлома. Для этого запретим все tcp-соединения,
в заголовках которых присутсвует только командный бит SYN(запрос на установку соединения). Для запугивания
можно отсылать ICMP-шку port unreachable
'ipfw -q add 53 unreach port tcp from any to 212.94.25.78 1025-65535 in setup'
Все! Ни один руткит на дальних портах не получит соединения! Разумеется если есть дополнительные сервисы на указанном
диапазоне, то необходимо их прописать с индексом до 53(ipfw add 25 allow tcp from any to any 6667 in -для IRC-daemon'а). Повторяю-это правило
будет срабатывать только для пакетов с битом SYN -ответ на запрос о соединении содержит биты SYN и ACK, поэтому они будут спокоино
проходить мимо этого рулеса(для DCC в ИРС, например). Еще прикольней прописать unreach host -на пинги отвечаешь, а соединиться к тебе нельзя.
2. Можно ограничивать трафик. Для этого необходимо включить в ядро DUMMYNET. Лимитирование трафика делается с помощью пайпов(pipes).
Формат следующий:
ipfw -q add [no. of rule] pipe [no. of pipe] [prot.] from [host] [port] to [host] [port] [direction] [opts.]
Далее необходимо задать параметры для паипа
ipfw pipe [no. of pipe] config bw [bandwidth] queue [queue size] plr [loss-rate, in float. point number] delay [in ms]
Здесь приведены основные функции. Для того, чтобы ограничить все соединения из локалки (в случае работы BSDbox'a как геитвея) до 5кбайт/сек
нужно набрать следующее:
ipfw add 25 pipe 1 ip from 192.168.0.0/24 to any
ipfw pipe 1 config bw 5Kbyte/s queue 20Kbytes delay 100
Если тебе как админу не нравится Квака(ну мало ли че..) то можно нагадить квакерам из локалки следующим образом:
ipfw add 26 pipe 2 ip from 192.168.0.0/24 to quake.server.ru
ipfw pipe 2 config delay 750
С таким зверским пингом им будет одно мучение-)), а если еще и добавить plr 0.5 то они повесятся=)
Примечание: там где команда не заключена в кавычки, она вводится в окне терминала; в кавычках ее следует писать в скрипт
На этом и все.

ukrteam.ru/