Показаны сообщения с ярлыком pf. Показать все сообщения
Показаны сообщения с ярлыком pf. Показать все сообщения

четверг, октября 29, 2009

SIP и NAT

Читаем о том как подружить SIP и NAT в переведенной мною статье SIP через NAT

пятница, августа 14, 2009

Борьба с перебором паролей на FTP сервере при помощи пакетного фильтра PF

Источник http://www.opennet.ru/tips/info/2140.shtml

Борьба с перебором паролей на FTP сервере при помощи пакетного фильтра PF

Для предотвращения bruteforce-атак по подбору паролей во FreeBSD или OpenBSD можно использовать
возможность пакетного фильтра PF по лимитированию числа соединений за единицу времени в сочетании с блокировкой по таблицам.

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

# Подключаем ранее составленный список заблокированных за излишнее число коннектов IP
table <ftp-attacks> persist file "/etc/pf.ftp.block.list"

# Блокируем все входящие соединения с IP, которые присутствуют в черном списке
block in quick on $ext_if from <ftp-attacks>

# Выявляем IP с которых было более 5 обращений за 40 секунд
# и добавляем этот IP в ранее созданную таблицу блокировки
pass in quick on $ext_if inet proto tcp from any to ($ext_if) port 21 keep state (max-src-conn-rate 5/40, overload flush global)

Перечитываем конфигурацию PF:
/etc/rc.d/pf reload
или
/sbin/pfctl -f /etc/pf.conf

Далее, чтобы сохранить созданную таблицу блокировки между перезагрузками, необходимо добавить
в /etc/rc.shutdown код для сброса в файл состояния таблицы перед завершением работы:
/sbin/pfctl -t ftp-attacks -T show > /etc/pf.ftp.block.list

Для удаления определенного IP (например, 192.168.1.1) из таблицы:
/sbin/pfctl -t ftp-attacks -T delete 192.168.1.1

Для добавления IP или подсети вручную:
/sbin/pfctl -t ftp-attacks -T add 192.168.1.1
/sbin/pfctl -t ftp-attacks -T add 192.168.1.0/24

Для полной очистки таблицы
/sbin/pfctl -t ftp-attacks -T flush

Для загрузки таблицы из файла:
/sbin/pfctl -t ftp-attacks -T replace -f /etc/pf.ftp.block.list

Для поиска IP в таблице
/sbin/pfctl -t ftp-attacks -T test 192.168.1.1

Для вывода более подробной статистики по каждому из IP в таблице:
/sbin/pfctl -t ftp-attacks -T show -v

Для очистки счетчиков срабатываний:
/sbin/pfctl -t ftp-attacks -T zero

среда, февраля 13, 2008

pf, freebsd 6.2 и 3 внешних канала.

В данной заметке привожу рабочий конфигурационный файл маршрутизатора с тремя внешними каналами, трансляцией адресов, переадресацией сервисов во внутреннюю сеть. Работает симметричная маршрутизация для правильного возврата пакетов в канал, с которого соединение было инициировано. Внутри локальной сети терминальный сервер 192.168.1.3. На самом сервере доступно из вне ftp ssh и почта. На втором и третьем внешнем интерфейсе на 5000 порту работает сервер vtun. У локальной сети 192.168.1.0/24. У туннельных сетей 192.168.3.0/24 и 192.168.4.0/24. Из локалки наружу разрешено 110, 3389, 53, остальное через прокси сервер squid.

#/etc/pf.conf
# Внешний интерфейс и шлюз для канала A (WAN_1).#
ext_if_a = "em0"
ext_gw_a = "x.x.x.x"
# Внешний интерфейс и шлюз для канала B (WAN_2).#
ext_if_b = "em2"
ext_gw_b = "x.x.x.x"
# Внешний интерфейс и шлюз для канала C (WAN_3).#
ext_if_c = "fxp0"
ext_gw_c = "x.x.x.x"
# Внутренний интерфейс (LAN).#
int_if = "em1"
# Обслуживаемые TCP и UDP сервисы.
tcp_svc = "22 25 21 35000:35100"
# TCP сервисы, обслуживаемые сервером из внутренней сети, и адрес сервера.
# 3389
tcp_svc_lan_terminal = "3389"
tcp_rdr_lan_terminal = "192.168.1.3"
# Не фильтровать трафик на lo интерфейсах.#
set skip on lo0
# Нормализовать весь входящий трафик.#
scrub in
# Включить трансляцию адресов на внешних интерфейсах.#
nat on $ext_if_a inet from !(self) -> $ext_if_a:0
nat on $ext_if_b inet from !(self) -> $ext_if_b:0
nat on $ext_if_c inet from !(self) -> $ext_if_c:0
# Переадресовать TCP сессии для сервисов, обслуживаемых локальным сервером.
# Правила rdr здесь НЕ должны содержать слова pass.
rdr on $ext_if_a inet proto tcp to $ext_if_a:0 port { $tcp_svc_lan_terminal\
} tag EXT_IF_A -> $tcp_rdr_lan_terminal
rdr on $ext_if_b inet proto tcp to $ext_if_b:0 port { $tcp_svc_lan_terminal\
} tag EXT_IF_B -> $tcp_rdr_lan_terminal
rdr on $ext_if_c inet proto tcp to $ext_if_c:0 port { $tcp_svc_lan_terminal\
} tag EXT_IF_C -> $tcp_rdr_lan_terminal
# Разрешить подключение к переадресованным сервисам из локальной сети по
# внешним адресам.
rdr pass on $int_if inet proto tcp to { $ext_if_a:0 $ext_if_b:0 $ext_if_c:0\
} port { $tcp_svc_lan_terminal } tag INT_IF_RDR -> $tcp_rdr_lan_terminal
nat on $int_if tagged INT_IF_RDR -> $int_if:0
# По умолчанию блокировать весь трафик на всех интерфейсах. Для входящих TCP
# соединений возвращать RST.
block on { $ext_if_a $ext_if_b $ext_if_c $int_if}
block return on { $ext_if_a $ext_if_b $ext_if_c $int_if} inet proto tcp
#Разрешить доступ через лок интерфейс к терминал серверу
pass out quick on $int_if inet proto tcp from any to $tcp_rdr_lan_terminal\
port $tcp_svc_lan_terminal keep state
# Пропускаем входящие пакеты для переадресованых сервисов. Устанавливаем
# для них симметричную маршрутизацию (если пакет пришел
# из канала A, ответ пойдет через канал A независимо от default route).
pass in quick reply-to ($ext_if_a $ext_gw_a) tagged EXT_IF_A keep state
pass in quick reply-to ($ext_if_b $ext_gw_b) tagged EXT_IF_B keep state
pass in quick reply-to ($ext_if_c $ext_gw_c) tagged EXT_IF_C keep state
# Выпускать исходящие пакеты. Установить маршрутизацию в зависимости от
# адреса источника. Пакеты с адресом интерфейса A уходят в канал A,
# с адресом интерфейса B - в канал B.
pass out route-to ( $ext_if_a $ext_gw_a ) inet from $ext_if_a:0 keep state
pass out route-to ( $ext_if_b $ext_gw_b ) inet from $ext_if_b:0 keep state
pass out route-to ( $ext_if_c $ext_gw_c ) inet from $ext_if_c:0 keep state
# Разрешить входящие ICMP PING пакеты.#
pass in on $ext_if_a reply-to ($ext_if_a $ext_gw_a) inet proto icmp\
to $ext_if_a:0 icmp-type echoreq code 0 keep state
pass in on $ext_if_b reply-to ($ext_if_b $ext_gw_b) inet proto icmp\
to $ext_if_b:0 icmp-type echoreq code 0 keep state
pass in on $ext_if_c reply-to ($ext_if_c $ext_gw_c) inet proto icmp\
to $ext_if_c:0 icmp-type echoreq code 0 keep state

# Разрешить входящие TCP сессии для обслуживаемых сервисов.#
pass in on $ext_if_a reply-to ($ext_if_a $ext_gw_a) inet proto tcp\
to $ext_if_a:0 port { $tcp_svc } flags S/SA keep state
pass in on $ext_if_b reply-to ($ext_if_b $ext_gw_b) inet proto tcp\
to $ext_if_b:0 port { $tcp_svc } flags S/SA keep state
pass in on $ext_if_c reply-to ($ext_if_c $ext_gw_c) inet proto tcp\
to $ext_if_c:0 port { $tcp_svc} flags S/SA keep state
#Разрешим туннели на интерфейсе WAN_2 и WAN3
pass in on $ext_if_b reply-to ($ext_if_b $ext_gw_b) inet proto tcp\
from x.x.x.x to $ext_if_b:0 port 5000 flags S/SA keep state
pass in on $ext_if_c reply-to ($ext_if_c $ext_gw_c) inet proto tcp\
from x.x.x.x to $ext_if_c:0 port 5000 flags S/SA keep state
pass quick on tun0 all
pass quick on tun1 all
#Разрешить в локалку пакеты от внутреннего интерфейса, из локальных сетей
# туннелей
pass out on $int_if inet from { $int_if:0, 192.168.3.0/24,\
192.168.4.0/24 } to $int_if:network:0 keep state
#Разрешить из локалки пакеты на внутренний интерфейс, в локальные сети
# туннелей
pass in on $int_if inet from $int_if:network:0 to { $int_if:0,\
192.168.3.0/24, 192.168.4.0/24 } keep state
#Разрешить из локалки пинг
pass in on $int_if inet proto icmp from $int_if:network:0 to any\
icmp-type echoreq code 0 keep state
#Разрешить из локалки 110, 3389, 53
pass in on $int_if inet proto tcp from $int_if:network:0 to any port\
{ 110, 3389 } flags S/SA keep state
pass in on $int_if inet proto udp from $int_if:network:0 to any port\
53 keep state


P.S. И теперь снаружи со всех трех каналов видно терминальный сервер, фтп и почтовый сервера.
Кто-то скажет что фаервол это не маршрутизатор и я согласен. Но на циску денег не дают. Поэтому чем не выход.



Обсудить сообщение можно в форуме admins.arg.su

среда, января 30, 2008

pf и freebsd 6.2

Обстоятельства диктуют переходить с ipfw на pf. Ну чтобы не попасть в просак решил я для начала поставить его на домашнем сервере.

Самое главное в осмыслении работы любого фаервола это понять принцип его работы. На самом деле все просто. Нужно рассматривать прохождение пакетов через интерфейсы относительно системы на которой установлен фаервол. Я хочу сказать что пакет входящий может может прийти в систему из интернета или из локальной сети (LAN). А исходящий пакет - это пакет в интернет или в LAN. Это очень важно.

В нашем случае требовалось обеспечить следующее.
  • Сетевых интерфейсов 2 (внешний и внутренний), включен nat.
  • С сервера наружу в интернет можно все.
  • Ping можно везде.
  • Из интернета на сервер можно пассивный ftp, ssh.
  • Из LAN и обратно можно все через туннель.
  • Из LAN в интернет можно dns, ssh, pop3, smtp, 1723, gre (остальное через прокси).
  • Необходимо пробросить порт на определенную машину в LAN чтобы работал torrent.
В ядро добавляем опции и компилим новое ядро. Как это сделать смотрите здесь

options ALTQ
options ALTQ_CBQ
options ALTQ_RED
options ALTQ_RIO
options ALTQ_HFSC
options ALTQ_PRIQ
options ALTQ_NOPCC
device pf
device pflog
device pfsync

Вообще в нашем конкретном случае все опции не нужны, но я думаю прогодятся в будущем. Добавлять опции в ядро не обязательно, но мне так больше нравится.

Далее добавим в /etc/rc.conf следующие строчки

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

А теперь собственно сам файл /etc/pf.conf с пояснениями.


#int_if - внутренний интерфейс, ext_if - внешний интерфейс
int_if = "rl0"
ext_if = "fxp0"
#comp_rdr_lan на этот комп пробросим порты
comp_rdr_lan = "192.168.2.2"
#порты пробрасываемые внутрь локалки на комп comp_rdr_lan (торент)
comp_rdr_port = "6881, 55555"
#локальная сетка через туннель
lan_work = "192.168.1.0/24"
#Разрешаем из локалки эти порты
tcp_udp_out = "53, 6112"
tcp_out = "22, 25, 110, 1723"
#tcp_services - сервисы на нашем серваке 21 - фтп, 35500:35600 - порты фтп
# для пассивного режима, использую proftpd эти порты указаны в proftpd.conf
# для пассивного режима, порт 113 идент - вроде как используется некоторыми
# сервисами, 22 - ssh
tcp_services = "{ 21, 35500:35600, 113, 22 }"
#icmp_types - какие типы icmp принимать
icmp_types = "echoreq"
# списки приватных сетей, для блокировки их на внешнем интерфейсе
priv_nets = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }"
#Поведение по умолчанию для правил фильтра, когда срабатывает правило block
# в нашем случае для отброшенных пакетов TCP отсылается TCP RST, для прочих
#ICMP Unreacheble
set block-policy return
#Нормализация входящего трафика
scrub in all
#Натим пакеты из локалки
nat on $ext_if from $int_if:network to any -> ($ext_if)
#Проброска портов в локалку на comp_rdr_lan
rdr pass on $ext_if inet proto { tcp, udp } from any to ($ext_if) \
port { $comp_rdr_port } -> $comp_rdr_lan
# по умолчанию запрещаем все
block all
#разрешаем все через локальный интерфейс
pass quick on lo0 all
#Блокируем приватные сети на внешнем интерфейсе
block drop in quick on $ext_if from $priv_nets to any
block drop out quick on $ext_if from any to $priv_nets
#Разрешаем доступ к нашему серваку снаружи к определенным портам
pass in on $ext_if inet proto tcp from any to $ext_if port $tcp_services \
flags S/SA keep state
#Разрешаем входящие icmp ping
pass in inet proto icmp all icmp-type $icmp_types keep state
#Разрешаем все через туннель
pass on tun0 all
pass on tun1 all
#Разрешить из локалки доступ к внутреннему интерфейсу и к локалке работы
pass in quick on $int_if from $int_if:network to { $int_if, $lan_work } \
keep state
#Разрешить из локалки tcp и udp на tcp_udp_out
pass in quick on $int_if inet proto { tcp, udp } from $int_if:network to any \
port { $tcp_udp_out } keep state
#Разрешить из локалки tcp на tcp_out
pass in quick on $int_if inet proto tcp from $int_if:network to any port \
{ $tcp_out } keep state
#Разрешить из локалки gre
pass in quick on $int_if inet proto gre from $int_if:network to any keep state
#Разрешить в локалку все через внутренний интерфейс
pass out on $int_if from any to $int_if:network keep state
#Разрешить наружу tcp через внешний интерфейс
pass out on $ext_if proto tcp all modulate state flags S/SA
#Разрешить наружу udp, icmp, gre через внешний интерфейс
pass out on $ext_if proto { udp, icmp, gre } all keep state


Ну и как памятка некоторые команды.

pfctl -sn Показать текущие правила NAT.
pfctl -sr Показать текущие правила фильтра.
pfctl -ss Показать текущую таблицу состояний.
pfctl -sa Показать все что можно.

P.S. Конфигурационный файл взят с абсолютно рабочей машины.



Обсудить сообщение можно в форуме admins.arg.su