Ноябрь.2007

PF или пакетный фильтр

    pf - может обеспечить достаточно глухую защиту, по крайней мере Волгу Телеком отшвыривал запросто. На тему есть прекрасноя лекция в русском переводе где описано чего и как. Я всего дам замечания из своего опыта.
    Пакетный фильтр и примыкающий к нему лог демон доступен как модуль, но можно и скомпилировать в ядро. В rc.conf не должно быть упоминания о nat демоне и ipfirewall. Должны быть другие строки:

    pf_enable="YES"
    pf_rules="/etc/pf.conf"
    pf_flags=""
    pflog_enable="YES"
    pflog_logfile="/var/log/pflog"
    pflog_flags=""

С флагами не всё понятно читаем man, но вот работающий сразу pf.conf можно взять из приложенных примеров в /usr/local/share/examples. NAT демона в процессах вы не увидите, здесь своя система трансляции адресов. В связи с этим при подключении к iNET через pppd следует перезапускать правила pf командой:

    pfctl -f /etc/pf.conf

либо руками, либо добавить в скрипт вызова pppd. Статистика прекрасно видна через клманду

pfctl -s info.



    Литература с примерами можно нарыть в интернете более чем. От себя могу добавить, что для изучения понятней pf нежели ipfw.





Добавления разных периодов, грубо 2009 год

Классический пример PF конфигурационного файла с фильтрацией входящего траффика и пропуском всего траффика из локальной сети:

# macros //переменные, упрощающие жизнь
ext_if="fxp0" // внешний интерфейс - ppp0 при модемах
int_if="xl0" // внутренний интерфейс
tcp_services="{ 22, 113 }"//внимательно посмотреть какие порты открыть
icmp_types="echoreq"// возможность пинговать хост
table <clients> persist file /etc/clients// определение таблицы с путём файла таблицы
comp3="192.168.0.3"// запись машины WEB сервера внутри локальной сети

# options
set block-policy return //определение политики PF как возврат пакетов отправителю
set loginterface $ext_if //включение статистики на входящий траффик
set skip on lo //отключение правил фильтрации на loop'e

# scrub
scrub in // оптимизация пакетов

# network address translation
nat on $ext_if from !($ext_if) to any -> ($ext_if) // переадресация для всех подсетей !!!
nat on $ext_if from $int_if to any -> ($ext_if) // переадресация только свой подсети!!
nat-anchor "ftp-proxy/*" // подвязка переадресации FTP протокола

# redirection
rdr-anchor "ftp-proxy/*"
rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021
rdr on $ext_if proto tcp from any to any port 80 -> $comp3 // пропуск трафиика напрямую по 80 порту к конкретному компьютеру

# filter rules
block in // блок на несанкционированные входяшие пакеты включая собственные подсети
pass out keep state // запоминать информацию (заголовки) исходящих пакетов
anchor "ftp-proxy/*" // подвязка FTP наружу
antispoof quick for { lo $int_if } // блокирование пакетов c поддельными заголовками
pass in on $ext_if inet proto tcp from any to ($ext_if) \
    port $tcp_services flags S/SA keep state // открываем порты разрешённых служб в самом PF
pass in on $ext_if inet proto tcp from any to $comp3 port 80 \
     flags S/SA synproxy state // пропуск пакетов напрямую для WEB сервера
pass in inet proto icmp all icmp-type $icmp_types keep state // разрешение на пингование
pass in quick on $int_if // разрешение траффика in/out локальной сети без правил

// TCP, UDP, ICMP траффик разрешён наружу благодаря записи в начале правил "pass out keep state" с сохранением информации

     Замечания по протоколу FTP. Не совсем чётко прописывается в объяснялках этот вопрос. Прекрасный ответ я нашёл в одном из форумах и суть его изложена напрямую ниже.

>Задача - разрешить из локалки доступ к любым ftp серверам через freebsd
>сервер с pf.
>как я понимаю, активный ftp отпадает сразу - на файрволле не сильно
>хочу открывать разрешения входящих соединений.
>


на 7.0+ есть ftp-proxy
в rc.conf
ftpproxy_enable="YES"
ftpproxy_flags="-v -D 7"

в pf.conf
rdr-anchor "ftp-proxy/*"
rdr on $int_if proto tcp from <ftpusers> to !(self) port ftp -> 127.0.0.1 port 8021
anchor "ftp-proxy/*"

ftp-proxy сам будет создавать правила для входящих.



для 6.0+ чуть больше правил,
в pf.conf
rdr on $int_if proto tcp from <ftpusers> to !(self) port ftp -> 127.0.0.1 port 8021
pass in quick on $ext_if inet proto tcp from port ftp-data to $ext_if user proxy flags S/SA keep state

и в inetd.conf
ftp-proxy stream tcp nowait root /usr/libexec/ftp-proxy ftp-proxy

и в rc.conf
inetd_enable="YES"



<ftpusers>- список IP кому разрешено ходить по ftp
в обоих случаях !(self) - на случай ftp на самом шлюзе

(работа в пассивном режиме полностью обеспечивается proxy-server'ом, то есть выделение пула адресов лежит на совести последнего)

     N.B. Соответственно в секции #macros надо прописать строчку :

table <ftpusers> persist file "/etc/ftpusers"

и создать как таковой сам файл ftpusers с перечнем адресов клиентов

     Работу ftp-proxy очень хорошо видно на примере когда идёт сеанс связи через и не. Попытка подключиться по протоколу FTP напрямую скажем через MC и т.д. будет неудачной вследствии невозможности перейти в пассивный режим обмена данными. То есть все порты выше 1024 брыкнуты.



pollex@yandex.ru
Hosted by uCoz