Настройка Firewall, NAT,ALTQ на PF
Packet Filter (PF) - фаервол разработанный для OpenBSD и позже портированный на FreeBSD и NetBSD. По сравнению с тем же ipfw, имеет более понятный для чтения и написания правил синтаксис, имеет встроенный NAT, очереди и другие вкусности. Примеры конфигов можно увитеть тут: /usr/share/examples/pf.
В ОС FreeBSD он поставляется в виде подгружаемых модулей ядра, добавим его поддержку:
pf_rules="/etc/pf.conf"
pf_flags=""
pflog_enable="YES"
pflog_logfile="/var/log/pflog"
pflog_flags=""
gateway_enable="YES"
Если FreeBSD используется в качестве маршрутизатора, следует разрешить проброс пакетов, добавить в файл /etc/sysctl.conf:
net.inet6.ip6.forwarding=1
Сам конфиг у нас находиться в /etc/pf.conf и имеет организованную структуру:
1. Макросы: Определяемые пользователем переменные, которые могут содержать адреса IP, имена интерфейсов, и т.д.
2. Таблицы: Применяются для хранения списков IP адресов.
3. Опции: Параметры, влияющие на работу pf.
4. Параметры нормализации Scrub: Подготовка пакета к нормализации и дефрагментации.
5. Приоретизация и очереди ALTQ: Обеспечивает управление полосой пропускания и установку приоритетов пакета.
6. Трансляции: Контроль NAT и перенаправление пакетов.
7. Правила фильтрации: Осуществляют выборочную фильтрацию пакетов на интерфейсах.
Для ясности происходящего приведу пример включения PF в сеть:
# Внешний виртуальный сетевой интерфейс созданный PPPoE.
ext_if="tun0"
# WAN ISP
int_isp="vr1"
# Сетевой интерфейс который смотрит в мою домашнюю сеть.
int_if="vr0"
router="192.168.1.1"
LAN="192.168.1.0/24"
# Разрешенные типы icmp сообщений
allowed_icmp_types="{ echoreq, unreach }"
# Открытые порты со стороны интернет
servises_ext = "{ 21 80 3389 4899 5900 }"
# Cписок немаршрутизируемых адресов, с которых к нам будут долбиться на внешний интерфейс
non_route_nets_inet="{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, 0.0.0.0/8, 240.0.0.0/4 }"
####ТАБЛИЦЫ####
# Те, кто ходит у меня через NAT.
table <it> persist { 192.168.1.5 }
# Всем с сети 192.168.2.0/24 кроме 192.168.2.200.
#table <clients> { 192.168.2.0/24, !192.168.2.200 }
####CONTROL PF####
# Тем, кто лезет туда куда не нужно вежливо сообщаем что нельзя
#set block-policy return
# Если Вас досят, есть смысл поставить вместо "return".
set block-policy drop
# Не проверяем на lo0
set skip on lo0
# Изменяем время для состояния установленного tcp соединения, которое по-умолчанию чересчур большое (24часа).
set timeout { frag 10, tcp.established 3600 }
# Собирать пакеты перед отправкой
scrub in all
#Очереди, полоса - 2мбит, режем исходящий трафик от сервера с стороны внешнего интерфейса tun0.
altq on $ext_if cbq bandwidth 1980Kb queue { qssh, qhttp, qdns, qack, qftp }
queue qhttp bandwidth 70% priority 6 cbq (default borrow)
queue qssh bandwidth 15% priority 5 cbq (borrow)
queue qdns bandwidth 5% priority 5 cbq (borrow)
queue qack bandwidth 5% priority 6 cbq (borrow)
queue qftp bandwidth 5% priority 2 cbq (red)
#### NAT ####
# Тем, кто в таблице <it> разрешаем ходить в интернет через NAT, кроме 25 порта.
nat on $ext_if inet from <it> to any port != smtp -> ($ext_if)
# Для примера, NAT всех разрешенных портов, кроме www
#nat on $ext_if from $int_if:network to any port { ntp, nntp, domain } -> $ext_if
nat on $ext_if inet from 192.168.1.100 to any port smtp -> ($ext_if) #DBSERV
#### PORTMAPING ####
# Указываем какие порты редиректить и куда.
rdr on $ext_if inet proto tcp from any to any port 3389 -> 192.168.1.10 port 3389 #RDP
rdr on $ext_if inet proto tcp from any to any port 4899 -> 192.168.1.11 port 4899 #RADMIN
rdr on $ext_if inet proto tcp from any to $ext_if port 5900 -> 192.168.1.12 port 5900 #VNC
#### ПРАВИЛА ФИЛЬТРАЦИИ ####
# Блокируем всяких нехороших людей стандартный антиспуфинг средствами pf.
antispoof log quick for { lo0, $int_if, $ext_if }
#### $ext_if ####
#Блокируем все входящие на внешнем интерфейсе (ext_if) tun0
block in on $ext_if
#Рубаем Мультикастовые рассылки (Данные, предназначенные для приемом группой машин. В отличие от unicast и broadcast)
block in on $ext_if from any to 240.0.0.0/4
#Блокируем приватные сети на внешний интерфейс
block drop in quick on $ext_if from $non_route_nets_inet to any
block drop out quick on $ext_if from any to $non_route_nets_inet
#Разрешаем пинги на внешний интерфейс
pass in on $ext_if inet proto icmp all icmp-type $allowed_icmp_types
#Разрешаем ssh на внешнем интерфейсе
pass in quick on $ext_if inet proto tcp from any to any port 2222 keep state
#Разрешаем открытые порты на внешнем интерфейсе
pass in on $ext_if inet proto { tcp,udp } from any to any port $servises_ext flags S/SA keep state
#IN ALTQ
pass in on $ext_if inet proto { tcp,udp } from any to $ext_if port 2222 queue ( qssh, qack )
pass in on $ext_if inet proto { tcp,udp } from any to $ext_if port 80 queue qhttp
pass in on $ext_if inet proto { tcp,udp } from any to $ext_if port 53 queue qdns
pass in on $ext_if inet proto { tcp,udp } from any to $ext_if port { 21 30000:35000 } queue qftp
#OUT ALTQ
pass out on $ext_if inet proto { tcp,udp } from $ext_if to $ext_if port 2222 queue ( qssh, qack )
pass out on $ext_if inet proto { tcp,udp } from $ext_if to $ext_if port 80 queue qhttp
pass out on $ext_if inet proto { tcp,udp } from $ext_if to $ext_if port 53 queue qdns
pass out on $ext_if inet proto { tcp,udp } from $ext_if to $ext_if port { 21 30000:35000 } queue qftp
#Разрешить все исходящие на внешнем интерфейсе
pass out on $ext_if keep state
#### $int_isp ####
# Разрешаем все на этом интерфейсе.
pass in quick on $int_isp all
pass out quick on $int_isp all
#### $int_if ####
# Наша локалка
# Блокируем все входящие на внутр. интерфейсе (int_if)
block in on $int_if all
#Разрешаем пинги на внутр. интерфейсе
pass in on $int_if inet proto icmp all icmp-type $allowed_icmp_types
#Разрешаем открытые порты на внутр. интерфейсе
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 21 flags S/SA keep state #ftp
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 30000:35000 flags S/SA keep state #ftp-pasive
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 25 flags S/SA keep state #smtp
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 53 flags S/SA keep state #domain
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 67 flags S/SA keep state #dhcps
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 80 flags S/SA keep state #http
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 110 flags S/SA keep state #pop3
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 123 flags S/SA keep state #synctime (ntp)
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 137:139 flags S/SA keep state #samba
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 143 flags S/SA keep state #imap
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 445 flags S/SA keep state #microsoft-ds
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 465 flags S/SA keep state #ssmtp
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 993 flags S/SA keep state #imaps
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 995 flags S/SA keep state #pop3s
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 2222 flags S/SA keep state #SSH
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 3128 flags S/SA keep state #proxy
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 5222:5223 flags S/SA keep state #jabber
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 8000 flags S/SA keep state #stream-radio
pass in on $int_if inet proto { tcp,udp } from $LAN to $router port 9090 flags S/SA keep state #jabber-www-adminka
#for NAT
pass in on $int_if inet proto { tcp,udp } from <it> to any flags S/SA keep state
#Разрешить все исходящие на внутр. интерфейсе
pass out on $int_if keep state
PF имеет некоторые ключи для работы:
Включить pf:
Выключить pf:
Загрузить pf.sh:
Анализировать, но не загружать конфиг:
Загрузить только правила NAT:
Загрузить только правила фильтрации:
Просмотр:
Показать текущие правила NAT:
Показать текущие правила фильтрации:
Показать текущее состояние таблиц:
Показать статистику правил и состояние счетчиков:
Показать все:
Просмотр очередей ALTQ в реалтайме:
Подсчет трафика с помощью pf на определенных интерфейсах:
Подсчет трафика с помощью pf на всех интерфейсах:
Сброс всех правил PF, полный клир:
Логирование трафика
Для просмотра логов, которые находятся в /var/log/pflog и не читабельны простым редактором используют tcpdump:
В реальном времени:
Для просмотра пакетов, которые прошли через определенный порт, в данном случае smtp порт:
Можно ограничить показ пакетов комбинацией указанных адреса хоста и порта:
Такой же способ применим при чтении информации из интерфейса pflog0:
Ставим в крон и отправляем себе на почту например каждый день в 8.00:
tcpdump -n -e -r /var/log/pflog | mail admin(at)unix.ck.ua && cat /dev/null > /var/log/pflog
Теперь пробуем проанализировать ваш конфиг:
если ошибок нет, значит все в порядке и можна загружать его в PF:
Для большей безопасности я пересобираю ядро с поддержкой PF:
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
Вот вроде и всё.
- Войдите на сайт для отправки комментариев
- Версия для печати
глянь ещё тут: ALTQ HFSC