FreeBSD

FreeBSD: Настройка ipfw + kernel nat

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

Ядро не пересобирал, на стандартном 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.
#

Оставить комментарий

7 комментариев

  • Спасибо. Большое.
    Единственная правка, у меня строчки типа
    ${ipfw} add nat 1 all from table(0) to any out via ${LanOut}
    не прокатили. Заключил table(0) в кавычки «, и все пошло

  • выяснил, что к kernel panic приводит правило
    # block some DOS attacks.
    ${ipfw} add deny log tcp from any to any tcpoptions !mss tcpflags syn,!ack

    без него всё работает отлично! спасибо за правила

    p.s. небольшое уточнение, файрвол корректно всё фильтрует согласно правилам, но только при переменной sysctl net.inet.ip.fw.one_pass=0, у вас это можно не заметить по статье. Так же по некоторым allow правилам трафика совсем нет, но это уже мелочи

  • У Вас сервер не уходит в kernel panic при таком файрволе? настроил по статье с учетом своих потребностей, сервер стал уходить в kernel panic, причём виноваты именно правила, всё уже проверил, kernel panic может быть пару раз в день

    • Kernel panic периодически появлялся при работающем на сервере transmission когда на закачку стояло много загрузок. Сейчас он отключён и вылетов нет. Возможно в правилах есть недочёт.

      • выяснил, что к kernel panic приводит правило
        # block some DOS attacks.
        ${ipfw} add deny log tcp from any to any tcpoptions !mss tcpflags syn,!ack

        без него всё работает отлично! спасибо за правила

        p.s. небольшое уточнение, файрвол корректно всё фильтрует согласно правилам, но только при переменной sysctl net.inet.ip.fw.one_pass=0, у вас это можно не заметить по статье. Так же по некоторым allow правилам трафика совсем нет, но это уже мелочи