on.
# blokuojam visus įeinančius paketus iš localhost'o
block in on le0 from localhost to any
|
Tinklo mask'es ir host'ai
IPF palaiko šiuos tinklo mask'ių fromatus:
#
block in on le0 from mynet/26 to any
#
block in on le0 from mynet/255.255.255.192 to any
#
block in on le0 from mynet mask 255.255.255.192 to any
#
block in on le0 from mynet mask 0xffffffc0 to any
|
Galima naudoti bet kurį šių formatų, tačiau kaip taisykles generuoja programa
ipstat, naudoja patį trumpiausią variantą (t.y patį pirmą). Kada yra nenurodoma
mask'ė, tai pagal nutylėjimą naudojama 255.255.255.255 arba "/32" mask'ė.
Priešingai host'o arba tinklo reikšmei pridedame simbolį !, be
tarpo prieš vardą arba skaičių.
IP protokolas
Norint filtruoti tam tikru protokolu, reikia nurodyti jo vardą ir numerį:
# blokuojame visus įeinančius ICMP paketus
block in on le0 proto icmp all
|
Vardai arba skaičiai, esantys /etc/protocols, taip pat gali būti
naudojami.
# leidžiam visu protokolo 4 (ipencap) paketus
pass in on le0 proto 4 all
|
Yra viena išimtis: "tcp/udp". Jei protokolo vietoje nurodomas "tcp/udp", tai
bus tikrinami abu protokolai. Tai naudinga kaip reikia riboti priėjimą prie
port'o:
# blokuojame visus įeinančius paketus skirtus NFS
# pastaba: jei nenurodome protokolą, bet nurodome port'ą, tada vyksta taspats,
# t.y., tikrinami abu protokolai tcp ir udp.
block in on le0 proto tcp/udp from any to any port = 2049
|
IP opcijos
IP opcijas sudarantys paketai gali sukelti tinklo saugumo problemų. IP opcijos
naudojama kaip kurių programų, pavyzdžiui traceroute, tačiau
daugelyje atveju jos nereikalingos. Tam, kad nerizikuoti daugelis geriau
nepraleidinėja paketų su IP opcijomis.
Pastabos: Žiūrėti rfc791 - INTERNET PROTOCOL. Toli gražu ne visi
traceroute naudoja IP opcijas, jei jų papildomais flag'ais
nenurodyti, jie nebus naudojami.
IP opcijų blokavimas gali būti dvejopas. Pirmas būdas - drausti visus paketus su
bet kokiomis opcijomis naudojant ipopts.
# blokuojame ir loginame visus paketus turinčius IP opcijas.
block in log all with ipopts
|
Antras būdas - išvardinti opcijas, kurias norite filtruoti.
# blokuojame visus "source routing" paketus.
# Pastaba: jei jūs nurodysite abu "lsrr,ssrr", tai filtras blokuos tuos
# paketus, kurie turės abi šias opcijas.
block in quick all with opt lsrr
block in quick all with opt ssrr
|
Taip pat galima išrinkinėti paketus, neturinčius opcijų header'iuose.
Pavyzdžiui, leidžiam telnet jungimasi be IP opcijų. Pastaba: "Source
route" pagal nutylėjimą yra draudžiami:
$ sysctl net.inet.ip.sourceroute
net.inet.ip.sourceroute = 0
|
# leidžiami veiksmai telnet'ui iki tol kol nenaudoja IP opcijų.
pass in proto tcp from any to any port = 23 with no ipopts
# leidžiami paketai su "strict source routing", bet be "loose source routing".
pass in from any to any with opt ssrr not opt lsrr
|
IP fragmentai
IP fragmentai - bloga naujiena. Neseni tyrimai parodė, kad IP fragmentai kelia
didelį pavojų IP filtravimui, jei jie sudaro taisykles, kurios remiasi
duomenimis, kurie gali būti paskirstyti skersai fragmentams. Atsižvelgiant į
paketinį filtrą, pavojus yra tame, kad paketo lauko TCP flag'as gali būti
antrame arba trečiame fragmente, o gal net pirmame. Tam, kad išvengti
nemalonumų, galime atskirti tokius paketus:
# blokuojame visus IP fragmentus.
block in all with frag
|
Gali kilti problema, kai paketų fragmentacija nėra planuota, tačiau tai galima
spręsti taip:
# atsikratome visų trumpų IP fragmentų
block in proto tcp all with short
|
TCP/UDP port'ai
Filtravimas pagal port'o numerius veikia tik su TCP ir UDP protokolais. Jūs
galite naudoti skaičius arba vardus esančius /etc/services. Kada
taisyklėse naudojamas raktinis žodis proto, jis bus naudojamas su
port'o vardu, kuriam ras atitikmenį pagal port'o numerį. Galimos variacijos su
port'ų numeriais:
Operat. Alias'as Paramtr. Resultatas
--------------------------------------------------------------------------------------------
< lt port# teisingai, jei portas mažesnis, reikšmė perduodama
> gt port# teisingai, jei portas didesnis, reikšmė perduodama
= eq port# teisingai, jei portas lygus, reikšmė perduodama
!= ne port# teisingai, jei portas nelygus, reikšmė perduodama
<= le port# teisingai, jei portas mažesnis arba lygus, reikšmė perduodama
=> ge port# teisingai, jei portas didesnis arba lygus, reikšmė perduodama
|
# leidžiam TCP paketus iš to paties potinklio ir host'o foo į host'ą 10.1.1.2,
# jei jie skirti 6667 port'ui.
pass in proto tcp from fubar/24 to 10.1.1.2/32 port = 6667
# leidžiam UDP paketus einančius ne iš 53-čio port'o ir skirtus localhost'ui.
pass in proto udp from fubar port != 53 to localhost
|
Taip pat galimas dviejų diapazonų palygynimas (sintaksė):
port1# <> port2# teisingai, jei portas mažesnis už port1 ir didesnis už port2
port1# >< port2# teisingai, jei portas didesnis už port1 ir mažesnis už port2
|
Atkreipkite dėmesį, kad yra sutapimas kaip port'as bus lygus vienai iš divejų
reikšmių, abiejose pavyzdžiuose.
# blokuojame visus įeinančius paketus į jūsų X'sus (nuo X:0 iki X:9).
block in proto tcp from any to any port 5999 >< 6010
|
# leidžiam bet kokį prisijungimą, išskryrus BSD print/r-servisus, tai taip pat
# blokuos ir syslog'ą.
block in proto tcp/udp all
pass in proto tcp/udp from any to any port 512 <> 515
|
Visa tai galima daryti ir atvirkščiai. Pradžioje leidžiam visus port'us, o po
to draudžiam reikiamą diapazoną. Atkreipkit dėmesį kaip keičias port'ų
numeriai.
pass in proto tcp/udp all
block in proto tcp/udp from any to any port 511 >< 516
|
ICMP tipai/kodai
ICMP gali būti administratoriaus problemų šaltinis. Visų ICMP blokavimas gali
būti naudingas, tačiau jūs blokuojate ir naudingų programų darbą, tokių kaip
ping. ICMP paketų filtravimas leis dirbti su ping'u.
# blokuojame visus ICMP paketus.
block in proto icmp all
# leidžiam ICMP "echos" ir "echo-replies" paketus.
pass in on le1 proto icmp from any to any icmp-type echo
pass in on le1 proto icmp from any to any icmp-type echorep
|
Skaičiai yra naudojami ICMP reikšmėms priskirti. Tarkim jūs norite blokuoti
visus "port-unreachables":
# blokuojame visus ICMP "destination unreachable" paketus
block in on le1 proto icmp from any to any icmp-type unreach code 3
|
TCP flag'ai
TCP flag'ų filtravimas yra naudingas, tačiau pas jus gali kilti problemų. Prieš
naudojant tokius filtrus savo taisyklėse rekomenduotina susipažinti su
atitinkama dokumentacija. Filtras seka kiekvieną TCP flag'ą pakete ir jei reikia
sulygina su IP filter taisyklėmis. Kaip kurie paketų filtrai leidžia filtruoti
TCP paketus jau susijungus ("established"). Kitaip tariant paketų su ACK bitu
filtracija. ACK bitas naudojamas sujungti ir baigti susijungimą. Pavyzdžiui pas
jus tokia taisyklė:
allow proto tcp 10.1.0.0 255.255.0.0 port = 23 10.2.0.0 255.255.0.0 established
|
Dabar galime rašyti taip:
pass in proto tcp 10.1.0.0/16 port = 23 10.2.0.0/16 flags A/A
pass out proto tcp 10.1.0.0/16 port = 23 10.2.0.0/16 flags A/A
|
Didesnė nauda yra filtruoti SYN flag'ą TCP susijungimuose. Šis flag'as būna
inicijuojant TCP susijungimą. Visuose kituose atvejuose ACK flag'as arba
kartais URG/PUSH papildomi flag'ai pakete. Todėl jei norite uždaryti bet kokius
susijungimus su mūsų lokaliu tinklu (10.1.0.0) iš išorės, reiktų daryti taip:
# blokuojame įeinačius susijungimus į vidinį tinklą iš išorės
block in on le0 proto tcp from any to 10.1.0.0/16 flags S/SA
|
Jei norite blokuoti atsakymus į susijungimus, darom taip (kada yra SA flag'as,
reiškia SYN-ACK taip pat nustatytas):
block out on le0 proto tcp from 10.1.0.0 to any flags SA/SA
|
Flag'ai po "/" reiškia TCP flag'o mask'ę, kurie parodo TCP flag'o bitus, pagal
kuriuos ir vykdoma filtracija. Kada naudojate SYN bitą jums būtinai reikia
nurodyti mask'ę, tam kad jūsų filtras nebūtų "nugalėtas" paketo su SYN ir URG
flag'ais.
Atsakymai į blokuotus paketus
Kam kad atsakyti į siunčiamus, per jūsų filtrą, blokuotus paketus, galite
siųsti ICMP klaidą (Destination Unreachable) arba atsakydami į TCP paketą TCP
RST (Reset).
Koks skirtumas? TCP/IP stirtai (stacks) reikia daugiau laiko persiųsti ICMP
klaidas viso užklausimo laikotarpyje, dėl laikinų problėmų (tinklas laikinai
buvo atjungtas), atsiranda galimybė neteisingai užbaigti susijungimą. Kitas
scenarijus iškviečia susijungimo užbaigimą tarp dviejų kompiuterių, kuriam buvo
skirta ICMP klaida. TCP RST naudojama vienai užklausai (tik vienam
susijungimui, negali būti naudojamas keliems), filtras iškart uždaro
susijungimą. Pavyzdžiui, jūs blokuojate 113 port'ą ir atsakymui
nurodote TCP RST paketą, ICMP paketą arba net nieko nenurodote,
nepajusite jokio užlaikymo, net jei "antras galas" darė užklausą i jūsų
identd servisa:
# blokuojam visas TCP užklausas į ident port'ą su atsakymu TCP-RST.
block in proto tcp from any to any flags S/SA
block return-rst in quick proto tcp from any to any port = 113 flags S/SA
|
# blokuojam visus UDP paketus ir grąžinam ICMP klaidą
block return-icmp in proto udp from any to any
|
Kada grąžinate ICMP klaidą, galite nurodyti ir ICMP tipą. Tai gali būti
reikalinga traceroute komandos elegantiškam užbaigimui. Todėl nurodome
ICMP tipą Unreachable skliausteliuose, po komandos "return-icmp":
# blokuojam visu įeinančius UDP paketus ir grąžinam ICMP klaidą.
block return-icmp (3) in proto udp from any to any port > 30000
block return-icmp (port-unr) in proto udp from any to any port > 30000
|
Šie abu pavyzdžiai ekvivalentūs, ir rodo "Port unreachable" klaidą atsakydami į
visas UDP užklausas einančias į portus didesnius už 30000.
IP saugumo klasės
Yra galimybė filtruoti paketus pagal IP security bitą, taip pat įvairias klases
ir autorizacijos lygius. Einamuoju momentu filtravimas pagal 16-bit'inį
autorizacijos flag'ą nėra realizuojamas. Kaip ir kitos IP savybės, ipopts galima
naudoti reversineme režime, t.y. nustatynėti paketus, jei nėra tamtikros klasės.
Kaip kurie pavyzdžiai pagal IP saugumo savybes:
# blokuojame visus paketus be IP saugumo savybių.
block in all with no opt sec
|
# leidžiame įeinančius ir išeinančius paketus turinčius "top secret" savybes.
block out on le1 all
pass out on le1 all with opt sec-class topsecret
block in on le1 all
pass in on le1 all with opt sec-class topsecret
|
Keep-state filtravimas
Keep-state filtravimas gali būti naudojamas bet kokiam TCP srautui, su galimybe
nutraukti filtravimą ateityje. Duomenys apie susijungimus yra laikomi lentelėje
ir nekeičia firewall taisyklių. Paketai yra tikrinami ar atitinką esamiems TCP
protokolams. Jei paketas priklauso nustatytam TCP sujungimui, tai tolimesnis
taisyklių tikrinimas yra nutraukiamas ir paketas praleidžiamas. TCP srautui
filtras seka ACK/SEQ (ack/sequence) skaičių eiliškumą paketo antraštėje (header),
ir praleis tik korektiškus paketus.
# palikti įrašą lentelėje visoms įšeinančioms telnet jungtims ir drausti kitą
# išeinantį srautą.
pass out on le1 proto tcp from any to any port = telnet keep state
block out on le1 all
|
UDP srautui, paketų apsikeitimas yra efektyvus ir be būsenos išsaugojimo. Bet
jei paketas pirmą kartą pasiųstas iš tam tikro port'o, tai atsakymas paprastai
laukiamas atgalinę kryptimi.
# leidžiam UDP atsakymus į DNS serverį.
pass out on le1 proto udp from any to any port = domain keep state
|
Išlaikymas UDP būsenos jungčių yra limituotas laiku taip pat kaip ir TCP
jungčių, kurios pridedamos į lentelę be SYN flag'o. Jeigu būsenų lenteleje įrašas
padarytas su SYN flag'u, tai sekantys po šiuo įrašu patekia paketai, neturintys
šito flag'o (tame tarpe SYN-ACK), bus išsaugoti lentelėje "amžinai" (timeout'as pagal
nutylėjimą lygus 5 dienoms), iki tol kol neatsiras paketas su FIN ar RST flag'u.
Network Address Translation (NAT'as)
Network Address Translation naudojamas tada, kaip reikia perkelti (remap) vieną
IP adresų diapazoną į kitą tinklinių adresų diapazoną. TCP ir UDP protokolams galima pridėti
ir port'o numerį. Perkeliamas paketas sudarantis IP-adresą/port'o-numerį, tada
kai palieką interfeisą ir kai IP filter patikrina jį su NAT taisyklėmis. Paketai
grąžinami į tą patį interfeisą kuriame buvo perkelti, ir savaime suprantama, su
originalių adresų informacija.
# perkeliam visas TCP jungtis iš 10.1.0.0/16 į 240.1.0.1, keičiant jų pradinį
# port'o numerį į kažkokį tarp 10000 ir 20000 imtinai. Visiems kitiems paketams
# laikinai išskirti naują IP adresą tarp 240.1.0.0 ir 240.1.0.255 kiekvienam
# naujam vartotojui. Šiame pavyzdyje ed1 - vidinis interfeisas. Naudokite
# ipnat, o ne ipf komandą taisyklėms pakrauti.
map ed1 10.1.0.0/16 -> 240.1.0.1/32 portmap tcp 10000:20000
map ed1 10.1.0.0/16 -> 240.1.0.0/24
|
Permatomo Proxy palaikymas
Transparent Proxy yra atliekamas paketų permetimas, panašiai kaip ir NAT
technologija, išskyrus tai, kad taisyklės yra keliamos įeinačių paketų.
Srauto perkelimui nautokite ipnat (kaip ir NAT'ui) vietoje ipf.
# permetimas dirba nuo įeinančių paketų.
# pavyzdžiui, permetam FTP jungtis per šitą kompiuterį (šitam pzv. ed0 -
# interfeisas kuris yra nurodytas default rounting'o) į lokalų FTP
# port'ą, susijungimas per proxy.
rdr ed0 0.0.0.0/0 port ftp -> 127.0.0.1 port ftp
|
Permatomas routing'as
Naudojamas IP filter, permatomą proxy galima padaryti dviem būdais. Pirmas -
naudoti komadą fastroute standartinėse routing'o taisyklėse, arba naudoti
fiksuotą rounting'ą komandos to pagalba. Abu permatomo routing'o
pavyzdžiai neiškviečia TTL reikšmės sumažėjimo, kada paketas eina per
branduolį.
# route (rojtinti) visus UDP paketus permatomai
pass in quick fastroute proto udp all
# route visus ICMP paketus ant le0 per le1 į "router"
pass in quick on le0 to le1:router proto icmp all
|
Paketų loginimas per tinklo interfeisą
Paketų loginimas per tinklo interfeisą yra palaikomas visiems paketams, kurie
buvo praleisti arba blokuoti. Praleistiems paketams naudojama komanda
dup-to, o blokuotiems galima naudoti to (didesnis
efektingumas), arba dup-to. Tam, kad loginti per interfeisą be ARP,
sukurkite statinį įrašą ARP-keše bevardžiui IP adresui (tarkime 10.0.0.1) ir
loginame per šitą IP.
# loginame visu short-TCP paketus per q3 su "packetlog", kaip paketų paskirties
# punktas
block in quick to qe3:packetlog proto tcp all with short
# loginti visas TCP jungtis
pass in quick on ppp0 dup-to le1:packetlog proto tcp all flags S/SA
|
Taisyklių grupės
Didesniam taisyklių apdirbimo efektingumui, galime apjungtis jas į grupes.
Pagal nutylėjimą visos taisyklės yra 0 grepės. Nulinė grupė yra "tevų" grupe
visoms likusioms. Naujos grupės organizavimui užtenka nurodyti komanda head:
# apdirbam visus įeinančius ppp paketus per ppp0 interfeisą 100 grupė,
# pagal nutilėjimą blokuot viską per šį interfeisą.
block in quick on ppp0 all head 100
|
Jei po to norėsit leisti priėjimą prie jūsų WWW server'io per ppp0, galite
pridėti tik taisyklę apie WWW. Atkreipkite dėmesį, kad tik paketai sutampantis
su aukščiau esančiomis taisyklėmis, bus pateikti 100 grupes taisyklėms.
# leidžiam priėjimą prie savo WWW server'io per ppp0
pass in quick proto tcp from any to any port = WWW keep state group 100
|