Настройки IPFW и NATD, Варианты реализации

Как вести лог блокировок в iptables и ipfw

Linux:

- Перед правилом блокировки нужно вставить "log" правило:
iptables -A FORWARD -p tcp -m tcp -s 192.168.0.0/16 --dport 25 \
-j LOG --log-level debug --log-prefix "outgoing mail"
iptables -A FORWARD -p tcp -m tcp -s 192.168.0.0/16 --dport 25 -j DROP

- Проверить запущены ли в системе klogd и syslogd.

- Настроить /etc/syslog.conf на прием kern.debug логов:
kern.=debug -/var/log/kernel/info

FreeBSD:
Добавить ключ log в ipfw, например:
ipfw add 1000 deny log tcp from any to 192.168.10.10 22 via fxp0
ipfw add 1000 deny log logamount 0 tcp from any to 192.168.10.10 80 via fxp0

Для ведения логов ядро должно быть собрано с IPFIREWALL_VERBOSE или нужно выставить "sysctl -w net.inet.ip.fw.verbose=1".

Далее проверить чтобы в /etc/syslog.conf было упоминание LOG_SECURITY:
security.* /var/log/security

Через параметр logamount передается число записей которые будет записано в лог,
после превышения записи перестанут появляться в логе, до тех пор пока не будет вызвана команда
"ipfw resetlog". Максимальное число сообщений можно также установить
через sysctl net.inet.ip.fw.verbose_limit.
Для отмены лимитирования на число записей, нужно установить атрибут в 0.


Особенности использование ftp из-за фаервола ipfw/natd

Необходимо выпустить пользователей на ftp сайты из локальной сети, но при этом не устанавливая
дополнительного ПО, используя только возможности FreeBSD 4.10.
Этими возможностями, как ни странно, оказались ipfw и natd
вот собственно как все это прописывается.

Исходные данные, FreeBSD 4.10 + настроенный nat правила для ipfw
ipfw -q add 100 divert natd from 192.168.20.0/24 to any 20, 21 out via $oif
ipfw -q add 200 divert natd from any 20, 21 to $iip in via $oif
ipfw -q add 300 allow tcp from any to any established
ipfw -q add 400 allow tcp from any to any setup
где $oif и $iip соответственно внешний интерфейс и внешний IP

теперь запускаем natd
/sbin/natd -m -s -u -punch_fw 500:200 -n xl1

заострю внимание на параметре "-punch_fw" -этот параметр создает в фаерволе "ходы",
добавляя динамические правила. В моем случае эти правила начнутся с номера 500 и будет их добавлено
максимум 200 (понятно чем больше сеть, те больше нужно правил).


Запуск двух natd для редиректа

ipfw:
00100 divert 7777 tcp from any to me dst-port 443
00100 divert 6666 tcp from any to 172.16.0.1 dst-port 443
00100 divert 6666 tcp from 172.16.0.1 443 to me
00100 divert 7777 tcp from 172.16.0.1 443 to not me

natd:
/sbin/natd -redirect_port tcp 172.16.0.1:443 443 -a 172.16.0.2 -p 6666
/sbin/natd -redirect_port tcp 172.16.0.1:443 443 -a 82.179.176.72 -p 7777


IPFW + natd


Эта статья родилась в следствии возникновения постоянных вопросов, связанных с использованием классической схемы работы сервера доступа в Интернет на базе компьютера с двумя сетевыми картами. Можно уже писать ФАК :. Опыт показывает, что посетители странички не всегда читают все статьи, считая свой опыт, в каком то вопросе исчерпывающим. Иногда это происходит из-за нехватки времени - хочется, чтобы все работало и сразу. Постараюсь как то упорядочить то что уже написано и акцентировать внимание на сложных моментах, которые являются ключевыми.

Задание:

* Построить сервер доступа для локальной сети в сеть Интернет на FreeBSD с использованием встроенного сетевого экрана ipfw и демона трансляции адресов natd.
* Принудительно завернуть всех пользователей http и др. на прокси-сервер squid.
* Предоставить отдельным пользователям (IP адресам) выход по превелигированным портам.
* Предоставить отдельному пользователю (IP адресу) прямой выход в Интернет минуя прокси-сервер squid.
* Обеспечить беспрепятственную работу почты, DNS.
* Запретить доступ из Интернета для служб FTP, telnet, SSH, Squid.
* Настроить грамотную фильтрацию протокола ICMP.

Исходные данные (реальные адреса изменены из соображения конфиденциальности):

* IP Адрес сервера во внутреннюю сеть 192.168.10.1
* IP Адрес интерфейса в Интернет (выдается провайдером) 195.195.95.5
* IP Адрес шлюза (выдается провайдером) 195.195.95.100
* IP Адрес DNS1, DNS2 (выдается провайдером) 195.195.95.50, 195.190.90.9
* Доменное имя сервера myd.ru

Необходимые изменения в ядре:

оptions IPFIREWALL
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=10
options IPFIREWALL_FORWARD
options IPDIVERT

Небольшие пояснения, относящиеся к собираемым опциям

* Включает поддержку ipfw на уровне ядра
* Логировать пакеты по правилу ipfw - log
* Ограничение записей попадающих в лог файл
* Включение опции принудительного перенаправления пакетов (для принудительного перенаправления на squid)
* Обработка пакетов внешней программой непосредственно из правил файрвола (в нашем случае демон natd)

Как пересобрать ядро можно почитать "Начальная установка"

Необходимые строки в rc.conf

defaultrouter="195.195.95.100" #Смотри задание
gateway_enable="YES" #Обьявляемся шлюзом
hostname="bsd.myd.ru" #Смотри задание
ifconfig_rl0="inet 195.195.95.5 netmask 255.255.255.0" #Внешний интерфейс
ifconfig_rl1="inet 192.168.10.1 netmask 255.255.255.0" #Внутренний интерфейс
firewall_enable="YES" #Запускаем при старте работу ipfw
firewall_script="/etc/rc.firewall" #Скрипт с правилами ipfw
natd_enable="YES" #Разрешаем использовать natd
natd_interface="rl0" #Оъявляем интерфейс для трансляции внутренних адресов во внешний
natd_flags="-f /etc/natd.conf" #Опции для NAT опишем в отдельном файле

/etc/natd.conf

same_ports yes
use_sockets yes
unregistered_only yes

/etc/rc.firewall

#Обьявляем переменную для облегчения написания правил. Ключик -q подавляет вывод сообщений ipfw на консоль
fwcmd="/sbin/ipfw -q"

# Данные по внешней сети
LanOut="rl0"
IPOut="195.195.95.5"
NetOut="24"
MaskOut="255.255.255.0"

# Данные по локальной сети
LanIn="rl1"
IPIn="192.168.10.1"
NetInIP="192.168.10.0"
NetInMask="24"
MaskIn="255.255.255.0"

# Привелигированные адрес (доступ избранным)
# Смотри примечание
MyIP1="192.168.10.97"
MyIP2="192.168.10.98"
MyIP3="192.168.10.99"

# Первый ДНС адрес наш. Ниже он ни где не используется, но можно указать фильтрацию UDP 53 если вы хотите, чтобы
# доступ к вашей зоне имел только ограниченный круг серверов. Лучший выход из положения использовать для службы DNS
# окружение chroot - jail - sandbox - называйте как хотите :)
dns1="192.168.10.1"
dns2="195.195.95.50"
dns3="195.190.90.9"

# Сбросить все правила которые устанавливались ранее
${fwcmd} -f flush

# Пропускать все пакеты сгенерированные сервером (кажется что lo0 настолько понятно, что не знаешь как еще обьяснить :))
# Без этого вообще ничего работать не будет :)
${fwcmd} add pass all from any to any via lo0

# Stop private networks (RFC1918) from entering the outside interface.
# Как видим из названия - это адреса, которым не место во внешней сети и появление их из Интернета на интерфейс,
# смотрящий в Инет - недопустимо - смело отбрасываем :)
${fwcmd} add deny ip from 192.168.0.0/16 to any in via ${LanOut}
${fwcmd} add deny ip from 172.16.0.0/12 to any in via ${LanOut}
${fwcmd} add deny ip from 10.0.0.0/8 to any in via ${LanOut}

# Принудительно заворачивать всех внутренних пользователей обращающихся к любым адресам по протоколам http,https,ftp
# на squid (смотри примечание 1 и 2)
# Правило fwd должно быть выше правила divert иначе оно не будет работать
${fwcmd} add fwd 127.0.0.1,3128 tcp from ${NetInIP}/${NetInMask} to any http,https,ftp via ${LanIn}

# Отправляем пакеты из внутренней сети наружу и с наружи для внутренней сети на обработку NAT
${fwcmd} add divert natd ip from ${NetInIP}/${NetInMask} to any out via ${LanOut}
${fwcmd} add divert natd ip from any to ${IPOut} in via ${LanOut}

# Это и следующее правила значительно облегчают жизнь файрволу :)
# Пропускаем все соединения с установленным битом RST или ACK
# По другому - пропускаем установленные соединения соединение
${fwcmd} add pass tcp from any to any established
# Разрешаем все пакеты выходящие из внешнего интерфейса с внешнего IP
${fwcmd} add pass ip from ${IPOut} to any out xmit ${LanOut}

# Избранным беспрепятственный доступ (все открывать неразумно)
${fwcmd} add pass tcp from ${MyIP1} to any 20,21,22,23,80,443,4000
${fwcmd} add pass tcp from any 20,21,22,23,80,443,4000 to ${MyIP1}
${fwcmd} add pass tcp from ${MyIP2} to any 20,21,22,23,80,443,4000
${fwcmd} add pass tcp from any 20,21,22,23,80,443,4000 to ${MyIP2}
${fwcmd} add pass tcp from ${MyIP3} to any 20,21,22,23,80,443,4000
${fwcmd} add pass tcp from any 20,21,22,23,80,443,4000 to ${MyIP3}

# Запрещаем - FTP, терминал, Squid - снаружи
${fwcmd} add deny tcp from any to any 20,21,22,23,3128 in via ${LanOut}
# Запрещаем - www, FTP, терминал - изнутри
${fwcmd} add deny tcp from any to any 20,21,22,23,80,443 in via ${LanIn}
${fwcmd} add deny tcp from any to any 8000-8104 in via ${LanIn}

# Разрешаем почту, DNS
${fwcmd} add pass tcp from any to any 25,110 via ${LanOut}
${fwcmd} add pass tcp from any 25,110 to any via ${LanOut}
${fwcmd} add pass udp from any to any 53 via ${LanOut}
${fwcmd} add pass udp from any 53 to any via ${LanOut}

${fwcmd} add pass all from any to any via ${LanIn}

# Доступен сервер www из внешнего мира
${fwcmd} add pass tcp from ${IPOut} 80 to any via ${LanOut}
${fwcmd} add pass tcp from any to ${IPOut} 80 via ${LanOut}

#ICMP
${fwcmd} add allow icmp from any to ${IPOut} in via ${LanOut} icmptype 0,3,4,11,12
${fwcmd} add allow icmp from any to ${NetInIP}/${NetInMask} in via ${LanOut} icmptype 0,3,4,11,12
${fwcmd} add allow icmp from ${IPOut} to any out via ${LanOut} icmptype 3,8,12
${fwcmd} add allow icmp from ${IPOut} to any out via ${LanOut} frag

${fwcmd} add deny log all from any to any via ${LanOut}

${fwcmd} add deny log ip from any to any

ПРИМЕЧАНИЕ:
1) Относится к привелигированным адресам. Исходя из обсуждения на opennet и основываясь на личном опыте могу сказать, что в ipfw (первая версия) нельзя указывать группы адресов в отличии от ipfw2 или ipnat. Всё это к тому, что если вы захотите установить принудительное заворачивание на squid шестым по счету правилом, то у вас возникнет проблема пропуска напрямую более чем одного IP, имеются кое какие мысли как это обойти, но времени проверить нет, по этому в данный момент остановимся на этом утверждении. Итак - чтобы пропустить в интернет миную статистику squid одного из избранных необходимо заменить шестое по счету правило на -
${fwcmd} add fwd 127.0.0.1,3128 tcp from not ${MyIP1} to any http,https,ftp via ${LanIn}
другого пока не знаю :) Просьба не тыкать в меня методами, которые описаны в мане без проверки - пишите рабочий скрипт, проверю помещу сюда :)
Если возникнет непреодолимое желание форвардить группы - компилите ipfw2 с ходу ссылку не скажу - попадется добавлю сюда. В FreeBSD 5.x ipfw2 вкомпилирован.
Ни что не мешает вам выкинуть строчки с форвардингом и прописывать юзерам использовать прокси в браузерах. Я так и сделал :) этот метод хорош когда внутренняя сеть невелика.
2) Для того, чтобы пользователи могли работать в случае принудительного проксирования - В squid.conf должны присутствовать строки:

http_port 3128
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on