IPFIREWALL (IPFW) — представляет собой межсетевой экран, написанный и поддерживаемый добровольными участниками проекта FreeBSD. Он использует stateless правила, т.е. правила без учета состояния, и наследование техники кодирования правил для получения того, что называется простой логикой с сохранением состояния (stateful).
Честно говоря по началу мне он не понравился, но разобравшись с ним, я понял, что он не хуже чем iptables. Хорошо документирован, так что не буду писать много теории, а сразу переходим к практике.) Но более подробно об IPFW можно прочитать здесь.
Собираем наше ядро, включив туда firewall, natd, bridge (мост — нужен для распределения нагрузки, и так как у нас будет wifi, но об этом в другой статье), Dymmanet (ограничение пропускной способности инета).
Проверим нашу архитектуру командой:
uname -a
Вывод
FreeBSD gate 11.1-RELEASE FreeBSD 11.1-RELEASE #1: Mon Sep 25 20:30:12 MSK 2017 root@gate:/usr/obj/usr/src/sys/GENERIC amd64
У меня 64 разрядная ОС, значит мой каталог такой — /sys/amd64/conf/. У кого x86, каталог i386 (cd /sys/i386/conf/ )
cd /sys/amd64/conf/
Копируем конфиг нашего ядра
cp GENERIC MYGENERIC
Редактируем. Добавляем необходимые опции.
nano MYGENERIC
options IPFIREWALL
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=10
options IPDIVERT
options DUMMYNET
options IPFIREWALL_NAT
options LIBALIAS
options ROUTETABLES=2
options DUMMYNET
options HZ="1000"
device if_bridge
Компилируем новое ядро.
!Процесс занимает длительное время
cd /usr/src
make buildkernel KERNCONF=MYGENERIC
Устанавливаем ядро
make installkernel KERNCONF=MYGENERIC
Редактируем rc.conf
nano /etc/rc.conf
#firewall
firewall_enable="YES"
firewall_type="open"
Если мы не добавим эту строчку firewall_type=»open», то получим автономный сервер без сети.
Перезагружаем сервер
reboot
Вывод системы (uname -a)
FreeBSD gate 11.1-RELEASE FreeBSD 11.1-RELEASE #1: Mon Sep 25 21:50:54 MSK 2017 root@gate:/usr/obj/usr/src/sys/MYGENERIC amd64
Все готово. Идем дальше.
Поднимаем кеширующий DNS (отдельная статья)
Правила для ipfw
nano /etc/sysctl.conf
net.inet.ip.fw.one_pass=0
Создаем конфиг нашего файрвола
touch /etc/ipfw.firewall
nano /etc/ipfw.firewall
ipfw -q -f flush
cmd="ipfw -q add"
cmt="ipfw"
skip="skipto 900"
ks="keep-state"
LanOut="re0"
LanIn="bridge0"
LanIn2="fxp0"
home="10.1.1.0/24"
home2="192.168.40.0/24"
home3="192.168.50.0/24"
$cmd 006 allow all from any to any via $LanIn
$cmd 007 allow all from any to any via $LanIn2
$cmd 010 allow all from any to any via lo0
$cmd 014 nat 1 ip from any to any in via $LanOut
$cmd 015 check-state
#############################out#########################
$cmd 020 $skip udp from any to any 53 out via $LanOut $ks
$cmd 021 $skip tcp from any to any 53 out via $LanOut $ks
$cmd 022 $skip udp from any to any 67 out via $LanOut $ks
$cmd 023 $skip udp from any to any 68 in via $LanOut $ks
#access
$cmd 024 $skip all from 10.1.1.2 to any via $LanOut $ks
$cmd 025 $skip all from 10.1.1.3 to any via $LanOut $ks
#http(s)
$cmd 027 $skip tcp from any to any 80,443 out via $LanOut $ks
$cmd 028 $skip tcp from any to any 4343 out via $LanOut setup $ks
#client icmp
$cmd 100 $skip icmp from me to any out via $LanOut $ks
#ntp
$cmd 199 $skip udp from any to any 123 out via $LanOut $ks
####################IN####################################
$cmd 200 deny all from 192.168.0.0/16 to any in via $LanOut #RFC 1918 private IP
$cmd 201 deny all from 172.16.0.0/12 to any in via $LanOut #RFC 1918 private IP
$cmd 202 deny all from 10.0.0.0/8 to any in via $LanOut #RFC 1918 private IP
$cmd 203 deny all from 127.0.0.0/8 to any in via $LanOut #loopback
$cmd 204 deny all from 0.0.0.0/8 to any in via $LanOut #loopback
$cmd 205 deny all from 169.254.0.0/16 to any in via $LanOut #DHCP auto-config
$cmd 206 deny all from 192.0.2.0/24 to any in via $LanOut #reserved for docs
$cmd 207 deny all from 204.152.64.0/23 to any in via $LanOut #Sun cluster
$cmd 208 deny all from 224.0.0.0/3 to any in via $LanOut #Class D & E multicast
#nat
$cmt nat 1 config log if $LanOut reset same_ports unreg_only \
redirect_port tcp 10.1.1.2:3389 3389 \
redirect_port tcp 10.1.1.2:4001 4001 \
redirect_port tcp 10.1.1.3:22 22 \
redirect_port tcp 10.1.1.3:80 80
$cmd 300 allow tcp from any to any established via $LanOut
#ssh
$cmd 301 allow tcp from any to me 22 in via $LanOut setup limit src-addr 2
#UDP
$cmd 303 allow udp from any to 10.255.255.255 1947,137-138 in via $LanOut
$cmd 304 allow all from any to 224.0.0.1 in via $LanOut
#web nat
$cmd 305 allow tcp from any to 10.1.1.2 3389 in via $LanOut
$cmd 308 allow tcp from any to 10.1.1.3 4343 in via $LanOut
$cmd 310 allow all from any to 10.1.1.2 4001 in via $LanOut
$cmd 311 allow tcp from any to 10.1.1.3 80 in via $LanOut
#ntp
$cmd 320 allow udp from any to any 123 in via $LanOut
$cmd 600 deny log all from any to any out via $LanOut
$cmd 601 deny log all from any to any in via $LanOut
$cmd 900 nat 1 ip from any to any out via $LanOut
$cmd 901 allow ip from any to any
$cmd 65534 deny log all from any to any
Делаем скрипт исполняемым
chmod +x /etc/ipfw.firewall
Добавляем опции в rc.conf. Вместо firewall_type, ставим firewall_script=путь до Ваше набора правил
nano /etc/rc.conf
#firewall
firewall_enable="YES"
firewall_script="/etc/ipfw.firewall"
firewall_logging="YES" (log)
gateway_enable="YES" шлюз (port.forwarding)
firewall_nat_enable="YES" - для редиректа портов
firewall_nat_interface="em0" - интерфейс смотрящий в инет
Перезагружаем компьютер
reboot
Чтобы применять правила, не обязательно каждый раз перезагружать компьютер, а можно воспользоваться двумя способами, мне больше нравиться второй
- sh /etc/ipfw.firewall
- service ipfw restart
!Не много дополнительной информации!
Чтобы отследить IP или порты приходящие на наш шлюз или идущие из локальной сети, можно воспользоваться утилитой iftop. (расскажу о ней более подробно в другой статье)
Если что-то не проходит, то смотрим логи ipfw (/var/log/security)
Всем удачи!