Další pravidla IPF
Odpovědi na blokovaný paket
V pravidlech v minulém dílu jsme se vůbec nevěnovali ICMP protokolu, man 4 icmp
. Používá jej například ping
nebo traceroute
. Často je však ICMP protokol využíván i k DoS útokům. V případě, že byste se neobešli bez těchto příkazů přicházejících zvenku na vaše síťová rozhraní, přidejte k ipf.rules
tato pravidla (jedná se o problém typu bezpečnost vs. uživatelské pohodlí, více o ICMP protokolu zde):
pass in quick on lnc0 proto icmp from any to 10.0.0.4/32 icmp-type 0 group 10
pass in quick on lnc0 proto icmp from any to 10.0.0.4/32 icmp-type 8 group 10
ICMP protokol se využívá i jako odpovědi na blokovaný paket. Bez takové odpovědi – RST (reset) paketu – dostane klient Connection/Operation timed out
. Díky RST paketu klient získá Connection refused
, my tím lehce ušetříme síťový provoz.
block return-rst in log on lnc0 proto tcp from any to 10.0.0.4/32 port = 22
Tento řádek by však blokoval nežádoucí spojení pouze pro TCP protokol, proto pro UDP je volba tato:
block return-icmp-as-dest(port-unr) in log on lnc0 proto udp from any to 10.0.0.4/32 port = 22
Stavové UDP a ICMP
V našich pravidlech máme pass out quick from any to any keep state keep frags
. V případě, že byste chtěli definovat pravidla pro každý protokol a službu zvlášt, IPFilter rovněž umožňuje použití keep state
i pro tyto protokoly. Povídání najdete v /usr/share/examples/ipfilter/ipf-howto.txt
.
Skupiny IPF
Dle pravidel z minulého dílu by byl například příchozí paket porovnáván i s předcházejícími pravidly pro odchozí spojeni. Optimalizovat procházení pravidel můžeme pomocí skupin. Paket splňující pravidlo pro určitou skupinu bude dále porovnáván jen s dalšími pravidly téže skupiny. Příklad:
block out on lnc0 all head 1
#block out quick from 192.168.1.0/24 to any group 1
block out quick from any to 0.0.0.0/7 group 1
block out quick from any to 2.0.0.0/8 group 1
block out quick from any to 5.0.0.0/8 group 1
...zkráceno...
pass out quick from any to any keep state keep frags group 1
Paket, který narazí na pravidlo block out on lnc0 all head 1
, tedy na pravidlo určující skupinu 1
( head 1
), bude dále porovnáván jen s pravidly náležejícími této skupině – tedy s těmi, která obsahují na konci řádku group 1
. Díky této skupině nebudou tedy přicházející pakety porovnávány s předešlými pravidly pro odchozí spojení, tj. tato pravidla budou zcela ignorována.
Můžeme využít samozřejmě i podskupiny, například pro příchozí ssh. Za skupinová pravidla pro inbound spojení tedy můžeme dát např.:
block return-rst in log proto tcp from any to 10.0.0.4/32 port = 22 head 11 group 10
pass in log quick proto tcp from 10.0.0.100/32 to 10.0.0.4/32 flags S keep state group 11
Vytvořili jsme podskupinu 11, která, jak naznačuje první řádek, je součástí skupiny 10. Pravidlo pro skupinu 11, tedy pokud nebude řečeno jinak, bude blokoval/logovat spojení na uvedenou IP adresu s cílem portu 22 a pošle zpět RST paket. V případě, že bude spojení navazováno z 10.0.0.100/32, bude povoleno. Kreativitě se meze nekladou.
Logování IPF
Pravidla logovaná pomocí log čte program ipmon
z /dev/ipl
a může je předat na stdout
, uložit do souboru nebo předat logovacímu démonu. Jestliže jste neměli nastaveno spouštění ipmon
v rc skriptu, můžete jej spustit i nyní:
ipmon -D /var/log/ipf.log - v případě logování do souboru
ipmon -Ds - v případě logování přes syslog
V případě logování přes syslogd budete muset upravit /etc/syslog.conf
(rovněž i rotování logů), defaultně má příslušnost – facility – local0.
local0.* /var/log/ipf.log
IPF přichází i s možností změnit řetězce pro logovacího démona pomocí level
. Příklad:
block return-rst in log level auth.alert proto tcp from any to 10.0.0.4/32 port = 22 head 11 group 10
srot# tail /var/log/auth.alert
Sep 13 06:20:59 srot ipmon[56]: 06:20:58.808143 lnc0 @10:28 b 10.0.0.1,3996 -> 10.0.0.4,22 PR tcp len 20 60 -S IN
Monitorování IPFilteru
Během laborování s pravidly pravděpodobně uděláte někde nějakou chybu. Na syntaktickou vás upozorní již ipf při nahrávání nových pravidel. V situaci, když nevíte, jak např. zjistit, které pravidlo vám blokuje provoz, můžete využít některé z balíků nástrojů IPF.
Na dočasnou statistiku IPF můžete použít program ipfstat
.
srot# ipfstat
IPv6 packets: in 0 out 0
input packets: blocked 86 passed 28919 nomatch 913 counted 0 short 0
output packets: blocked 0 passed 27191 nomatch 1415 counted 0 short 2
input packets logged: blocked 83 passed 1890
output packets logged: blocked 0 passed 1895
packets logged: input 0 output 0
log failures: input 0 output 0
fragment state(in): kept 0 lost 0
fragment state(out): kept 0 lost 0
packet state(in): kept 10 lost 0
packet state(out): kept 93 lost 6
ICMP replies: 0 TCP RSTs sent: 3
Invalid source(in): 0
Result cache hits(in): 4375 (out): 2271
IN Pullups succeeded: 0 failed: 0
OUT Pullups succeeded: 2053 failed: 0
Fastroute successes: 3 failures: 0
TCP cksum fails(in): 0 (out): 0
Packet log flags set: (0)
none
Bez dodatečných voleb vám ukáže ipfstat
statistiku povolených/bloklých nebo logovaných paketů atd.
Pomocí ipfstat -i/o
můžete prohlédnout vaše aktuální pravidla. V případě, že přidáte -h
( ipfstat -hi/ho
), bude přidáno počítadlo paketů náležejících určitému pravidlu.
Dalším důležitým přepínačem je -n
, resp. -ni/no
. V případě, že najdete záznam v lozích ohledně nějakého např. zablokovaného paketu, můžete lehce zjistit syntaxi příslušného pravidla. Nejprve záznam z logu:
Sep 13 05:21:41 srot ipmon[56]: 05:21:40.983971 lnc0 @10:28 b 10.0.0.1,3195 -> 10.0.0.4,22 PR tcp len 20 60 -S IN
srot# ipfstat -ni | grep @28
@28 block return-rst in log proto tcp from any to 10.0.0.4/32 port = 22 head 11 group 10
Vidíme, jak vypadá pravidlo, které nám zablokovalo přicházející spojení. Další volbou, které vás může zajímat, je -s
zobrazující aktuální stavovou tabulku IPF.
NAT s pomocí IPF
Často se NAT využívá v situaci, kdy je omezena možnost použití více veřejných IP adres. Např. můžete mít od ISP přidělenu jednu veřejnou IP adresu (tu máte na externím rozhraní vaší brány), dále máte místní síť více počítačů s neveřejnými-privátními IP adresami (např. 192.168.1.0/24). Stroje v LAN jsou tedy zvenku nedostupné, poněvadž se nejedná o veřejné adresy, stejně jako nemůže být váš stroj zvenku dosažen na své privátní adrese. Proto je potřeba NAT na brány k přepisu odchozích IP adres vašich paketů na veřejnou IP adresu vašeho externího rozhraní. Tento překlad síťových adres, NAT, v Linuxu označovaný jako maškaráda, řídí v IPFilteru konfigurační soubor /etc/ipnat.rules
a obslužný program ipnat
. Pravidla se tedy přidávají do ipnat.rules
:
map lnc0 192.168.1.2/32 -> 10.0.0.4/32
Toto pravidlo bude přepisovat zdrojovou IP adresu v paketech za IP adresu na externím rozhraní.
V případě, že byste chtěli poskytnout nějakou vnitřní službu, jež je, jak bylo řečeno, kvůli privátní IP adrese zvenku nedosažitelná, můžete přesměrovat požadavek na nějakou IP adresu/port ve vaší LAN.
rdr lnc0 10.0.0.4/32 port 2222 -> 192.168.1.2 port 22
Tedy požadavek na 10.0.0.4:2222 bude přesměrován na stroj v LAN a port 22. Pravidla ipnat
načteme tedy např. takto:
srot# ipnat -f /etc/ipnat.rules && ipnat -l
List of active MAP/Redirect filters:
map lnc0 192.168.1.2/32 -> 10.0.0.4/32
rdr lnc0 10.0.0.4/32 port 2222 -> 192.168.1.2 port 2222 tcp
List of active sessions:
Zkuste se připojit na přesměrovaný port a zkuste znova ipnat -l
.
Tipy na práci s IPF
IP Filter/IP Nat/PPPoE DSL and DHCP Server setup script
Existuje skript, který vám má ulehčit nastavování pravidl pro IPFilter. Nachází se zde a má pomáhat s pravidly, NAT a je přizpůsoben i pro ADSL uživatele. Část skriptu:
######################################################### Do you want statefull firewall or just allow everything and rely on IPNAT to protect you, I recommend firewalling :) Choose: "y" for statefull firewall or "n" for allow everything ######################################################### y #########################################################
IPFmeta
Pomocí portu ipfmeta
, který se nachází v /usr/ports/security/ipfmeta
, můžete v ipf.rules
používat objekty. Můžete si vytvořit vlastní zkratky nebo pojmenování pro sítě atd. (podrobnosti).
PF
S FreeBSD 5 přichází i možnost používat PF původně vyvinutý na OpenBSD. PF přináší několik výhod, které IPFilter nemá, např.:
-
seznamy – dovoluje použít podobná kritéria v jednom pravidle
block out on fxp0 from { 192.168.0.1, 10.5.32.6 } to any
-
makra – uživatelsky definované proměnné
tcpudp = "{tcp, udp }" internal="rl0" trusted = "{ 10.0.0.1, 10.0.0.2, 10.0.0.10 }" pass in on $internal inet proto $tcpudp from $trusted to $myserver port 80
- tabulky – specifikování skupiny IP adres. Výhodné např. pro neroutovatelné sítě.
- fronty – specifikování pořadí zpracování paketů
Zařazení PF do FreeBSD je velmi vítáno. Na téma PF se podívejte na stránkách OpenBSD.cz.
Naše aktuální pravidla
block in log quick from any to any with ipopts
block in log quick proto tcp from any to any with short
pass in quick on lo0 all
pass out quick on lo0 all
block out on lnc0 all head 1
#block out quick from 192.168.1.0/24 to any group 1
block out quick from any to 0.0.0.0/7 group 1
block out quick from any to 2.0.0.0/8 group 1
block out quick from any to 5.0.0.0/8 group 1
#block out quick from any to 10.0.0.0/8 group 1
block out quick from any to 23.0.0.0/8 group 1
block out quick from any to 27.0.0.0/8 group 1
block out quick from any to 31.0.0.0/8 group 1
block out quick from any to 69.0.0.0/8 group 1
block out quick from any to 70.0.0.0/7 group 1
block out quick from any to 72.0.0.0/5 group 1
block out quick from any to 82.0.0.0/7 group 1
block out quick from any to 84.0.0.0/6 group 1
block out quick from any to 88.0.0.0/5 group 1
block out quick from any to 96.0.0.0/3 group 1
block out quick from any to 127.0.0.0/8 group 1
block out quick from any to 128.0.0.0/16 group 1
block out quick from any to 128.66.0.0/16 group 1
block out quick from any to 169.254.0.0/16 group 1
block out quick from any to 172.16.0.0/12 group 1
block out quick from any to 191.255.0.0/16 group 1
block out quick from any to 192.0.0.0/19 group 1
block out quick from any to 192.0.48.0/20 group 1
block out quick from any to 192.0.64.0/18 group 1
block out quick from any to 192.0.128.0/17 group 1
block out quick from any to 192.168.0.0/16 group 1
block out quick from any to 197.0.0.0/8 group 1
block out quick from any to 201.0.0.0/8 group 1
block out quick from any to 204.152.64.0/23 group 1
block out quick from any to 206.112.0.0/16 group 1
block out quick from any to 224.0.0.0/3
pass out quick from any to any keep state keep frags group 1
block in log on lnc0 from any to any head 10
block in quick from 0.0.0.0/7 to any group 10
block in quick from 2.0.0.0/8 to any group 10
block in quick from 5.0.0.0/8 to any group 10
#block in quick from 10.0.0.0/8 to any group 10
block in quick from 23.0.0.0/8 to any group 10
block in quick from 27.0.0.0/8 to any group 10
block in quick from 31.0.0.0/8 to any group 10
block in quick from 69.0.0.0/8 to any group 10
block in quick from 70.0.0.0/7 to any group 10
block in quick from 72.0.0.0/5 to any group 10
block in quick from 82.0.0.0/7 to any group 10
block in quick from 84.0.0.0/6 to any group 10
block in quick from 88.0.0.0/5 to any group 10
block in quick from 96.0.0.0/3 to any group 10
block in quick from 127.0.0.0/8 to any group 10
block in quick from 128.0.0.0/16 to any group 10
block in quick from 128.66.0.0/16 to any group 10
block in quick from 169.254.0.0/16 to any group 10
block in quick from 172.16.0.0/12 to any group 10
block in quick from 191.255.0.0/16 to any group 10
block in quick from 192.0.0.0/19 to any group 10
block in quick from 192.0.48.0/20 to any group 10
block in quick from 192.0.64.0/18 to any group 10
block in quick from 192.0.128.0/17 to any group 10
#block in quick from 192.168.0.0/16 to any group 10
block in quick from 197.0.0.0/8 to any group 10
block in quick from 201.0.0.0/8 to any group 10
block in quick from 204.152.64.0/23 to any group 10
block in quick from 224.0.0.0/3 to any group 10
block return-rst in log level auth.alert proto tcp from any to 10.0.0.4/32 port = 22 head 11 group 10
pass in log first quick proto tcp from 10.0.0.100/32 to 10.0.0.4/32 flags S keep state group 11
block return-rst in log proto tcp from any to 10.0.0.4/32 group 10
block return-icmp-as-dest(port-unr) in log proto udp from any to 10.0.0.4/32 group 10
Závěr
Nastavení fw je velmi složitý problém. Pokusil jsem se jej trochu nastínit, pro další podrobnosti prosím nahlédněte do /usr/share/examples/ipfilter/ipf-howto.txt
nebo do man 5 ipf
. V dalšími dílu se podíváme na tolikrát zmiňované jaily.