Subject: PF блокирует любой трафик, если не указано "можно всё и всем".
Здравствуйте! Система FreeBSD 7.0-RELEASE готовится к тому, чтобы стать шлюзом между интернетом (через VPN от провайдера) и локальной сетью. Она уже настроена и вполне работоспособна за исключением одного момента - не работает нормально pf (настройка pf проводилась в соответствии с http://house.hcn-strela.ru/BSDCert/BSDA-course/apcs02.html#p...)
Приведу фрагмент pf.conf:int_if = "fxp1" # внутренний интерфейс
ext_if = "sis0" # внешний интерфейсlocal_network = "{ 192.168.5.0/24 }" # локальная сеть, ip шлюза 192.168.5.1
comstar_vpn = "{ 10.0.0.0/24 }" # сеть провайдера
table <denied> persist file "/etc/pf/denied.txt"
table <allowed> const { 192.168.5.44, 192.168.5.91, 192.168.5.1 }set block-policy drop
set skip on lo0scrub in all fragment reassemble
scrub out all random-id##### NAT #####
nat on $ext_if inet from $local_network -> ($ext_if)##### block #####
block log on { $ext_if }
block return on { $ext_if } inet proto tcp##### filter ######
### out ###
pass out on $ext_if inet from any to any keep stateСобственно проблема: в таком виде трафик нормально проходит, но вот толку от такого файрволла нет. Стоит заменить, например, последнюю строку на
pass out on $ext_if inet from <allowed> to any keep state
или
pass out on $ext_if inet from 192.168.5.44 to any keep stateкак трафик ходить перестаёт. Наличие или отстутствие keep state на ситуацию не влияет (и не должно, но я старался проверить всё - мало ли). Написание строки в в виде
pass out all
block out on $ext_if inet from { <denied>, !<allowed> } to anyрезультатов также не дало.
Пробовал смотреть логи с помощью
# tcpdump -n -e -ttt -r /var/log/pflog
В первое применение команда выдала вывод примерно на страницу, но на тот момент я не зафиксировал его. А при последующих попытках выдаёт только
# reading from file /var/log/pflog, link-type PFLOG (OpenBSD pflog file)
При этом в rc.conf строки
pflog_enable="YES"
pflog_logfile="/var/log/pflog"
присутствуют.В общем же у меня такое впечатление, будто PF "не понимает" чего-то, когда я подсовываю ему ip или табличку для разрешения выхода. При этом встроенные переменные вроде all обрабатываютс нормально (например, можно явно указать протоколы - tcp и udp - всё будет работать).
Вопрос: какую мелочь я пропустил и какой важной информации для решения проблемы не сообщил?
P.S. Т.к. с FreeBSD я знаком только 1 неделю, прошу отправлять меня не просто "курить маны", а "курить ... маны", где "..." - точное название и подробное описание маршрута. Спасибо.
>[оверквотинг удален]
>### out ###
>pass out on $ext_if inet from any to any keep state
>
>Собственно проблема: в таком виде трафик нормально проходит, но вот толку от
>такого файрволла нет. Стоит заменить, например, последнюю строку на
>
>pass out on $ext_if inet from <allowed> to any keep state
>или
>pass out on $ext_if inet from 192.168.5.44 to any keep state
>уходить то будут с адресом $ext_if, а не 192.168.5.0/24
>[оверквотинг удален]
>
>В общем же у меня такое впечатление, будто PF "не понимает" чего-то,
>когда я подсовываю ему ip или табличку для разрешения выхода. При
>этом встроенные переменные вроде all обрабатываютс нормально (например, можно явно указать
>протоколы - tcp и udp - всё будет работать).
>Вопрос: какую мелочь я пропустил и какой важной информации для решения проблемы
>не сообщил?
>P.S. Т.к. с FreeBSD я знаком только 1 неделю, прошу отправлять меня
>не просто "курить маны", а "курить ... маны", где "..." -
>точное название и подробное описание маршрута. Спасибо.
>[оверквотинг удален]
>>
>
>уходить то будут с адресом $ext_if, а не 192.168.5.0/24
>
>>[оверквотинг удален]
>>
>>В общем же у меня такое впечатление, будто PF "не понимает" чего-то,
>>когда я подсовываю ему ip или табличку для разрешения выхода. При
>>этом встроенные переменные вроде all обрабатываютс нормально (например, можно явно указать
>>протоколы - tcp и udp - всё будет работать).^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Что мешает указывать протокол? ИМХО без этого никак))))>>Вопрос: какую мелочь я пропустил и какой важной информации для решения проблемы
>>не сообщил?
>>P.S. Т.к. с FreeBSD я знаком только 1 неделю, прошу отправлять меня
>>не просто "курить маны", а "курить ... маны", где "..." -
>>точное название и подробное описание маршрута. Спасибо.http://www.openbsd.org/faq/pf/ - первоисточник
http://www.lissyara.su/?id=1671 - Лисяра, полезная инфа.... да и еще обратите внимание на tcpdump (позволит увидеть куда и как пакеты ходят/приходят).
Разобрался, как работает tcpdump. Ниже - вывод лога пинга google.com (по правилу pass out log all.002582 rule 10/0(match): pass out on sis0: 10.0.0.2 > 64.233.187.99: ICMP echo request, id 15822, seq 5636, length 40
155676 rule 10/0(match): pass out on fxp1: 64.233.187.99 > 192.168.5.44: ICMP echo reply, id 512, seq 5636, length 40
3. 348888 rule 10/0(match): pass out on fxp1: 192.168.5.1 > 192.168.5.44: [|icmp]
005856 rule 10/0(match): pass out on fxp1: 192.168.5.1 > 192.168.5.44: [|icmp]
000035 rule 10/0(match): pass out on fxp1: 192.168.5.1 > 192.168.5.44: [|icmp]
Получается, что исходящий трафик уходит с 10.0.0.2, как мне и говорили. Потом уже возвращается на комп, с которого шёл пинг (192.168.5.44). Как в таком случае верно составить правила, которые бы позволяли бы контролировать этот процесс?
Я внимательно читал и ркомендации "Лисяры", и оригинал, но, видимо, чего-то недопонял всё-таки.
По-прежнему любое применение правил вызывает прекращение хождения трафика.
Пытался построить конструкции, в т.ч.:pass out all
block in all
pass in on fxp1 from any to <allowed>основываясь на данных tcpdump, однако они оказались нерабочими. Я буду продолжать попытки разобраться, но если кто-то поможет приблизить победу, буду рад.
>[оверквотинг удален]1
>таком случае верно составить правила, которые бы позволяли бы контролировать этот
>процесс?что именно хотите контролировать?
>Я внимательно читал и ркомендации "Лисяры", и оригинал, но, видимо, чего-то недопонял
>всё-таки.
>По-прежнему любое применение правил вызывает прекращение хождения трафика.
>Пытался построить конструкции, в т.ч.:
>
>pass out all
>block in all
>pass in on fxp1 from any to <allowed>это весь pf.conf? если да, то где разрешение входящих для внешнего интерфейса и NAT, если только часть, то этого мала, покажите весь pf.conf, только без закоментированных строк.
>
>основываясь на данных tcpdump, однако они оказались нерабочими. Я буду продолжать попытки
>разобраться, но если кто-то поможет приблизить победу, буду рад.
Дайте листинги
pf.conf
ifconfigКомментарии после вашего ответа.
Привожу целиком, без каких-либо сокращений, pf.conf. К сожалению, ifconfig я сейчас привести не могу, но могу привести rc.conf, будет понятно, как настроены интерфейсы.
По поводу вопроса о том, что я хочу контролировать: надеюсь, из pf.conf это будет понятно.
pf.conf##### Macros's ######
int_if = "fxp1"
ext_if = "sis0"local_network = "{ 192.168.5.0/24 }"
s_network = "{ 192.168.6.0/24 }"
provider_vpn = "{ 10.0.0.0/24 }"
mysql = "{ 192.168.5.8, 192.168.5.7 }"
table <denied> persist file "/etc/pf/denied.txt"
table <bad_url> persist file "/etc/pf/bad_url.txt"
table <inet_limit> persist file "/etc/pf/inet_limit.txt"
table <provider-stat> const file "/etc/pf/provider-stat.txt"
table <health> const file "/etc/pf/health.txt"
table <allowed> const { 192.168.5.79, 192.168.5.47, 192.168.5.44, 192.168.5.91, 192.168.5.50, 192.168.5.1 }
table <n_mail> const { 192.168.5.47, 192.168.5.92, 192.168.5.71, 192.168.5.96 }xpd = "{ 89.111.146.132, 89.111.146.134 }"
cont_ru = "{ 89.249.18.81 }"
tcp_services = "{ 21, 22, 123, 135, 53, 119, 3389, 12489, 3306, 1000:3000, 3000:6000, 6000:12000, 21080 }"
tcp_inet_limit = "{ 3000:6000, 1500, 2082, 21, 20, 1000:50000, 80, 8010, 8080, 443, 873, 6000:12000 }"
im = "{ 5190, 5222, 5060:5070, 3478, 16384:16482, 17948:17949 }"
mail_services = "{ 143, 993, 389, 636, 110, 995, 25, 465 }"
web_ports = "{ 80, 8080, 8000, 443 }"set block-policy drop
set skip on lo0scrub in all fragment reassemble
scrub out all random-id##### NAT #####
nat on $ext_if inet from $local_network -> ($ext_if)##### block #####
block log on { $ext_if }
block out quick on $ext_if inet proto tcp from { <denied>, !<allowed> } to <bad_url> port $web_ports
block return on { $ext_if } inet proto tcp##### filter ######
### out ###
pass out on $ext_if inet proto tcp from { $local_network } to { $cont_ru } port $web_ports keep state
pass out on $ext_if inet proto tcp from { $mysql } to { $xpd } port 3306 keep state
pass out on $ext_if inet proto { tcp, udp } from { 10.0.0.1, $local_network, $s_network, $provider_vpn } to { 83.136.24.60, 83.136.24.15, <provider-stat> } keep state
pass out on $ext_if inet proto tcp from 192.168.5.98 to any port $web_ports keep state
pass out on $ext_if inet proto tcp from { 192.168.5.48, <n_mail>, <allowed> } to any port $mail_services keep state
pass out on $ext_if inet proto tcp from { 192.168.5.47, 192.168.5.7 } to <health> port $web_ports keep state
pass out on $ext_if inet proto tcp from { 192.168.5.47, 192.168.5.7 } to <health> port 1000:3000 keep state
pass out on $ext_if inet proto tcp from { $local_network, $s_network, $provider_vpn } to { $local_network, $s_network, $provider_vpn } port 6000:12000 keep state
pass out on $ext_if inet proto tcp from { 192.168.5.47, 192.168.5.7 } to any port { 1000:3000, 3000:6000, 21, 21080, 10001, 10021 } keep state
pass out on $ext_if inet proto { tcp, udp } from { 192.168.5.15, 192.168.5.63, 192.168.5.220, 192.168.5.104, 192.168.5.61, 192.168.5.94, 192.168.5.73, 192.168.5.108, <allowed> } to any port $im keep state
pass out on $ext_if inet proto tcp from 192.168.5.7 to 89.111.188.96 keep state
pass out on $ext_if inet proto tcp from <inet_limit> to any port $tcp_inet_limit keep state
pass out on $ext_if inet proto tcp from { $local_network, $s_network, $provider_vpn } to { 192.168.5.1, 83.69.241.55 } port 3389 keep state
pass out on $ext_if inet proto tcp from <allowed> to any port $web_ports keep state
pass out on $ext_if inet proto icmp from any to any keep state
pass out on $ext_if inet proto udp from any to any port domain keep state### in ###
pass in on $ext_if inet proto icmp from any to any keep state
pass in on $ext_if inet proto udp from any to any keep state
pass in on $ext_if inet proto tcp from $ext_if to any port $tcp_services keep state
pass in on $ext_if inet proto tcp from $ext_if to any port $tcp_inet_limit keep state
pass in on $ext_if inet proto tcp from $ext_if to any port $im keep state
pass in on $ext_if inet proto tcp from $ext_if to any port $mail_services keep state
pass in on $ext_if inet proto tcp from $ext_if to any port $web_ports keep state
rc.conf# Services
gateway_enable="YES"
sshd_enable="YES"
nrpe2_enable="YES"
ntpdate_enable="YES"
webmin_enable="YES"
ntpdate_flags="-b europe.pool.ntp.org"# PacketFilter
pf_enable="NO"
pf_rules="/etc/pf.conf"
pf_flags=""
pflog_enable="YES"
pflog_logfile="/var/log/pflog"
pflog_flags=""# Interface's
ifconfig_fxp1="inet 192.168.5.1 netmask 255.255.255.0"
ifconfig_sis0="inet 10.0.0.2 netmask 255.255.255.248"
defaultrouter="10.0.0.1"
hostname="mars.n.domain.ru"
>[оверквотинг удален]
>##### NAT #####
>nat on $ext_if inet from $local_network -> ($ext_if)
>
>##### block #####
>block log on { $ext_if }
>block out quick on $ext_if inet proto tcp from { <denied>, !<allowed> } to <bad_url> port $web_ports
>block return on { $ext_if } inet proto tcp
>
>##### filter ######
>после NAT, здесь адресом источника, для исходящих с $ext_if, уже будет адрес внешнего интерфейса.
по адресу источника фильтруйте на внутреннем интерфейсе или для них не делайте NAT и потом не выпускайте с $ext_if пакеты с адресом источника, отличным от адреса внешнего интерфейса.
>[оверквотинг удален]
>pf_flags=""
>pflog_enable="YES"
>pflog_logfile="/var/log/pflog"
>pflog_flags=""
>
># Interface's
>ifconfig_fxp1="inet 192.168.5.1 netmask 255.255.255.0"
>ifconfig_sis0="inet 10.0.0.2 netmask 255.255.255.248"
>defaultrouter="10.0.0.1"
>hostname="mars.n.domain.ru"
>[оверквотинг удален]
>web_ports = "{ 80, 8080, 8000, 443 }"
>
>set block-policy drop
>set skip on lo0
>
>scrub in all fragment reassemble
>scrub out all random-id
>
>##### NAT #####
>nat on $ext_if inet from $local_network -> ($ext_if)У вас ДХЦП????? ^^^^
>[оверквотинг удален]
># Services
>gateway_enable="YES"
>sshd_enable="YES"
>nrpe2_enable="YES"
>ntpdate_enable="YES"
>webmin_enable="YES"
>ntpdate_flags="-b europe.pool.ntp.org"
>
># PacketFilter
>pf_enable="NO"^^^^
нуна "YES">[оверквотинг удален]
>pf_flags=""
>pflog_enable="YES"
>pflog_logfile="/var/log/pflog"
>pflog_flags=""
>
># Interface's
>ifconfig_fxp1="inet 192.168.5.1 netmask 255.255.255.0"
>ifconfig_sis0="inet 10.0.0.2 netmask 255.255.255.248"
>defaultrouter="10.0.0.1"
>hostname="mars.n.domain.ru"Да, и вот еще, попробуйте сначала сделать простые правила, а затем усложнять и приводить к реалиям.
Вопросы:
1) Распишите, что именно вы хотите сделать с PF.
2) Мониторить пробовали? Дайте вывод загрузки правил...
В этом куске заменить "pass out on $ext_if" на "pass quick in on $int_if"
А перед ним поставить "block in on $int_if"
И поубирать "keep-state" везде!
>[оверквотинг удален]
>state
>pass out on $ext_if inet proto tcp from <inet_limit> to any port $tcp_inet_limit keep state
>pass out on $ext_if inet proto tcp from { $local_network, $s_network, $provider_vpn
>} to { 192.168.5.1, 83.69.241.55 } port 3389 keep state
>pass out on $ext_if inet proto tcp from <allowed> to any port $web_ports keep state
>pass out on $ext_if inet proto icmp from any to any keep
>state
>pass out on $ext_if inet proto udp from any to any port
>domain keep state
>А вообще конфиг можно оптимизировать. Попробуйте изложить задачу фильтра по-русски.
>после NAT, здесь адресом источника, для исходящих с $ext_if, уже будет адрес внешнего >интерфейса. по адресу источника фильтруйте на внутреннем интерфейсе или для них не >делайте NAT и потом не выпускайте с $ext_if пакеты с адресом источника, отличным от >адреса внешнего интерфейса.Спасибо. Тут разобрался и понял, куда как пакеты ходят.
>У вас ДХЦП????? ^^^^
Да. Те машины, доступ которых надо так или иначе контролировать, имеют StaticDHCP.
># PacketFilter
>pf_enable="NO"
> ^^^^
>нуна "YES"Я его просто вручную включаю пока. Чтобы в крайнем случае, если совсем всё заблокирую, машину можно было бутнуть (работаю по ssh). Впрочем, теперь уже подключены монитор и клавиатура.
>Да, и вот еще, попробуйте сначала сделать простые правила, а затем усложнять и приводить >к реалиям.
Уже осознал и перешёл. Дело на самом деле в том, что всё это нерабочее хозяйство досталось мне от уволившегося админа, который не успел этот шлюз довести до ума. Вот я теперь систему и осваиваю.
> 1) Распишите, что именно вы хотите сделать с PF.
Если рассматривать простейший квант задачи - то обеспечить выполнения простых правил:
компу(группе компов) А можно через нат выходить в интернет (другую подсеть),
компу(группе компов) Б - нельзя.
Из таких кусочков можно построить всё, что мне необходимо.
> 2) Мониторить пробовали? Дайте вывод загрузки правил...Пробовал - будет чуть ниже.
>В этом куске заменить "pass out on $ext_if" на "pass quick in on $int_if"
>А перед ним поставить "block in on $int_if"
>И поубирать "keep-state" везде!Почему-то не получилось. А keep state - в соответствии с http://www.lissyara.su/?id=1671 - роли тут не играет.
> Попробуйте изложить задачу фильтра по-русски.
Разрисовка всего на бумаге помогла найти ошибку в правилах, но сами бы правила работали...
В общем, что сделал. Упростил правила до минимума, пока pf пускает всё и контролирует только icmp - так проще наблюдать за ситуацией. Если в секции out стоит следующее:
pass out all #выпускаем весь трафик
block out log proto icmp from any to any #но блокируем icmp весь
pass out log on $ext_if proto icmp from any to any #разрешаем его, тем не менее, с $ext_if
pass out log on $int_if proto icmp from any to any #и с $int_if тожеТо получаем закономерную картину для пинга ya.ru с машины 192.168.5.44:
000000 rule 14/0(match): pass out on sis0: (tos 0x0, ttl 127, id 12159, offset 0, flags [none], proto ICMP (1), length 60) 10.0.0.2 > 213.180.204.8: ICMP echo request, id 13284, seq 4106, length 40
003610 rule 15/0(match): pass out on fxp1: (tos 0x0, ttl 57, id 23417, offset 0, flags [none], proto ICMP (1), length 60) 213.180.204.8 > 192.168.5.44: ICMP echo reply, id 512, seq 4106, length 40Теперь меняем последнее правило:
pass out all #выпускаем весь трафик
block out log proto icmp from any to any #но блокируем icmp весь
pass out log on $ext_if proto icmp from any to any #разрешаем его, тем не менее, с $ext_if
pass out log on $int_if proto icmp from 192.168.5.44 to any #а с $int_if разрешаем только заданному IPИ получаем картину странную:
000000 rule 14/0(match): pass out on sis0: (tos 0x0, ttl 127, id 56379, offset 0, flags [none], proto ICMP (1), length 60) 10.0.0.2 > 213.180.204.8: ICMP echo request, id 2281, seq 6410, length 40
014106 rule 13/0(match): block out on fxp1: (tos 0x0, ttl 57, id 30264, offset 0, flags [none], proto ICMP (1), length 60) 213.180.204.8 > 192.168.5.44: ICMP echo reply, id 512, seq 6410, length 40Т.е. трафик, уходящий с внутреннего интерфейса (fxp1) благополучно блокируется, хотя разрешён явным образом. Пробовал задавать не IP, а таблицу <allowed> в правиле, играться с ключами keep state/no state, добавлять quick и т.п. Без толку, картина одинаковая.
Одинаково непонятная для меня пока.
Так что продолжаем борьбу.P.S. а тут ещё вышел более чем недельный перерыв в работе.
>[оверквотинг удален]
>с $int_if разрешаем только заданному IP
>
>И получаем картину странную:
>
>000000 rule 14/0(match): pass out on sis0: (tos 0x0, ttl 127, id 56379, offset 0, flags [none], proto ICMP (1), length 60) 10.0.0.2 > 213.180.204.8: ICMP echo request, id 2281, seq 6410, length 40
>014106 rule 13/0(match): block out on fxp1: (tos 0x0, ttl 57, id 30264, offset 0, flags [none], proto ICMP (1), length 60) 213.180.204.8 > 192.168.5.44: ICMP echo reply, id 512, seq 6410, length 40
>
>Т.е. трафик, уходящий с внутреннего интерфейса (fxp1) благополучно блокируется, хотя разрешён явным образом. Пробовал задавать не IP, а таблицу <allowed> в правиле, играться с ключами keep state/no state, добавлять quick и т.п. Без толку, картина одинаковая.
>Одинаково непонятная для меня пока.
>Так что продолжаем борьбу.вы разрешили с 192.168.5.44 на любой, а ответы на 192.168.5.44 - нет, что и видите в логах
>
>P.S. а тут ещё вышел более чем недельный перерыв в работе.
Также Вам необходимо изучить синтаксис фильтра.
>вы разрешили с 192.168.5.44 на любой, а ответы на 192.168.5.44 - нет, что и видите в >логах
>Также Вам необходимо изучить синтаксис фильтра.Спасибо! Наконец-то, общими усилиями, я начал потихоньку понимать, что к чему. И частично фильтр у меня уже работает. Когда всё будет настроено, отпишу - почти наверняка будут ещё хорошие советы. Ну и "чайникам" вроде меня, может быть, поможет.