FreeBSD firewall - IPFW
Obsah
Úvod
Účelem tohoto dokumentu není podrobný popis typů firewallů a jejich realizace,
ale průvodce konfigurací paketového firewallu IPFW pod FreeBSD.
Proč firewall
- Isolace vnitřní sítě - jeden přístupový bod do Internetu.
- Znemožnění zmapování sítě zvenčí.
- Sledování provozu na síti.
- Jemnější specifikace práv individuálních počítačům/uživatelů.
- Odstínění případných bezpečnostních děr v softwaru síťových služeb.
Typy firewallů
Firewally můžeme rozdělit na dva základní typy:
Aplikační brána
Pracuje na aplikační vrstvě. Střeží tedy jednotlivé aplikace. Veškerá komunikace
probíhá prostřednictvím proxy serverů, tzv. zástupných serverů. Místo klasických
démonů (telnetd, ftpd atd.) běží speciálně upravené proxy servery. Uživatelé
přistupují ke službách prostřednictvím těchto proxy serverů transparentně nebo
pomocí upravených klientů.
Komunikace mezi serverem a klientem vypadá následovně:
klient chce kontaktovat server, místo toho kontaktuje proxy server na firewallu
a ten dále komunikuje se skutečným serverem dle daných pravidel.
+ možnost autentizace na úrovni uživatelů
+ není potřeba zasahovat do jádra
- nutnost úpravy aplikací
- nutnost zvláštního programu pro každou aplikaci
Paketový filter
Pracuje na síťové vrstvě. Zkoumá hlavičky každého paketu a podle seznamu pravidel
se rozhodne jak s daným paketem naloží. Tedy daný paket může např. zahodit, anebo
pustit k dalšímu zpracování.
+ není potřeba upravovat aplikace
+ rychlost, většina operací se odehrává uvnitř jádra
+ nenáročný, lze vyrobit firewall na jedné disketě
- autentizace jen podle IP adres či čísla portů
Paketový filtr IPFW
IPFW je nativní paketový filter a traffic-shapper pod FreeBSD. Jako další volbu
pro paketový filtr pod FreeBSD lze použít
IP Filter,
jemuž se v tomto dokumentu věnovat nebudu. Porovnání IPFW a IP Filtru je shrnuto
zde.
Pro pochopení a následnou tvorbu pravidel paketového filtru je potřeba vědět, jak
pakety putují jádrem. Data příjdou na fyzické síťové rozhraní ze sítě a jádro si
je vyzvedne a zpracuje do formy paketu. Podle cílové IP adresy jádro určí, zda
paket patří tomuto počítači nebo jinému a bude
forwardován (forwardování se musí zapnout pomocí sysctl -w net.inet.ip.forwarding=1).
Další možnost je, že aplikace na našem počítači vygeneruje nějaká data
a ty jsou poslána síťovým rozhraním směrem ven do sítě.
Cestování paketů jádrem popisuje následující obrázek:
Incoming -->[Routing ]----------------> Outgoing
[Decision] ^
v |
| |
| |
---> Local Process ---
Pro tvorbu pravidel se používá program
ipfw. Jednotlivá pravidla jsou očíslovaná od 1 do 65535. Pravidlo číslo 65535
je natvrdo nastaveno při kompilaci jádra, a to na implicitně vše zakázat.
Volbou IPFIREWALL_DEFAULT_TO_ACCEPT v konfiguračním souboru jádra můžeme
implicitně vše povolit.
Každý paket je porovnáván se seznamem pravidel a pokud paket vyhoví některému pravidlu,
je provedena akce spojená s pravidlem. IPFW podporuje také stavový filter, kdy pakety
jsou porovnávány proti záznamům ve stavové tabulce. Tedy na data procházející firewallem se
nepohlíží jako na jednotlivé pakety, ale jako na konexe. Pro každou konexi se vytvoří
dynamické pravidlo s omezenou životností a zapíše se do stavové tabulky.
Každé pravidlo v seznamu má následující čítače:
- čítač paketů prošlých daným pravidlem
- čítač bytů prošlých daným pravidlem
- čítač paketů prošlých daným pravidlem, které se logovaly
a časové razítko udávající, kdy naposledy paket vyhověl danému pravidlu.
Jednotlivé čítače lze zobrazit a také nulovat.
Dále pravidla lze združovat do množin a s množinami nakladat jako s celkem.
Množiny lze povolovat, zakazovat, prohazovat, přesouvat pravidla z jedné množiny
do druhé a samozřejmě mazat.
Zprovoznění IPFW
Máme dvě možnosti:
1) Zavést modul ipfw.ko do jádra
$ kldload ipfw
Pozor: jestliže zavádíte modul vzdáleně, je potřeba to udělat nějak takto:
$ kldload ipfw && ipfw add allow all from any to any
jinak si pod sebou podřežete větev...
2) Kompilací jádra s podporou IPFW
$ cd /usr/src/sys/i386/conf && vim JADRO
# podpora pro samotný IPFW
options IPFIREWALL
# IPv6 varianta
options IPV6FIREWALL
# logovaní paketů přes syslog, pokud nezkompilujete jádro s touto volbou a budete
# zadávat pravidla do IPFW s volbou log, pakety nebudou nikdy logovány.
options IPFIREWALL_VERBOSE
# IPv6 varianta
options IPV6FIREWALL_VERBOSE
# udává počet paketů logovaných přes syslog na každé pravidlo,
# přes syslog reporty (daily, weekly apod.) je možné zasílat info o tom,
# že byl dosažen limit logování paketů pro dané pravidlo
options IPFIREWALL_VERBOSE_LIMIT=N
# IPv6 varianta
options IPV6FIREWALL_VERBOSE_LIMIT=N
# implicitně povolí vše (bez této volby je implicitně vše zakázáno)
options IPFIREWALL_DEFAULT_TO_ACCEPT
# IPv6 varianta
options IPV6FIREWALL_DEFAULT_TO_ACCEPT
# umožní forwardovat pakety na jinou IP/port pomocí akce fwd příkazu ipfw
options IPFIREWALL_FORWARD
# umožní dělat NAT pomocí natd
options IPDIVERT
# zatajení firewallu před nmap (jádro ignoruje pakety s příznaky SYN+FIN),
# odstraňte pokud provozujete web server
options TCP_DROP_SYNFIN
# ICMP_BANDLIM umožní omezení šiřky pásma pro ICMP errory,
# většinou se používá pro ochránění před D.O.S
options ICMP_BANDLIM
# zatajení firewallu před traceroute
options IPSTEALTH
$ /usr/sbin/config JADRO
$ cd ../../config/JADRO
$ make depend
$ make
$ make install
$ reboot
Startovací skripty
/etc/rc.conf a možné volby
# zapnutí IPFW (sysctl -w net.inet.ip.fw.enable=1)
firewall_enable="YES"
# cesta k souboru s pravidly
firewall_script="/etc/rc.firewall"
# prednastavené firewally: open, client, simple, closed, custom
firewall_type="UNKNOWN"
# při "YES" se nebudou při bootu vypisovat pravidla
firewall_quiet="NO"
# zapne logování přes syslog (sysctl -w net.inet.ip.fw.verbose=1)
firewall_logging="YES"
# zapne forwardovaní mezi síťovými rozhraními (sysctl -w net.inet.ip.forwarding=1)
gateway_enable="YES"
# při nastavení čísla většího jak 0 se budou logovat spojení,
# které se pokoušely připojit na porty, na kerých neposlouchá žádný socket
log_in_vain="0"
# Nastavení na YES způsobí to, že jádro bude ignorovat TCP rámce, které mají
# nastaven SYN a FIN bit.
tcp_drop_synfin="NO"
# Nastavení na YES způsobí to, že jádro bude ignorovat ICMP REDIRECT pakety.
icmp_drop_redirect="NO"
# Nastavení na YES způsobí to, že jádro bude logovat ICMP REDIRECT pakety.
icmp_log_redirect="NO"
Výpis a mazání pravidel
výpis pravidel
$ ipfw list
výpis pravidel včetně časového razítka, kdy naposledy paket vyhověl danému pravidlu
$ ipfw -t list
výpis pravidel včetně čítačů
$ ipfw -a list
nebo
$ ipfw show
smazání pravidel
$ ipfw -f flush
Základní syntaxe
ipfw příkaz [číslo_pravidla] akce protokol from zdroj [zdrojový_port] to cíl [cílový_port] [[in/out] via interface]
příkazy:
- add
- delete
akce:
- allow | pass | permit = povolení paketu
- deny | drop = zahození paketu
- fwd | forward ipaddr[,port] = forwardování na ipaddr[:port]
- reset = zahození paketu a zaslání TCP paketu s RST bitem
- count = zvýší se čítače a pokračuje se dál
- unreach code = zahození paketu a zaslaní ICMP zprávy, kde code může být net, host, protocol, port, ...
- skipto číslo_pravidla = skok na dané číslo pravidla
Př.:
# zákaz všeho
ipfw add 1000 deny all from any to any
Specifikování protokolu
Protokoly: tcp, udp, icmp, ...
více viz. /etc/protocols
ipfw prikaz [číslo_pravidla] akce protokol from zdroj to cíl
Př.:
# povolení TCP odkudkoliv kamkoliv
ipfw add allow tcp from any to any
Specifikování zdrojové a cílové adresy
Zdrojové a cílové adresy můžeme zadávat jako jména nebo IP adresy. Pokud je protokol
TCP nebo UDP můžeme určit i číslo portu.
Př.:
ipfw add 1000 allow udp from myhost 1024-65535 to neco.cz 21
nebo
ipfw add 1100 allow tcp from 192.168.0.1 1024-65535 to any
rovnež můžeme používat i masku sítě
ipfw add 2000 allow all from 192.168.0.0/16 to any
ipfw add 2100 deny all from any to 10.0.0.0:255.0.0.0
nebo můžeme použít příkaz NOT
# zákaz všech paketů kromě pořítače s IP 192.168.0.3
ipfw add 1100 deny all from not 192.168.0.3
Specifikování portu
Zdrojové a cílové porty můžeme zadávat ve tvaru port, jako rozsah port_od-port_do nebo výčtem oddělým čárkami.
# povolení TCP na IP 192.168.0.5 a port 25
add 1000 allow tcp from any to 192.168.0.5 25
# povolení TCP na IP 192.168.0.5 a porty 1021-1023
ipfw add 1000 allow tcp from any to 192.168.0.5 1021-1023
# povolení TCP na IP 192.168.0.5 a porty 21,22,23
ipfw add 1000 allow tcp from any to 192.168.0.5 21,22,23
Interface a kontrola toku
# povolení všech paketů dovnitř
ipfw add 1000 allow all from any to any in
# povolení všech paketů ven
ipfw add 1000 allow all from any to any out
# povolení všech paketů dovnitř přes kterýkoliv interface
ipfw add 1000 allow all from any to any in via any
# povolení všech paketů dovnitř přes interface xl0
ipfw add 1000 allow all from any to any in via xl0
ICMP typy
icmptypes typ = pravidlu vyhoví ICMP pakety určitého typu.
Pokud je před icmptypes přidán '!', potom vyhovují všechny pakety, které
nejsou tohoto typu.
Je 15 typu ICMP:
0-Echo Reply
3-Destination Unreachable
4-Source Quench
5-Redirect
8-Echo Request
9-Router Advertisement
10-Router Silicitation
11-Time-to-Live Exceeded
12-IP header bad
13-Timestamp Request
14-Timestamp Reply
15-Information Request
16-Information Reply
17-Address Mask Request
18-Address Mask Reply
Př.:
# povolí pakety typu 8 (echo request) ven
ipfw add 1000 allow icmp from any to any out icmptypes 8
# povolí pakety typu 0 (echo reply) dovnitř
ipfw add 1100 allow icmp from any to any in icmptypes 0
# zakáže pakety typu 8 (echo request) dovnitř
ipfw add 1200 deny icmp from any to any in icmptypes 8
TCP flags, setup a established
tcpflags - tomuto pravidlu bude vyhovovat každý TCP paket, jehož hlavička obsahuje
jeden z následujícich příznaků.
Nebo pokud použijeme '!' pred tcpflags, budou vyhovovat všechny pakety, které
nemají flag nastaven. Tyto pravidla se dají použivat pouze u TCP.
FIN = požadavek na ukončení spojení
# SYN bit je posilan pri inicializaci spojeni = nazýváno v IPFW také setup
SYN = požadavek na inicializace spojení
RST = Reset konexe
PSH = Push Flag
# ACK bit je posílán při již probíhajícím spojení = nazýváno v IPFW také established
ACK = Acknowledgement
URG = Indicate Urgent OOB data
Př:
ipfw add deny tcp from any to any in tcpflags syn
je stejné jako
ipfw add deny tcp from any to any in setup
Fragmentované pakety
Pro detekci fragmentovaných paketů se používá možnost frag. Přijímání mnoha
fragmentovaných paketů způsobuje DoS (denial of services). Možnost frag
může být použita jenom v případě že:
1) není použito tcpflags
2) není použit TCP nebo UDP port
Př.:
# zakázání frag. paketů dovnitř
ipfw add deny all from any to any in frag
Logování
log = je logován každý paket, který vyhovuje pravidlu.
logamount číslo = tento parametr následuje za příkazem log. Určuje kolikrát
se budou pakety vyhovujicí konkretnímu pravidlu logovat. Po dosaženi určeného maxima
je logování zastaveno. Čítač se musí vynulovat, aby se mohlo logovat dále (ochrana před DOS).
Je-li číslo rovno nule, loguje se pořád bez omezení.
Př.:
# loguje prvních 100 paketů, které vyhovují tomuto pravidlu
ipfw add 1000 deny log loagmount 100 all from any to any
# loguje se kazdy paket, který vyhovuje pravidlu
ipfw add 1000 deny log loagmount 0 all from any to any
Pokud jsou pravidla logována jsou uvedeny v logu následující informace:
- datum a čas
- číslo pravidla
- akce
- zdrojová a cílová IP adresa
- zdrojový a cílový port
- zařízení, přes které paket přisel/odcházel
Př.:
Apr 27 01:18:58 ares /kernel: ipfw: 9900 Deny TCP 10.1.1.57:1027 10.1.1.1:445 in via fxp1
NAT
IPFW nemá přímo v sobě podporu pro NAT. K tomu účelu je zde démon natd, který překlad
adres obstarává. Poslouchá na portu 8668.
[root@ares root]# grep natd /etc/services
natd 8668/divert # Network Address Translation
V jádře je potřeba mít zaplou volbu IPDIVERT.
Př.:
# adresy se překladají na zařízení fxp0
ipfw add 40000 divert natd all from any to any via fxp0
nastavení v /etc/rc.conf
# má se spuštět natd
natd_enable="YES"
# rozhraní, na kterém se mají překládat adresy
natd_interface="fxp0"
# parametry, s kterými se spouští natd
# na rozhraní, na kterém se překládají adresy se port 5000 přesměruje na
# IP 10.1.1.53 port 22
natd_flags="-m -s -redirect_port tcp 10.1.1.53:22 5000"
Odkazy
IPFW manuál CZ
IPFW HOWTO
FreeBSD Handbook - firewall
ipfw - manuálové stránky
FreeBSD firewall
IPFW manuál
IPFW - psaní pravidel
IPFW logging
IPFW NAT HOWTO
natd - manuálové stránky