Cellar Door

10 июля 2005

OpenBSD Packet Filter

Сегодня разбирался с пакетным фильтром pf. Краткие впечатления - божественно. ИМХО о таком сочетании простоты, мощи и гибкости остальные open-source файрволы (и, как пишут, многие коммерческие - сам pf нередко приравнивают к продукции небезызвестной CheckPoint) могут только мечтать. Рабочий конфиг (без nat) можно поместить менее чем в 10 строчек, превосходно читабельных кстати. А функции stateful inspection, scrub, ALTQ дают понять, что это творение совсем другого класса, чем iptables, ifpw или ifpilter... Вот результат моих сегодняшних экспериментов, конфиг для DHCP-подключения (без NAT):

ext_if="ppp0"
udp_serv = "{ domain }"
tcp_serv = "{ 6 }"
priv_nets = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }"

#set loginterface $ext_if

scrub in on $ext_if all fragment reassemble no-df min-ttl 20 max-mss 1440
scrub on $ext_if all reassemble tcp
scrub out on $ext_if all random-id no-df

# silently drop TCP non-SYN packets, the remaining ruleset only deals with
# TCP SYNs, which always create state when passed. the ruleset basically
# deals with 'connections', not packets, beyond this point.
#
block out quick proto tcp all flags /S
block in quick proto tcp all flags /S
block out quick proto tcp all flags A/A
block in quick proto tcp all flags A/A
#
# Some anti-fingerprinting techniques
#
block in quick proto tcp all flags SF/SFRA
block in quick proto tcp all flags SFUP/SFRAU
block in quick proto tcp all flags FPU/SFRAUP
block in quick proto tcp all flags F/SFRA
block in quick proto tcp all flags U/SFRAU
block in quick proto tcp all flags P/P

# block and log everything by default
#
block in log all
block out all

# block anything coming from source we have no back routes for
#
block in log from no-route to any

# block and log outgoing packets that don't have my address as source, they are
# either spoofed or something is misconfigured (NAT disabled, for instance),
#
block out log quick on $ext_if inet from !($ext_if) to any

# silently drop broadcasts (cable modem noise)
#
block in log quick on $ext_if from any to 255.255.255.255

# RFC 1918 - block private networks
#
block in log quick on $ext_if inet from $priv_nets to any
block out log quick on $ext_if inet from ($ext_if) to $priv_nets

pass quick on lo0 all keep state

# ICMP
#
pass out on $ext_if inet proto icmp from ($ext_if) to any icmp-type 8 code 0 keep state
#pass in on $ext_if inet proto icmp from any to ($ext_if) icmp-type 8 code 0 keep state

# UDP
#
pass out on $ext_if inet proto udp from ($ext_if) to any keep state
#pass in on $ext_if inet proto udp from any to ($ext_if) port $udp_serv keep state

# TCP
#
pass out on $ext_if inet proto tcp from ($ext_if) to any modulate state flags S/SA
#pass in on $ext_if inet proto tcp from any to ($ext_if) port $tcp_serv synproxy state flags S/SA

Историческая справка: pf был написан в течении лета-осени 2001 года Daniel Hartmeier и сообществом разработчиков OpenBSD, к чему их вынудили проблемы с лицензированием кода ipfilter, а сейчас он доступен пользователям OpenBSD, FreeBSD, NetBSD и DragonFly.
Вот два лучших ресурса по теме:
http://www.benzedrine.cx/pf.html
https://www.solarflux.org/pf/
А русскоязычная документация например здесь: часть 1, часть 2.