IPFW — примеры правил

FREEBSD: НАСТРОЙКА IPFW + KERNEL NAT

ipfw: порядок прохождения пакетов, сложные случаи — http://nuclight.livejournal.com/124348.html

Хорошая статья по ipfw http://bezopasnik.org/unix/dok/FreeBSD/dok/653.htm

 Подбирал конфиг под себя, так что его можно использовать в целях ознакомления.

Ядро не пересобирал, на стандартном GENERIC

В /etc/rc.conf добавляем строчки:

# Включаем Firewall
firewall_enable="YES"
# Указываем файл с правилами
firewall_script="/etc/rc.firewall"
# Включаем лог
firewall_logging="YES"
# Включаем nat
firewall_nat_enable="YES"
# Если нужно ограничить скорости интернета у пользователей
#dummynet_enable="YES"

Добавляем в /etc/sysctl.conf

net.inet.ip.fw.verbose=1
net.inet.ip.fw.verbose_limit=100
net.inet.ip.fw.one_pass=0

Редактируем rc.firewall до такого вида:

#!/bin/sh

# Задаём строку для обращения к ipfw.
ipfw="/sbin/ipfw -q"

# Сетевая карта в которую вставлен провод от провайдера.
LanOut="vr0"
IpOut="1.2.3.4"

# Сетевая карта "смотрящая" во внутреннюю сеть.
LanIn="nfe0"
IpIn="192.168.20.254"

# IP адрес машины во внутренней сети.
HOME="192.168.20.1"
HOME2="192.168.20.2"

# Внутренняя подсеть.
NetIn="192.168.20.0"

# Сетевая маска внутренней подсети.
NetMask="24"

# Если до выполнения этого сценария в фаерволе
# были какие-то правила - сбрасываем их.
${ipfw} -f flush

# Создаём таблицу с пользователями, которым разрешен доступ в Интернет.
#  Если в таблице 0 были какие-то значения - сбрасываем их.
${ipfw} -f table 0 flush

# В эту таблицу будем добавлять тех, кому будет разрешен доступ в интернет.
${ipfw} table 0 add 192.168.20.1
${ipfw} table 0 add 192.168.20.2
${ipfw} table 0 add 192.168.20.3
${ipfw} table 0 add 192.168.20.4
${ipfw} table 0 add 192.168.20.5
# Если нужно больше адресов - добавляем больше.

# Создаём таблицы Fail2ban.
sshd_ban_table="table(50)"
proftpd_ban_table="table(51)"
exim_ban_table="table(52)"
wordpress_ban_table="table(53)"

# Сбрасываем все ограничители.
${ipfw} -f pipe flush

# Сбрасываем все очереди.
${ipfw} -f queue flush

# Далее простой firewall.

# Fail2ban.
${ipfw} add 10 deny tcp from ${proftpd_ban_table} to me 21 via ${LanOut}
${ipfw} add 11 deny tcp from ${sshd_ban_table} to me 22 via ${LanOut}
${ipfw} add 12 deny tcp from ${exim_ban_table} to me 25 via ${LanOut}
${ipfw} add 13 deny tcp from ${wordpress_ban_table} to me 80 via ${LanOut}

${ipfw} add 2000 check-state

${ipfw} add allow ip from any to any via lo0
${ipfw} add deny ip from any to 127.0.0.1/8
${ipfw} add deny ip from 127.0.0.1/8 to any

# block unuseful traffic.
${ipfw} add deny ip from any to 10.0.0.0/8 in via ${LanOut}
${ipfw} add deny ip from any to 172.10.0.0/12 in via ${LanOut}
${ipfw} add deny ip from any to 192.168.0.0/16 in via ${LanOut}
${ipfw} add deny ip from any to 0.0.0.0/8 in via ${LanOut}
${ipfw} add deny ip from any to 169.254.0.0/16 in via ${LanOut}
${ipfw} add deny ip from any to 240.0.0.0/4 in via ${LanOut}

# Запрещаем фрагментированные ICMP.
${ipfw} add deny icmp from any to any frag

# Запрещаем широковещательные ICMP на интерфейсе подключенном к Интернет.
${ipfw} add deny icmp from any to 255.255.255.255 in via ${LanOut}
${ipfw} add deny icmp from any to 255.255.255.255 out via ${LanOut}

# Конфигурируем проброс портов через IPFW NAT.
${ipfw} nat 1 config if ${LanOut} log reset same_ports unreg_only 
 redirect_port tcp ${HOME}:51414 51414 
 redirect_port tcp ${HOME2}:51415 51415

# Теперь определяем какие пакеты будут проходит NAT.
${ipfw} add nat 1 all from table(0) to any out via ${LanOut}
${ipfw} add nat 1 all from any to ${IpOut} in via ${LanOut}


# Запрещаем пакеты с адресами частных сетей на интерфейсе подключенном к Интернет.
${ipfw} add deny ip from 10.0.0.0/8 to any out via ${LanOut}
${ipfw} add deny ip from 172.16.0.0/12 to any out via ${LanOut}
${ipfw} add deny ip from 192.168.0.0/16 to any out via ${LanOut}
${ipfw} add deny ip from 0.0.0.0/8 to any out via ${LanOut}

# Так же запрещаем автоконфиг. частной сети.
${ipfw} add deny ip from 169.254.0.0/16 to any out via ${LanOut}

# Запрещаем мультикаст-рассылки на интерфейсе подключенном к Интернет.
${ipfw} add deny ip from 224.0.0.0/4 to any out via ${LanOut}

# Разрешаем самому маршрутизатору ходить в Интернет.
${ipfw} add allow ip from ${IpOut} to any out via ${LanOut}

# Разрешаем все установленные соединения.
${ipfw} add allow tcp from any to any established

# UDP трафик от сервера.
${ipfw} add allow udp from ${IpOut} to any out via ${LanOut}

# UDP трафик к серверу на порт 51413 (Transmission).
${ipfw} add allow udp from any to ${IpOut} 51413 in via ${LanOut}

# Доступ к DNS серверу.
${ipfw} add allow udp from any to ${IpOut} 53 in via ${LanOut}
${ipfw} add allow udp from ${IpOut} 53 to any out via ${LanOut}
${ipfw} add allow udp from any 53 to ${IpOut} in via ${LanOut}
${ipfw} add allow udp from ${IpOut} to any 53 out via ${LanOut}

# Разрешаем серверу собирать статистику с устройств в Интернете "Cacti".
${ipfw} add allow ip from any 161 to ${IpOut} in via ${LanOut}

# Разрешаем входящие TCP и UDP на те IP, которые имеют доступ к Интернет.
${ipfw} add allow udp from any to table(0) in via ${LanOut}
${ipfw} add allow tcp from any to table(0) in via ${LanOut}

# Разрешаем ICMP запросы типов 0,8,11 .
${ipfw} add allow icmp from any to any icmptypes 0,8,11

# Разрешаем FTP с ограничением в 10 .
${ipfw} add allow tcp from any to ${IpOut} 20,21 in via ${LanOut} setup limit src-addr 10

# Разрешаем входящие соединения на порт SSH с ограничением в 2 .
${ipfw} add allow tcp from any to ${IpOut} 22 in via ${LanOut} setup limit src-addr 2

# Открываем 25 порт, есть почтовый сервер.
${ipfw} add allow tcp from any to ${IpOut} 25 in via ${LanOut} setup

# Доступ в DNS серверу.
${ipfw} add allow tcp from any to ${IpOut} 53 in via ${LanOut} setup

# Доступ к 80,443 порту, на сервере крутится сайт.
${ipfw} add allow tcp from any to ${IpOut} 80 in via ${LanOut} setup
${ipfw} add allow tcp from any to ${IpOut} 443 in via ${LanOut} setup

# Iperf для теста скорости.
${ipfw} add allow tcp from any to ${IpOut} 5001 in via ${LanOut} setup

# Выпускаем icecast2 в Интернет.
${ipfw} add allow tcp from any to ${IpOut} 8000 in via ${LanOut} setup

# Доступ с Интернета к web интерфейсу Transmission.
${ipfw} add allow tcp from any to ${IpOut} 9091 in via ${LanOut} setup

# Разрешаем любые ICMP запросы на внутреннем сетевом интерфейсе.
${ipfw} add allow icmp from any to any via ${LanIn}

# Разрешаем трафик внутренней сети на внутреннем интерфейсе.
${ipfw} add allow ip from ${NetIn}/${NetMask} to any via ${LanIn}
${ipfw} add allow ip from any to ${NetIn}/${NetMask} via ${LanIn}

# Запрещаем всё и пишим в лог.
${ipfw} add 65534 deny log all from any to any

Fail2ban блокирует тех, кто лезет на 21, 22, 25, 80 порты.

Перезагружаем firewall

# /etc/rc.d/ipfw restart
net.inet.ip.fw.enable: 1 -> 0
net.inet6.ip6.fw.enable: 1 -> 0
Firewall rules loaded.
Firewall logging enabled.
#

------
Еще один пример:

IPFW

# Разрешаем весь траффик по внутреннему интерфейсу (петле)
# Вообще я во многих местах читал что без него может ничё не заработать вообще
# и прочие страшилки. Работает - почта, апач, .... А вот squid - не работает :)
# так что без него и правда - никуда.
${FwCMD} add allow ip from any to any via lo0
${FwCMD} add deny ip from any to 127.0.0.0/8
${FwCMD} add deny ip from 127.0.0.0/8 to any

# режем частные сети на внешнем интерфейсе - по легенде он у нас
# смотрит в интернет, а значит пакетам этим браться неоткуда на нём.
# рубим частные сeти
${FwCMD} add deny ip from any to 10.0.0.0/8 in via ${LanOut}
${FwCMD} add deny ip from any to 172.16.0.0/12 in via ${LanOut}
${FwCMD} add deny ip from any to 192.168.0.0/16 in via ${LanOut}
${FwCMD} add deny ip from any to 0.0.0.0/8 in via ${LanOut}

# рубим автоконфигуреную частную сеть
${FwCMD} add deny ip from any to 169.254.0.0/16 in via ${LanOut}

# рубаем мультикастовые рассылки
${FwCMD} add deny ip from any to 240.0.0.0/4 in via ${LanOut}

# рубим фрагментированные icmp
${FwCMD} add deny icmp from any to any frag

# рубим широковещательные icmp на внешнем интерфейсе
${FwCMD} add deny icmp from any to 255.255.255.255 in via ${LanOut}
${FwCMD} add deny icmp from any to 255.255.255.255 out via ${LanOut}

# рубим траффик к частным сетям через внешний интерфейс
# заметтьте - эти правила отличаются от тех что были выше!
${FwCMD} add deny ip from 10.0.0.0/8 to any out via ${LanOut}
${FwCMD} add deny ip from 172.16.0.0/12 to any out via ${LanOut}
${FwCMD} add deny ip from 192.168.0.0/16 to any out via ${LanOut}
${FwCMD} add deny ip from 0.0.0.0/8 to any out via ${LanOut}

# рубим автоконфигуреную частную сеть
${FwCMD} add deny ip from 169.254.0.0/16 to any out via ${LanOut}

# рубаем мультикастовые рассылки
${FwCMD} add deny ip from 224.0.0.0/4 to any out via ${LanOut}

# рубаем мультикастовые рассылки
${FwCMD} add deny ip from 240.0.0.0/4 to any out via ${LanOut}

# port-scan protect
${FwCMD} add deny log tcp from any to me in via ${LanOut} tcpflags fin, syn, rst, psh, ack, urg
${FwCMD} add deny log tcp from any to me in via ${LanOut} tcpflags !fin, !syn, !rst, !psh, !ack, !urg
${FwCMD} add deny log tcp from any to me not established tcpflags fin

# Запрещаем пакеты с не кор рек т ны ми TCP-флагами.
# NULL-пакеты = второй тест nmap
${FwCMD} add deny log tcp from any to me in via ${LanOut} tcpflags !syn,!ack,!rst

# XMAS-пакеты = третий тест nmap
${FwCMD} add deny log tcp from any to me in via ${LanOut} tcpflags syn,fin,urg,psh,!ack
${FwCMD} add deny log tcp from any to me in via ${LanOut} tcpflags syn,fin,!ack

# Седьмой тест nmap
${FwCMD} add deny log tcp from any to me in via ${LanOut} tcpflags fin,urg,psh,!ack
${FwCMD} add deny log tcp from any to me in via ${LanOut} tcpflags fin,!ack
${FwCMD} add deny log tcp from any to me in via ${LanOut} tcpflags urg,!ack
${FwCMD} add deny log tcp from any to me in via ${LanOut} tcpflags psh,!ack

# Отбрасываем пакеты с нестандартными IP-опциями
${FwCMD} add deny log all from any to me in via ${LanOut} ipoptions ssrr
${FwCMD} add deny log all from any to me in via ${LanOut} ipoptions lsrr
${FwCMD} add deny log all from any to me in via ${LanOut} ipoptions rr
# Запрещаем пакеты с Timestampf
${FwCMD} add deny log all from any to any in via ${LanOut} ipoptions ts

# allow trafic only to that int, where it arrive
${FwCMD} add deny log ip from any to any not verrevpath in

#Защита от icmp флуда
${FwCMD} add 500 deny icmp from any to any in icmptype 5,9,13,14,15,16,17

# Разрешаем только корректные пакеты на порты публичных сервисов (на примере 25 порта)
${FwCMD} add pass tcp from any to me 25 in via ${LanOut} tcpflags syn,!ack,!psh,!fin,!urg,!rst
${FwCMD} add pass tcp from any to me 25 in via ${LanOut} tcpflags ack,!syn,!psh,!fin,!urg,!rst
${FwCMD} add pass tcp from any to me 25 in via ${LanOut} tcpflags ack,psh,!syn,!fin,!urg,!rst
${FwCMD} add pass tcp from any to me 25 in via ${LanOut} tcpflags ack,fin,!syn,!psh,!urg,!rst

Примечание.

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

------

https://alexnettm.org.ua/freebsd/freebsd-nastrojka-ipfw-kernel-nat.html

http://unix.uz/articles/secure/90-primery-nastrojki-ipfw.html

https://anteh.ru/notes/freebsd/notes_NATIPFWMI.html
FreeBSD QoS. http://nag.ru/articles/reviews/15524/freebsd-qos.html
http://www.lissyara.su/articles/freebsd/tuning/ipfw/
https://www.opennet.ru/docs/RUS/ipfw/ipfw.html
http://www.macenterprise.org/articles/advancedipfwfirewallconfiguration

ipfw + nat + redirect ports

Посмотреть nat

ipfw nat show config
ipfw nat 1 config ip 172.16.0.0 deny_in same_ports reset redirect_port tcp 192.168.0.2:37979 37979

проброс нескольких портов

ipfw nat 1 config if ng0 same_ports \
redirect_port 192.168.1.3:1234 1234 \
redirect_port 192.168.1.4:5678 5678

https://ctopmbi4.wordpress.com/category/freebsd/ipfw/

nat one_pass

 Значение /etc/sysctl.conf net.inet.ip.fw.one_pass=0

После проверки nat -ом. если в нате стоит deny_in и записей  в таблице nat нет. то пакет пойдетдальше по правилами фаера.

Если значение стоит 1.sysctl.conf net.inet.ip.fw.one_pass=1  то пакет будут принят создаться запись в нате и пакет дальше по правилам фаера не пойдет.

ПРАВИЛА

Перечитать правила фаера из скрипта например без потери соединения.

/bin/sh /etc/rc.firewall &

Для просмотра динамических правил  опция -d в ipfw

ipfw использует два вида набора правил: статические и динамические. Статические являются постоянными. Пример:

ipfw add 100 allow tcp from any to me 80
ipfw add 200 allow tcp from me 80 to any

посмотреть ipfw show

00020 11936 1263070 allow ip from any to any via lo0

номер правила, кол-во срабатываний, кол-во байт прошедших через правило и самое правило.

Динамические правила создаются условиями keep-state и limit в правилах, причём динамические правила имеют двухстороннюю направленность. ПРИМЕР:

Если мы перепишем предыдущие два правила в «динамическом ключе«, то получим одноправило:

ipfw add 100 allow tcp from any to me 80 keep-state

Т.о. пакет, приходящий на наш сервер на 80 порт создаёт динамическое правило, которое мы увидим при выводе ipfw -d show:

00100    55 555432(144s) STATE tcp x.x.x.x 56789<-> y.y.y.y 80

Здесь, 00100 — номер правила, 55 — количество пакетов, прошедших через это правило, 555432— количество байт, 144s — оставшееся время, после которого (при отсутствии трафика) правило будет удалено, остальное понятно из контекста.

Соответственно, если имеется правило

00050  0  0  check-state

то оно и будет проверять, существует ли правило в динамической таблице, после чего пакет будет обработан динамическим правилом с обновлением счетчиков в нём.

divert

Если check-state стоит до правил с divert’ом, то пакеты, естественно, в этот divert не попадают. Как следствие, динамические правила просто «устаревают«, не дождавшись обновления и «не пропускают» пакеты потому, что через divert они не прошли, а следовательно имеют «неверные» адреса в заголовке пакета.

Минимальная конфигурация для создания ограничение скорости для пользователя

задаем правило под номером 100

ipfw add 100 pipe 1 ip from any to 192.168.0.119 out via em0

Задаем непосредственно сам pipe под номером 1

ipfw pipe 1 config bw 2Mbit/s

тем самым мы ограничиваем скорость от всех до ип адреса 192.168.0.119  ВХОДЯЩИЙ  с интерфеса em0

Посмотреть правила PIPE можно коммандой

ipfw pipe show

либо по  номеру пайпа: ipfw pipe 1 show

очереди queue

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

есть основная мысль, которая описывает разделение пакетов в pipe. 
Если всем пользователям необходимо равномерно распределять поток, то создавать
вручную количество очередей соответствующее количеству пользователей не
нужно. Мы создаем всего одну очередь
ipfw queue 1 config pipe 1 weight 50 queue 20 mask dst-addr 0xffffffff
параметр mask, в котором указываем что для каждого
отдельного destination адреса будет создаваться своя очередь с такими же
параметрами, как у этой.
 Отметим, что ограничение без потерь возможно только в отношении исходящего
 трафика. Стек протоколов TCP/IP не предусматривает возможности заставить
 удаленную сторону слать пакеты медленнее