traducere ver. 0.2 de catre Riddl Documentul a fost tradus intr-un ritm foarte alert. Nu este o traducere profesionala. Deasemenea nu este o traducere mot-a-mot. Am incercat sa respect versiunea originala. Multumiri lui Gushterul. Daca gasiti greseli sau aveti obervatii dati-mi un mail pentru Riddl la "discutii at gmx dot net". Nu uitati sa precizati numele documentului. Multumesc anticipat. Pentru ultima versiune a acestei traduceri verifica . Lecturare placuta! ______________________________________________________________________ Rusty Russell v1.0.8, Tue Jul 4 14:20:53 EST 2000 Acest document descrie cum sa obtii, instalezi si configurezi software-ul ipchains pentru realizarea de firewall sub Linux, precum si cateva posibilitati de folosire al acestuia. ______________________________________________________________________ Cuprins 1. Introducere 1.1. La ce foloseste? 1.2. De ce? 1.3. Cum? 1.4. De unde? 2. Bazele teoretice ale filtrarii de pachete 2.1. La ce foloseste? 2.2. De ce? 2.3. Cum? 2.3.1. Un kernel ce are compilat suport pentru filtrare de pachete 2.3.2. ipchains 2.3.3. Crearea regulilor permanente 3. Sunt derutat! Rutare, masqueradare, forwardare de pachete, ipautofw.... 3.1. Ghidul de trei linii al lui Rusty privind masqueradarea 3.2. Promovare gratuita: regulile WatchGuard 3.3. Firewall-uri obisnuite 3.3.1. Retea privata: Proxy-uri traditionale 3.3.2. Retea privata: Proxy-uri transparente 3.3.3. Retea privata: Masquerading 3.3.4. Retea publica 3.3.5. Servicii interne limitate 3.4. Mai multe informatii despre masquerading 4. Filtrul de pachete 4.1. Cum travereseaza pachetele filtrele 4.1.1. Folosirea ipchains 4.1.2. Ce vei vedea cand porneste computerul 4.1.3. Operatii pentru o singura regula 4.1.4. Optiuni de filtrare 4.1.4.1. Specificarea adreselor IP sursa si destinatie 4.1.4.2. Specificarea inversa 4.1.4.3. Specificarea protocolului 4.1.4.3.1. Specificarea porturilor TCP si UDP 4.1.4.3.2. Specificarea tipului si codului ICMP 4.1.4.4. Specificarea interfetei 4.1.4.5. Specificarea doar a pachetelor TCP SYN 4.1.4.6. Despre fragmente 4.1.5. Efectele filtrarii de pachete 4.1.5.1. Specificarea unei tinte 4.1.5.2. Logarea pachetelor 4.1.5.3. Schimbarea tos (type of service) 4.1.5.4. Marcarea unui pachet 4.1.5.5. Operatii pentru un chain 4.1.5.6. Crearea unui chain nou 4.1.5.7. Stergerea unui chain 4.1.5.8. Stergerea tuturor regulilor unui chain 4.1.5.9. Listarea regulilor unui chain 4.1.5.10. Resetarea (aducerea la 0) a counter-elor 4.1.5.11. Setarea policy-ului 4.1.6. Operatii pentru masquerading 4.1.7. Verificarea unui pachet 4.1.8. Mai multe reguli dintr-o data si ceea ce se intampla atunci 4.2. Exemple folositoare 4.2.1. Folosirea ipchains-save 4.2.2. Folosirea ipchains-restore 5. Diverse 5.1. Cum sa iti organizezi regulile firewall-ului 5.2. Ce anume sa nu filtrezi spre afara 5.2.1. Pachete icmp 5.2.2. Conexiunile TCP catre servere DNS (servere de nume) 5.2.3. FTP 5.3. Filtrarea Pingului Mortii 5.4. Filtrarea pentru Teardrop si Bonk 5.5. Filtrarea fragmentelor in masa 5.6. Schimbarea regulilor din firewall 5.7. Cum realizez protectia impotriva spoofarii IP 5.8. Proiecte mai avansate 5.8.1. SPF: filtrare dupa starea pachetului (stateful packet filtering) 5.8.2. "Hack-ul" ftp-data al lui Michael Hasenstein 5.9. Planuri de viitor 6. Probleme des intalnite 6.1. ipchains -L ingheata! 6.2. Specificarea inversa nu poate fi realizata! 6.3. Masqueradarea/Forwardarea nu se realizeaza! 6.4. Tinta -j REDIR nu merge! 6.5. Specificare mai multor interfete (ex "-i ppp+") nu merge! 6.6. TOS nu merge! 6.7. ipautofw si ipportfw nu merg! 6.8. xosview este stricat! 6.9. Segmentation Fault din cauza tintei "-j REDIRECT"! 6.10. Nu pot preciza valori de timeout pentru masquerading! 6.11. Vreau sa filtrez IPX! 7. Un exemplu serios 7.1. Topologia retelei 7.2. Scopurile 7.3. Inainte de realizarea filtrarii de pachete 7.4. Filtrarea de pachete pentru pachetele directe 7.4.1. Trecerea spre alte chain-uri din chain-ul forward 7.4.2. Definirea chain-ului icmp-acc 7.4.3. Reguli pentru conexiuni reteaua interna ==> DMZ (servere) 7.4.4. Reguli pentru conexiuni din reteaua externa ==> DMZ (servere) 7.4.5. Reguli pentru conexiuni din reteaua interna ==> reteaua externa 7.4.6. Reguli pentru conexiuni din DMZ ==> reteaua interna 7.4.7. Reguli pentru conexiuni din DMZ ==> reteaua externa 7.4.8. Reguli pentru conexiuni din reteaua externa ==> reteaua interna 7.4.9. Filtrul de pachete pentru insusi sistemul care este ruter 7.4.9.1. Interfata catre reteaua externa 7.4.9.2. Interfata catre reteaua de servere (DMZ) 7.4.9.3. Interfata catre reteaua interna 7.5. In final 8. Anexa: Diferente intre ipchains si ipfwadm 8.1. Tabel pentru informare rapida 8.2. Exemple de comenzi ipfwadm translatate in ipchains 9. Anexa: Folosirea scriptului ipfwadm-wrapper 10. Anexa: Multumiri. 10.1. Traduceri ______________________________________________________________________ 1. Introducere Aceste este IPCHAINS-HOWTO pentru Linux; citeste capitolul "De unde?" pentru site-ul principal care contine ultima veriune. Ar trebui sa citesti deasemenea NET-3-HOWTO. IP-Masquerading HOWTO, PPP-HOWTO, Ethernet-HOWTO si Firewall HOWTO ar fi deasemenea interesante de citit (la fel ar putea sa fie intesante si FAQ-ul alt.fan.bigfoot). Daca filtrarea de pachete este ok pentru tine, citeste sectiunea "De ce?", sectiunea "Cum?", si citeste printre randuri sectiunea "Reguli pentru firewall". Daca faci trecerea de la ipfwadm, citeste sectiunea "Introducere","Cum?", anexa "Diferente intre ipchains si ipfwadm" si sectiunea "Folosirea scriptului ipfwadm-wrapper". 1.1. La ce foloseste? Ipchains pentru linux este o rescriere a codului pentru firewall IPv4 pentru Linux (care a fost in mare preluat de la BSD) si o rescriere a ipfwadm, care este o rescriere a ipfw apartinand BSD-ului. Ipchains este cerut pentru administrarea filtrelor de pachete in kernelurile Linux versiunea 2.1.102 si mai avansate. 1.2. De ce? Deoarece: codul mai vechi pentru firewall nu intelegea fragmentele, avea counter-e pe 32 biti (cel putin pe Intel), nu suporta alte protocoale in afara TCP, UDP si ICMP, nu putea sa realizeze schimbari mari rapid, nu stia sa specifice reguli inverse, are cateva inflorituri, si poate fi greu de manevrat (facandu-l predispus la erori din partea utilizatorului). 1.3. Cum? In mod curent codul pentru filtrarea de pachete este inclus in kernelurile de la versiunea 2.1.102.. Pentru versiunile 2.0 va trebui sa aplici un patch pe care il downloadezi de pe pagina web. Daca kernelul 2.0 este mai recent decat patch-ul respectiv, ar trebui sa mearga; aceasta parte de cod din kernel este destul de stabila (ex. patch pentru kernel 2.0.34 este bun si pentru kernel 2.0.35). Deoarece patch-ul pentru ver. 2.0 este incompatibil cu patch-urile pentru ipportfw si ipautofw, nu recomand aplicarea acestuia decat in cazul in care ai mare nevoie de functionalitatea oferita de ipchains. 1.4. De unde? Pagina oficiala poate fi gasita in trei locuri: Multumiri lui Penguin Computing Multumiri echipei SAMBA Multumiri lui Jim Pick . Exista o lista de discutii pentru rapoarte privind bug-uri, discutii, dezvoltare si folosire. Subscrie-te pe aceasta lista trimitand la subscribe at east.balius.com un mesaj avand in corpul mesajului "subscribe ipchains-list". Pentru a trimite mail la toti cei care sunt subscrisi pe lista foloseste adresa ipchains-list at east.balius.com. 2. Bazele teoretice ale filtrarii de pachete 2.1. La ce foloseste? Intreg traficul dintr-o retea este transmis sub forma de pachete. De exemplu, downloadarea unui fisier (sa zicem, in marime de 50K) va cauza primirea a in jur de 36 de pachete cu o marime de 1460 bytes fiecare. Partea de inceput a oricarui pachet spune unde se duce, de unde a venit, tipul pachetului, si alte asemenea detalii. Aceasta parte de inceput a pachetului se numeste header. Restul pachetului care contine informatia propriu-zisa este numita body (corp). Unele protcoale, cum ar fi TCP, care este folosit pentru trafic web, mail, si conectarea de la distanta pe alte sisteme, folosesc termenul de "conexiune" -- inainte de transmiterea oricaror informatii cu date propriu-zise, pachete diferite (cu headere speciale) sunt schimbate, spunand "Vreau sa ma conectez", "OK", si "Mersi". Apoi pachete normale sunt schimbate. Un filtru de pachete este o portiune de cod care se uita la headerul pachetelor pe masura ce acestea trec, si decid soarta intregului pachet. Poate sa decida sa ignore pachetul (ignora pachetul ca si cum nu ar fi fost primit), accepta pachetul (lasa pachetul sa intre), sau sa respinga pachetul (asemanator cu ignorarea pachetul cu deosebira ca spune sistemului care l-a trimis acest lucru). Sub linux, filtrarea de pachete este compilata in kernel, si sunt cateva smecherii pe care le putem face cu pachetele, dar ramane valabil principiul general al examinarii headerelor si determinarea sortii pachetului. 2.2. De ce? Control. Securitate. Vigilenta. Control: cand folosesti un sistem Linux pentru a-ti conecta reteaua interna la o alta retea (sa spunem, Internet) ai posibilitatea de a permite un anumit tip de trafic, si sa refuzi pe altele. De exemplu, header-ul contine adresa destinatie a unui pachet, asa ca poti preveni pachetele sa se duca spre o anumita parte a retelei exterioare. Ca un alt exemplu, folosesc Netscape pentru accesarea arhivelor Dilbert. Sunt reclame pe pagina de la doubleclick.net, si Netscape imi pierde timpul incarcandu-le. Spunand filtrului de pachete sa nu permita pachete de la sau spre nici una din adresele detinute de catre doubleclick.net rezolva aceasta problema (cu toate acestea sunt modalitati mai bune pentru aceasta: vezi Junkbuster). Securitate: cand sistemul tau Linux este singurul intre haosul Internetului si reteaua ta ordonata si delicata, este placut sa stii ca poti sa restrictionezi ceea ce vine tropaind la usa. De exemplu, poti sa permiti la tot sa iasa din retea, dar ai putea fi ingrijorat de binecunoscutul "Ping al Mortii" venind de la persoanele din afara rau intentionate. Ca un alt exemplu, s-ar putea sa nu doresti ca persoanele din afara sa se telnet-uiasca pe sistemul tau Linux, chiar daca toate conturile tale au parole. Poate doresti (ca multi oameni) sa fii un observator al Internet-ului, si nu server (de voie, sau in alt mod). Pur si simplu nu lasa pe nimeni sa se conecteze, punand fitrul de pachete sa respinga pachetele folosite la initierea de conexiuni. Vigilenta: uneori o masina prost configurata in reteaua locala va decide sa arunce pachete spre lumea din afara. Este dragut sa spui filtrului de pachete sa te anunte daca se intampla ceva anormal; poate poti face ceva cu privire la acel lucru, sau poate esti doar curios. 2.3. Cum? 2.3.1. Un kernel ce are compilat suport pentru filtrare de pachete Ai nevoie de un kernel care sa aiba suport compilat pentru IP firewall chains. Poti sa iti dai seama daca ai kernelul care iti trebuie verificand existenta fisierului "/proc/net/ip_fwchains". Daca acesta exista, este ok. Daca nu, trebuie sa compilezi un kernel cu suport pentru IP firewall chains. Intai downloadeaza sursele kernelului pe care il doresti. Daca ai sursele pentru kernel peste versiunea 2.1.102, inclusiv, nu va fi necesar sa ii aplici patch. In caz contrar, aplica un patch de pe pagina web listata mai sus, si realizeaza configuratia cum este detaliat mai jos. Daca nu stii cum sa faci asta nu intra in panica -- citeste Kernel-HOWTO. Optiunile de configurarea ce trebuie facute pentru kernel ver 2.0 sunt: ______________________________________________________________________ CONFIG_EXPERIMENTAL=y CONFIG_FIREWALL=y CONFIG_IP_FIREWALL=y CONFIG_IP_FIREWALL_CHAINS=y ______________________________________________________________________ Pentru kernelurile ver. 2.1 sau 2.2: ______________________________________________________________________ CONFIG_FIREWALL=y CONFIG_IP_FIREWALL=y ______________________________________________________________________ Comanda ipchains cumunica kernelului si ii spune ce pachete sa filtreze. Mai jos este prezentat cum vei realiza filtrarea de pachete. 2.3.2. ipchains Comanda ipchains introduce si sterge reguli din portiunea din kernel referitoare la filtrarea de pachete. Aceasta inseamna ca orice vei realiza va fi pierdut dupa rebootare, citeste "Crearea regulilor permanente" pentru a vedea cum sa faci regulile permanente. ipchains inlocuieste ipfwadm, care a fost folosit pentru vechiul cod de firewall IP. Exista o multime de scripturi folositoare de pe site-ul ftp al ipchains-ului: http://netfilter.filewatcher.org/ipchains/ipchains-scripts-1.1.2.tar.gz Aceasta arhiva contine un script numit ipfwadm-wrapper care iti permite sa realizezi filtrarea de pachete exact cum era inainte. Probabil ca nu ar trebui sa folosesti acest scipt in afara de cazul cand doresti o cale rapida de a upgrada un sistem ce foloseste ipfwadm (este mai incet, nu verifica argumentele, etc.). In acest caz nu ai nevoie nici de acest HOWTO. Vezi anexa "Diferente intre ipchains si ipfwadm" si anexa "Folosirea scriptului ipfwadm-wrapper" pentru mai multe detalii privind ipfwadm. 2.3.3. Crearea regulilor permanente Regulile curente ale firewall-ului se afla in kernel, si de aceea vor fi pierdute la rebootare. Recomand folosirea scripturile "ipchains-save" si "ipchains-restore" pentru a face regulile permanente. Pentru a realiza aceasta, seteazati regulile, apoi ruleaza (ca root): # ipchains-save > /etc/ipchains.rules # Creaza un script astfel: #! /bin/sh # Script to control packet filtering. # If no rules, do nothing. [ -f /etc/ipchains.rules ] || exit 0 case "$1" in start) echo -n "Turning on packet filtering:" /sbin/ipchains-restore < /etc/ipchains.rules || exit 1 echo 1 > /proc/sys/net/ipv4/ip_forward echo "." ;; stop) echo -n "Turning off packet filtering:" echo 0 > /proc/sys/net/ipv4/ip_forward /sbin/ipchains -F /sbin/ipchains -X /sbin/ipchains -P input ACCEPT /sbin/ipchains -P output ACCEPT /sbin/ipchains -P forward ACCEPT echo "." ;; *) echo "Usage: /etc/init.d/packetfilter {start|stop}" exit 1 ;; esac exit 0 Asigura-te ca acest script este rulat devreme in procesul de incarcare al sistemului. In cazul meu (Debian 2.1), am facut o legatura simbolica numita "S39packetfilter" in directorul "/etc/rcS.d" (acesta va fi rulat inainte de S40network). 3. Sunt derutat! Rutare, masqueradare, forwardare de pachete, ipautofw.... Acest HOWTO este dedicat filtrarii de pachete. Aceasta inseamna a decide ce pachete sa lasi sa treaca sau nu. Cu toate acestea, Linux-ul fiind terenul de joaca al hackerilor probabil ca doresti sa realizezi mai multe de atat. O problema este faptul ca aceeasi comanda "ipchains" este folosita sa controlezi masqueradingul cat si realizarea de proxy transparent, deasemenea aceastea sunt diferite fata de filtrarea de pachete (implementarea Linux curenta le pune una langa celelalte, lasand impresia ca sunt strans inrudite). Realizarea de masquerading si proxy transparent sunt detaliate in HOWTO-uri separate, si auto forwardarea si fowardarea de porturi sunt controlate de comenzi diferite, dar cum multa lume ma intreaba despre acestea, voi include o multime de scenarii posibile si voi indica momentul cand trebuie aplicat fiecare. Meritele de securitate ale fiecarei configuratii nu va fi discutat aici. 3.1. Ghidul de trei linii al lui Rusty privind masqueradarea Se presupune ca interfata ta externa este "ppp0". Foloseste comanda "ifconfig" pentru a afla interfata, si modifica dupa caz: # ipchains -P forward DENY # ipchains -A forward -i ppp0 -j MASQ # echo 1 > /proc/sys/net/ipv4/ip_forward 3.2. Promovare gratuita: regulile WatchGuard Poti sa cumperi firewall-uri gata facute. Unul excelent este FireBox de la WatchGuard. Este excelent pentru ca imi place, este sigur, este bazat pe Linux, si pentru ca au finantat suportul pentru ipchains cat si pentru noul cod de firewall (pentru 2.4). Pe scurt, WatchGuard ma platesc pe mine pentru a avea ce manca in timp ce muncesc pentru voi. Asa ca ia in considere produsul lor. http://www.watchguard.com 3.3. Firewall-uri obisnuite Te ocupi de littlecorp.com. Ai o retea interna, si o conexiune PPP catre internet (de pe ruterul firewall.littlecorp.com care are adresa 1.2.3.4). Folosesti ethernet pentru reteaua locala, si sistemul tau se numeste "myhost". Sectiunea care urmeaza va ilustra diferite scenarii care sunt obisnuite. Cititi cu atentie, pentru ca sunt fiecare usor diferite. 3.3.1. Retea privata: Proxy-uri traditionale In acest scenariu, pachetele din reteaua privata nu vor ajunge pe Internet si viceversa. Adresele IP pentru reteaua privata ar trebui sa fie asignate din clasa de IP-uri pentru retele private conform cu RFC1918 (ex: 10.*.*.*, 172.16.*.*-172.31.*.* or 192.168.*.*). Singurul mod prin care te conecteazi la Internet este prin conectare la firewall, care este singurul sistem comun celor doua retele, pe care le conecteaza. Pentru a realiza acest lucru folosesti (pe firewall) o aplicatie numita proxy (exista proxy-uri pentru FTP, www, telnet, RealAudio, Usenet News si alte servicii). Citeste Firewall HOWTO. Orice servicii pe care le doresti accesibile de pe Internet trebuie sa fie pe firewall. (insa vezi "Servicii interne limitate"). Exemplu: Permiterea acesului web din reteaua privata catre Internet 1. Reteaua privata are asignate adresele 192.168.1.*, myhost fiind sistemul cu adresa 192.168.1.100, iar interfata ethernet a firewall-ului avand asignata adresa 192.168.1.1. 2. Un proxy pentru web (ex. squid) este instalat si configurat pe firewall, sa spunem ca asculta pe portul 8080. 3. Netscape-ul din reteaua privata este configurat sa foloseasca drept proxy portul 8080 de pe firewall. 4. DNS nu trebuie sa fie configurat in reteaua privata. 5. DNS trebuie sa fie configurat pe firewall. 6. Nici o ruta default (gateway) nu trebuie sa fie configurata in reteaua privata. Netscape de pe myhost citeste http://slashdot.org 1. Netscape se conecteaza la portul 8080 de pe firewall, folosind portul 1050 de pe myhost. Intreaba de pagina web a adresei "http://slashdot.org". 2. Proxy-ul se uita dupa numele "slashdot.org", si gaseste 207.218.152.131. Apoi deschide o conexiune catre acea adresa IP (folosind portul 1025 de pe interfata externa a firewall-ului), si intreaba serverul web (portul 80) de pagina web. 3. Pe masura ce primeste pagina web prin conexiunea cu serverul de web, firewall-ul copiaza informatia catre conexiunea cu Netscape. 4. Netscape afiseaza pagina Din punctul de vede al slashdot.org, conexiunea este facuta de la 1.2.3.4, portul 1025 catre 207.218.152.131 (slashdot.org), portul 80. Din punctul de vedere al myhost conexiunea este realizata de la 192.168.1.100 (myhost), portul 1050, catre 192.168.1.1 (interfata ethernet a firewall-ului), portul 8080. 3.3.2. Retea privata: Proxy-uri transparente In acest scenariu, pachetele din reteaua privata nu vor ajunge pe Internet si viceversa. Adresele IP pentru reteaua privata ar trebui sa fie asignate din clasa de IP-uri pentru retele private conform cu RFC1918 (ex: 10.*.*.*, 172.16.*.*-172.31.*.* or 192.168.*.*). Singurul mod prin care te conectezi la Internet este prin conectare la firewall, care este singurul sistem comun celor doua retele, pe care le conecteaza. In acest scop rulezi o aplicatie (pe firewall) numita proxy transparent; kernelul schimba destinatia pachetele din reteaua privata care ar fi trebuit sa fie trimise spre Internet catre proxy-ul transparent. (modifica rutarea). Proxy transparent insemna ca hosturile din reteaua privata nu au nevoie sa shtie ca este implicat un proxy. Orice servicii pe care le doresti accesibile de pe Internet trebuie sa fie pe firewall. (insa vezi "Servicii interne limitate"). Exemplu: Permiterea acesului web din reteaua privata catre Internet 1. Reteaua privata are asignate adresele 192.168.1.*, myhost fiind sistemul cu adresa 192.168.1.100, iar interfata ethernet a firewall-ului avand asignata adresa 192.168.1.1. 2. Un proxy de web transparent (cred ca sunt patch-uri pentru squid, pentru ai permite sa lucreze in acest mod, sau incerca "transproxy") este instalat si configurat pe firewall, sa spunem ca asculta pe portul 8080. 3. Kernelului ii este spus, folosind ipchains, sa redirecteze conexiunile catre portul 80 spre proxy. 4. Netscape din reteaua privata este configurat sa se conecteze direct. 5. DNS trebuie sa fie configurat in reteaua privata (trebuie sa rulezi un server DNS pentru reteaua locala, ca un proxy, pe firewall). 6. Ruta default (gateway) trebuie sa fie configurata in reteaua privata, pentru a trimite pachetele catre firewall. Netscape de pe myhost citeste http://slashdot.org. 1. Netscape rezolva numele "slashdot.org" in adresa 207.218.152.131. Apoi deschide o conexiune catre aceea adresa folosind portul local 1050, si cere serverului de web (portul 80) pagina web. 2. Pe masura ce pachetele de la myhost (portul 1050) catre slashdot.org (portul 80, trec prin firewall, ele sunt redirectate catre proxy-ul transparent ce asculta pe portul 8080. Proxy-ul transparent deschide o conexiune (folosind portul local 1025) catre 207.218.152.131, portul 80 (care este adresa reala catre care se indreptau pachetele originale). 3. Pe masura ce primeste pagina web prin conexiunea cu serverul de web, firewall-ul copiaza informatia catre conexiunea cu Netscape. 4. Netscape afiseaza pagina. Din punctul de vedere al slashdot.org, conexiunea este facuta de la 1.2.3.4 (interfata PPP a firewall-ului), portul 1025 catre 207.218.152.131 (slashdot.org), portul 80. Din punctul de vedere al myhost conexiunea este realizata de la 192.168.1.100 (myhost), portul 1050, catre 207.218.152.131 (slashdot.org) portul 80, dar defapt vorbeste cu proxy-ul transparent. 3.3.3. Retea privata: Masquerading In acest scenariu, pachetele din reteaua privata nu vor ajunge pe Internet fara o modificare in prealabil si viceversa. Adresele IP pentru reteaua privata ar trebui sa fie asignate din clasa de IP-uri pentru retele private conform cu RFC1918 (ex: 10.*.*.*, 172.16.*.*-172.31.*.* sau 192.168.*.*). In loc sa folosim un proxy, folosim o facilitate speciala a kernelului numita "masquerading". Masqueradarea recreeaza pachetele pe masura ce acestea trec prin firewall, in asa fel incat intodeauna par ca vin de la insusi firewall-ul. Apoi rescrie raspunsurile in asa fel incat apar ca si cum ar veni de la insasi destinatia originala. Masquerading are module speciale pentru unele protocoale mai speciale, cum ar fi FTP, RealAudio, Quake, etc. Pentru protocoale pentru care nu se poate realiza acest lucru, facilitatea "forwardare automata" care poate manipula unele dintre aceste protocoale prin realizarea automata de forwardare pentru porturile necesare. Vezi "ipportfw" (kernelurile 2.0) sau "ipmasqadm" (kernelurile 2.1). Orice servicii pe care le doresti accesibile de pe Internet trebuie sa fie pe firewall. (insa vezi "Servicii interne limitate"). Exemplu: Permiterea accesului la web din reteaua privata catre Internet. 1. Adresa privata are asignate adresele 192.168.1.*, myhost fiind sistemul cu adresa 192.168.1.100, iar interfata ethernet a firewall-ului avand asignata adresa 192.168.1.1. 2. Firewall-ul este configurat sa realizeze masquerading pentru pachetele care pleaca din reteaua privata spre Internet, portul 80. 3. Netscape este configurat sa se conecteze direct. 4. DNS trebuie configurat corect in reteaua privata. 5. Firewall-ul ar trebui sa fie ruta default (gateway) pentru reteaua privata. Netscape de pe myhost citeste http://slashdot.org 1. Netscape rezolva numele "slashdot.org" in adresa IP 207.218.152.131. Apoi deschide o conexiune catre acea adresa IP, folosind portul local 1050, si cere serverului de web (portul 80) pagina web. 2. Pe masura ce pachetele de la myhost (portul 1050) catre slashdot.org (portul 80) trec prin firewall, acestea sunt rescrie pentru a parea ca vin de pe interfata PPP a firewall-ului, portul 65000. Firewall-ul are o adresa internet valida (1.2.3.4) asa ca pachetele replica de la slashdot.org sunt rutate inapoi corect. 3. Pe masura ce pachetele de la slashdot.org (portul 80) sunt rutate inapoi catre firewall.littlecorp.com (portul 65000), acestea sunt rescrise pentru a se inapoia catre myhost, portul 1050. Aceasta este reala magie a masqueradingului: tine minte cand rescrie pachetele ce ies pentru ca sa poata rescrie pachetele replica pe masura ce acestea vin. 4. Netscape afiseaza pagina. Din punctul de vedere al slashdot.org, conexiunea este realizata de la adresa IP 1.2.3.4 (interfata PPP a firewall-ului) portul 65000, catre 207.218.152.131 (slashdot.org) portul 80. 3.3.4. Retea publica In acest scenariu, reteaua ta personala este parte din Internet: pachetele pot sa circule fara nici o modificare intre ambele retele. Adresele IP ale retelei interne trebuie sa fie asignate printr-o cerere pentru un bloc de adrese IP, astfel incat restul Internetului sa stie cum sa ruteze pachetele catre aceasta. Aceasta implica o conexiune permanenta. In acest caz, filtrul de pachete este folosit pentru a decide ce pachete sa fie forwardate intre reteaua ta si restul Internetului, de exemplu sa permiti restului Internetului accesul numai la serverele interne de web. Exemplu: Permiterea accesului web din reteaua personala catre Internet 1. Reteaua interna are adresele IP asignate conform cu blocul de adrese IP pe care le-ai inregistrat. (sa zicem 1.2.3.*) 2. Firewall-ul este configurat sa permita traficul. 3. Netscape este configurat sa se conecteze direct. 4. DNS trebuie sa fie corect configurat in reteaua ta. 5. Firewall-ul trebuie sa fie ruta default (gateway) pentru reteaua ta. Netscape de pe myhost citeste http://slashdot.org 1. Netscape rezolva numele "slashdot.org" in adresa IP 207.218.152.131. Deschide apoi o conexiune catre aceea adresa IP, folosind portul local 1050, si cere serverului de web (portul 80) pagina web. 2. Pachetele trec prin firewall-ul tau la fel cum trec prin multe alte rutere intre tine si slashdot.org. 3. Netscape afiseaza pagina. Exista doar o singura conexiune: de la 1.2.3.4 (myhost) portul 1050, la 207.218.152.131 (slashdot.org) portul 80. 3.3.5. Servicii interne limitate Sunt cateva lucruri pe care le poti intreprinde pentru a permite accesul din afara Internetului catre servicile interne, decat sa rulezi acele servici pe firewall. Aceast lucru este posibil printr-o solutie pentru conexiunile externe in gen proxy sau masquerading. Cea mai simpla abordare este sa rulezi aplicatia "redirector", care este un proxy care asteapta o conexiune pe un port dat, si apoi deschide o conexiune interna catre un host intern, pe un anumit port, si copiaza datele intre cele doua conexiuni. Din punctul de vedere al Internetului, conexiunea este facuta pe firewall. Din punctul de vedere al serverului intern, conexiunea este facuta intre interfata interna a firewall-ului si serverul intern. O alta cale (care, pentru kernel ver. 2.0 este necesar un patch pentru ipportwf, sau un kernel versiunea 2.1 sau peste) este sa folosesti forwardarea de porturi din kernel. Aceasta realizeaza acelasi lucru ca "redirector" intr-un mod diferit: kernelul rescrie pachetele pe masura ce ele trec, schimbandu-le adresa si portul destinatie catre un host si port anumit din reteaua interna. Din punctul de vedere al Internetului conexiunea este facuta cu firewall-ul. Din punctul de vedere al serverului intern, conexiunea este una directa intre serverul intern si hostul din Internet. 3.4. Mai multe informatii despre masquerading David Ranch a scris un excelent nou HOWTO despre masquerading, care se suprapune mult peste acest HOWTO. Poti sa gasesti acest HOWTO la http://www.linuxdoc.org/HOWTO/IP-Masquerade-HOWTO.html Pagina oficiala pentru Masquerading este la: http://ipmasq.cjb.net 4. Filtrul de pachete Aceasta sectiune descrie tot ceea ce trebuie sa stii cu adevarat pentru a realiza un filtru de pachete ca sa iti indeplineasca cerintele. 4.1. Cum travereseaza pachetele filtrele Kernelul porneste cu trei liste de reguli; aceste liste se numesc chain-uri. Aceste trei chain-uri incluse default sunt: input, output si forward. Cand un pachet soseste (sa zicem, prin placa Ethernet) kernelul foloseste chain-ul input pentru a decide soarta pachetului. Daca trece de acest chain, kernelul decide unde sa trimita pachetul (aceasta este numita rutare). Daca este destinat pentru o alta masina, pachetul trece prin chain-ul forward. In final, chiar inainte ca un pachet sa plece, kernelul verifica chain-ul output. Un chain este o lista cu reguli ce trebuie verificate. Fiecare regula spune "daca headerul pachetului arata asa, atunci iata ce sa faci cu pachetul". Daca regula nu se potriveste cu pachetul, atunci urmatoarea regula din chain este examinata. In final, daca nu mai exista reguli de verificat, atunci kernelul verifica politica (policy-ul) pe care o are chain-ul. Intr-un sistem in care se pune baza pe securitate, de obicei politica este sa ignore pachetul sa sa ii dea reject. Pentru fanii ASCII, aceasta este calea pe care o parcurge un pachet: ---------------------------------------------------------------- | ACCEPT/ interfata lo | v REDIRECT _______ | --> C --> S --> ______ --> D --> ~~~~~~~~ -->|Chain-ul|---> _________--> h a |Chain-ul| e {Decizie } |forward | |Chain-ul |ACCEPT e n |input | m {de rutare} |________|--->|output | c i |________| a ~~~~~~~~ | | ->|_________| k t | s | | | | | s y | q | v | | | u | v e v DENY/ | | v m | DENY/ r Proces Local REJECT | | DENY/ | v REJECT a | | | REJECT | DENY d --------------------- | v e ----------------------------- DENY Iata o descriere a fiecarui pas: Checksum: Acesta este un test pentru a vedea daca pachetul a fost corupt in vreun fel. Daca da, atunci este ignorat. Normalitate (sanity): Acest test defapt exista inainte fiecarui chain, dar acela care se face inainte chain-ului input este cel mai important. Pachetele malformate ar putea sa incurce codul de verificare al regulilor, aceastea sunt ignorate aici (daca acest lucru se intampla, un mesaj este trimis catre syslog). Chain-ul input: Acesta este primul chain din firewall unde pachetul va fi verificat. Daca decizia chain-ului nu este DENY (ignora) sau REJECT, pachetul isi continua drumul. Demasquerade:Daca pachetul este o replica la un pachet asupra caruia a fost realizata masquerading, se realizeaza asupra acestuia demasquradare, iar apoi se indreapta direct catre chain-ul output. Daca nu folosesti Masquerading IP, poti sa stergi mental aceasta din diagrama. Decizie de rutare: Campul privind destinatia este examinat de catre codul ce realizeaza rutarea, pentru a decide daca pachetul trebuie sa se indrepte catre un proces local (vezi "Procesul local" de mai jos) sau forwardat catre o masina la distanta (vezi "Chain-ul forward" de mai jos). Procesul local: Un proces ruland pe masina poate primi pachete dupa pasul deciziei privind rutarea pachetelor, si poate trimite pachete (care trec prin pasul deciziei rutarii, apoi travereseaza chain-ul output) Interfata lo: Daca pachetele unui proces local, sunt destinate pentru un proces local, acestea vor iesi prin chain-ul output cu interfata setata "lo", apoi se vor intoarce prin chain-ul input cu interfata deasemenea "lo". Interfata "lo" este numita interfata loopback. local: daca pachetul nu a fost creat de un proces local, atunci chain-ul forward este verificat, in caz contrar pachetul se duce catre chain-ul output. Chain-ul forward: Acest chain este traversat de orice pachet care incearca sa treaca prin aceasta masina catre alta. Chain-ul output: Acest chain este traversat de toate pachetele chiar inainte de a iesi. 4.1.1. Folosirea ipchains In primul rand, asigurate ca ai versiunea de ipchains la care se refera acest document. $ ipchains --version ipchains 1.3.9, 17-Mar-1999 Observatie: recomand 1.3.4 (care nu are optiuni in format lung, cum ar fi "--sport"), 1.3.8 sau mai avansate; acestea fiind foarte stabile. ipchains are o destul de detaliata pagina de manual (man ipchains), si daca ai nevoie de mai multe detalii in particular, poti sa verifici interfata pentru programare (man 4 ipfw), sau fisierul net/ipv4/ip_fw.c in sursele kernelului 2.1.x, care este (bineinteles) o sursa de incredere. Mai exista deasemenea o fisa de referinta rapida creata de catre Scott Bronson in arhiva surselor, in format US Letter PostScript(TM) si A4. Sunt mai multe lucruri diferite pe care le poti face cu ipchains. In primul rand comenzi prin care poti administra un chain intreg. Incepi cu trei chain-uri compilate default pe care nu le poti sterge: input, output si forward. 1. Creaza un chain nou (-N). 2. Sterge un chain gol (-X). 3. Schimba policy-ul (politica) pentru unul din chain-urile default (-P). 4. Listeaza regulile dintr-un chain (-L). 5. Sterge regulile dintr-un chain (-F) 6. Reseteaza counter-ele pentru pachete si bytes pentru toate regulile dintr-un chain (-Z). Sunt mai multe moduri de a manipula regulile dintr-un chain: 1. Adauga o noua regula intr-un chain (-A). 2. Introduce o noua regula la o pozitia anumita intr-un chain (-I) (default adauga la inceput). 3. Inlocuieste o regula la o anumita pozitie din chain (-R). 4. Sterge o regula la o anumita pozitie din chain (-D). 5. Sterge prima regula care se potriveste din chain (-D). Sunt cateva operatii si pentru masquerading: 1. Listeaza conexiunile pentru care se fac in mod curent masquerading (-M -L). 2. Stabileste valori de timeout pentru masquerading (-M -S). (Dar citeste si "Nu pot preciza valori de timeout pentru masquerading!") Ultima (si poate cea mai folositoare) functie iti permite sa verifici ce s-ar intampla cu un pachet dat daca ar traversa un chain dat. 4.1.2. Ce vei vedea cand porneste computerul Inainte de rularea oricarei comenzi ipchains (fii atent, unele distributii ruleaza ipchains in scripturile de initializare), nu vor exista nici un fel de reguli in nici unul dintre chain-urile incluse default ("input", "output" si "forward"), si fiecare din aceste chain-uri va avea un policy de ACCEPT. Aceasta inseamna ca nu exista filtrare de pachete. 4.1.3. Operatii pentru o singura regula Acesta este unul dintre cele mai importante lucruri; manipularea regulilor. Cel mai obisnuit, vei folosi probabil comenzile de adaugare (-A) si de stergere (-D). Celelalte (-I pentru introducere si -R pentru inlocuire) sunt doar prelungiri ale comenzilor precedente. Fiecare regula specifica o multime de conditii pe care un pachet trebuie sa le indeplineasca, si ce sa faca daca regulile sunt indeplinite (o "tinta"). De exemplu, s-ar putea sa doresti sa ignori toate pachetele ICMP venind de la adresa 127.0.0.1. Deci, in acest caz conditiile sunt ca protocolul sa fie ICMP si adresa sursa sa fie 127.0.0.1. Tinta noastra este "DENY". 127.0.0.1 este interfata "loopback", care exista chiar daca nu ai legatura reala la o retea. Poti folosi programul "ping" pentru a genera acest tip de pachete (pur si simplu trimite pachete ICMP de tip 8 (echo request) la care toate host-urile ar trebui sa raspunda cu pachete ICMP de tip 0 (echo replay)). Aceast program este foarte folositor pentru teste. # ping -c 1 127.0.0.1 PING 127.0.0.1 (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms --- 127.0.0.1 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.2/0.2/0.2 ms # iptables -A input -s 127.0.0.1 -p icmp -j DENY # ping -c 1 127.0.0.1 PING 127.0.0.1 (127.0.0.1): 56 data bytes --- 127.0.0.1 ping statistics --- 1 packets transmitted, 0 packets received, 100% packet loss # Poti vedea aici ca primul ping reuseste ("-c 1" spune sa sa trimita doar un singur pachet). Apoi adaugam in coada (-A) chain-ului "input", o regula ce spune ca pentru pachetele de la 127.0.0.1 ("-s 127.0.0.1") de tip ICMP ("-p icmp") trebuie sa sarim la "DENY" ("-j DENY"). Apoi testam regula noastra, folosind al doilea ping. Va fi o pauza pana cand programul se da batut sa astepte un raspuns care nu va veni niciodata. Am putea sa stergem regula in doua moduri. Intai, deoarece stim ca este singura regula din chain-ul input, putem folosi o stergere numarata, ca in: # iptables -D input 1 # Pentru a sterge regula cu numarul 1 din chain-ul input. Al doilea mod este sa scriem comanda prin care am introdus regula -A, dar sa inlocuim -A cu -D. Aceasta este folositor cand ai un chain complex de reguli si nu doresti sa le numeri ca sa iti dai seama ca este a 37-a regula de care vrei sa scapi. In aces caz, vom folosi: # ipchains -D input -s 127.0.0.1 -p icmp -j DENY # Sintaxa comenzii -D trebuie sa aiba exact aceleasi optiuni cum are comanda -A (sau -I, sau -R). Daca sunt reguli identice in acelasi chain, numai prima regula va fi stearsa. 4.1.4. Optiuni de filtrare Am vazut folosirea optiunii "-p" pentru a specifica protocolul, si optiunii "-s" pentru a specifica adresa sursa, dar sunt alte optiuni pe care le putem folosi pentru a preciza caracteristici ale pachetului. Ceea ce urmeaza este un compedium complet. 4.1.4.1. Specificarea adreselor IP sursa si destinatie Adresele IP ale sursei ("-s") si destinatiei ("-d") pot fi specificate in patru moduri. Cea mai obisnuita forma este sa folosesti numele complet, cum ar fi "localhost" sau "www.securityorg.net". Cea de-a doua cale este sa specifici adresa IP cum ar fi "127.0.0.1". Cea de a treia si a patra cale permite specificarea unui grup de adrese IP, cum ar fi "199.95.207.0/24" sau "199.95.207.0/255.255.255.0". Amandoua specifica orice adresa IP de la 199.95.207.0 pana la 199.95.207.255 inclusiv; cifrele dupa "/" spun care parti din adresa IP sunt semnificative. "/32" sau "/255.255.255.255" este default (se potriveste cu toata adresa IP). Pentru a specifica oricare adresa IP "/0" poate fi folosit, astfel: # ipchains -A input -s 0/0 -j DENY # Aceasta este folosit in mod rar, deoarece efectul de mai sus este asemanator cu nespecificare deloc a optiunii "-s". 4.1.4.2. Specificarea inversa Multe optiuni, inclusiv optiunile "-s" si "-d" pot avea argumentele precedate de "!" (pronuntat "nu") pentru a corespunde adreselor care NU sunt egale cu adresele date. De exemplu, "-s ! localhost" corespunde oricarui pachet care nu vine de la localhost. 4.1.4.3. Specificarea protocolului Protocolul poate fi specificat prin optiunea "-p". Protocolul poate fi un numar ( daca stii valorile numerice de protocol pentru IP) sau un nume pentru cazurile speciale de "TCP", "UDP" sau "ICMP". Nu conteaza daca se foloseste sau nu CAPS, asa ca "tcp" merge la fel ca si "TCP". Numele protocolului poate fi precedat de "!", pentru a inversa, ca si "-p ! tcp" pentru a specifica pachetele care nu sunt TCP. 4.1.4.3.1. Specificarea porturilor TCP si UDP Pentru cazul special cand este specificat un protocol TCP si UDP, poate fi precizat un argument in plus insemnand portul TCP sau UDP, sau un sir (inclusiv capetele sirului) de porturi (citeste insa mai jos "Despre fragmente"). Un sir este reprezentat prin caracterul ":", cum ar fi "6000:6010" care acopera 11 numere de porturi, de la 6000 la 6010 inclusiv. Daca limita de jos este omisa, atunci este considerata 0. Daca limita de sus este omisa, atunci este considerata 65535. Deci, pentru a specifica conexiunile TCP venind de la porturile sub 1024, sintaxa ar fi urmatoarea "-p TCP -s 0.0.0.0/0 :1023". Numerele de porturi pot fi specificate si prin nume, exemplu "www". Observatie: sensul regulii poate fi inversat si in cazul porturilor daca se pune in fata acestui argument semnul "!". Deci, pentru a specifica orice pachet care este pachet TCP dar nu este WWW, ai scrie astfel: -p TCP -d 0.0.0.0/0 ! www Este important sa realizezi ca -p TCP -d ! 192.168.1.1 www este foarte diferit de -p TCP -d 192.168.1.1 ! www Prima regula se potriveste cu toate pachetele care sunt de tip TCP, spre portul 80 si care nu au ca destinatie adresa 192.168.1.1. Iar, cea de a doua regula se potriveste cu toate pachetele de tip TCP care au ca destinatie 192.168.1.1, fara sa fie spre portul 80. In sfarsit, pentru regula urmatoare se potrivesc pachetele care nu au ca destinatie adresa 192.168.1.1 si nici portul 80. -p TCP -d ! 192.168.1.1 ! www 4.1.4.3.2. Specificarea tipului si codului ICMP Cand este precizat tipul de protocol ICMP, exista deasemenea argumente ce pot fi precizate in plus. ICMP nu are porturi. ICMP are un tip si un cod. Poti sa le specifici folosind nume ICMP (vezi ipchains -h icmp pentru a lista aceste nume) dupa optiunea "-s", sau ca numere insemnand tipul ICMP si codul, unde tipul urmeaza dupa optiunea "-s", iar codul dupa optiunea "-d". Numele ICMP sunt destul de lungi: trebuie sa folosesti doar destul de multe litere astfel incat sa se deosebeasca unele de altele. Iata o mica tabela pentru cele mai intalnite tipuri de pachete ICMP: Numar Nume Cerut de catre 0 echo-reply ping 3 destination-unreachable Any TCP/UDP traffic. 5 redirect routing if not running routing daemon 8 echo-request ping 11 time-exceeded traceroute Observatie: numele ICMP nu pot fi precedate deocamdata de semnul "!". Sub nici o forma sa nu blochezi toate pachetele ICMP de tip 3! Citeste mai jos "Pachete icmp". 4.1.4.4. Specificarea interfetei Optiunea "-i" specifica numele interfatei cu care sa corespunda. O interfata este dispozitivul fizic prin care intra pachetul sau prin care iese pachetul. Poti folosi comanda ifconfig pentru a lista interfetele care sunt "sus". (in stare de functionare in acel moment). Interfata pentru pentru pachete ce sosesc (pachetele ce traverseaza chain-ul input) este considerata interfata prin care au intrat. In mod logic, interfata pentru pachetele care pleaca (pachetele ce traverseaza chain-ul output) este interfata prin care vor iesi. Interfata pentru pachetele ce traverseaza chain-ul forward este deasemenea interfata prin care vor iesi pachetele. Este perfect valabil sa specifici o interfata care nu exista; regula nu se va potrivi cu nici un pachet pana cand interfata nu este sus. Aceasta este extrem de folositor pentru legaturi PPP de dial-up (de obicei interfete ppp0) si asemanatoare. Ca un caz special, un nume de interfata terminandu-se cu "+" se va potrivi cu toate interfetele (fie ca exista sau nu) care incep cu acel sir de caractere. De exemplu pentru a specifica o regula care sa se potriveasca tuturor interfetelor PPP, optiunea -i ppp+ ar fi folosita. Numele interfetei poate fi precedata de "!", pentru a corespunde cu pachetul care nu se potriveste cu intefata specificata. 4.1.4.5. Specificarea doar a pachetelor TCP SYN Uneori este folositor sa permiti conexiunile TCP intr-o singura directie, nu si in cealalta. De exemplu, ai putea sa permiti conexiuni catre un server extern WWW, dar nici o conexiune de la acel server. Naiv ar fi sa blochezi pachetele TCP dinspre server. Din pacate, conexiunile TCP cer ca pachetele sa circule in ambele directii. Solutia ar fi sa blochezi numai pachetele folosite pentru a initia conexiuni. Aceste pachete sunt numite pachete SYN (ok, tehnic sunt pachete cu flag SYN pus si cu flagurile RST si ACK nepuse, dar le numim pe scurt pachete SYN). Prin ignorarea acestor pachete, putem sa oprim aceste conexiuni. Optiunea "-y" este folosita pentru aceasta; este valida numai pentru regulile in care specificam tcp ca protocol. De exemplu, pentru a specifica incercarile de conexiune de la 192.168.1.1: -p TCP -s 192.168.1.1 -y Aceasta optiune poate fi inversat prin precedarea "-y" cu semnul "!", care se potriveste pentru toate pachetele care nu initiaza conexiuni. 4.1.4.6. Despre fragmente Uneori un pachet este prea mare pentru a incape cu totul pe conexiune. Cand aceasta se intampla, pachetul este divizat in fragmente, si trimis ca pachete multiple. Celalalt capat reansambleaza aceste fragmente pentru a construi intregul pachet. Problema cu fragmentele este ca unele dintre argumentele descrise mai sus (in particular portul sursa, portul destinatie, tipul ICMP, codul ICMP, flagul syn TCP) cere kernelului sa verifice inceputul pachetului, care exista numai in primul pachet. Daca sistemul tau este singura conexiune catre o retea externa, atunci poti spune kernelului Linux sa reansambleze toate pachetele care trec prin el, prin compilarea kernelului cu optiunea "IP: always defragment set" egala cu "Y". In caz contrar, este important sa stii cum sunt tratate fragmentele de catre regulile de filtrare. Orice regula de filtrare care cere informatii pe care nu le avem nu se va potrivi. Aceasta inseamna ca primul fragment este tratat ca orice alt pachet. Al doilea si urmatoarele nu vor mai fi. De aceea o regula -p tcp -s 192.168.1.1 www (specificand un port sursa "www") nu se vor potrivi cu un fragment (altul decat primul). Nici regula opusa nu va face acest lucru -p TCP -s 192.168.1.1 ! www. Oricum, poti sa specifici o regula special pentru fragmentul al doilea si urmatoarele, folosind optiunea "-f". Evident, nu este corect sa specifici porturi TCP sau UDP, tip ICMP, cod ICMP, sau flag syn TCP, intr-o asemenea regula cu referire la fragmente. Este de asemenea legal sa specifici ca o regula nu se aplica la al doilea si urmatoarele fragmente, prin precedarea lui "-f" cu "!". De obicei este considerat sigur sa lasi sa treaca al doilea si urmatoarele fragmente, deoarece filtrarea va afecta primul fragment, si de aceea previne reansamblarea pe calculatorul destinatie; cu toate acestea, sunt cunoscute bug-uri care permit caderea sistemului doar prin simpla trasnmitere de fragmente. Este decizia ta. Nota pentru network-heads: pachetele cu malformatii (pachete TCP, UDP si ICMP prea scurte codului de firewall ca sa citeasca tipul portului sau codul ICMP si tipul) sunt tratate ca fragmente de asemenea. Doar fragmentele TCP care incep de la pozitia 8 sunt ignorate de catre kernel (un mesaj este trimis catre syslog, daca acest lucru se intampla). De exemplu, urmatoarea regula va ignora toate fragmentele ce au ca destinatie 192.168.1.1: # ipchains -A output -f -d 192.168.1.1 -j DENY # 4.1.5. Efectele filtrarii de pachete Acum stim toate modurile in care putem sa folosim o regula pentru a se potrivi anumitor pachete. Daca un pachet se potriveste cu o regula, urmatoarele lucruri se intampla: 1. Counter-ul de byte pentru acea regula creste cu o valoare egala cu marimea pachetului (header si restul pachetului) 2. Counter-ul de pachete pentru acea regula este incrementat. 3. Daca regula o cere, informatii despre pachet sunt scrise in fisierele de log. 4. Daca regula o cere, TOS al pachetului este schimbat. 5. Daca regula o cere, pachetul este marcat (acest lucru nu este posibil in kernelurile ver. 2.0). 6. Tinta regulii este examinata pentru a decide soarta acelui pachet. Pentru varietate le voi examina in ordinea importantei. 4.1.5.1. Specificarea unei tinte O tinta spune kernelului ce sa faca pachetului care se potriveste unei reguli. ipchains foloseste "-j" (in sensul "sare la") pentru argumentul tintei. Numele tintei trebuie sa fie mai mic decat 8 caractere, si conteaza daca este scris cu litere mici sau mari: "RETURN" sau "return" sunt lucruri diferite. Cel mai simplu caz este atunci cand nu este nici o tinta specificata. Acest tip de regula (numita uneori "accounting rule") este folositoare cand dorim sa avem o evidenta a numarului de pachete care indeplinesc anumite conditii. Chiar daca se potriveste sau nu kernelul examineaza urmatoarea regula din chain. De exemplu, pentru a numara pachetele care vin de la 192.168.1.1: # ipchains -A input -s 192.168.1.1 # (Folosind "ipchains -L -v" putem vedea counter-ele de pachete si bytes asociate fiecarei reguli.) Exista sase tinte speciale. Primele trei sunt destul de simple: ACCEPT, REJECT si DENY. ACCEPT lasa pachetul sa treaca. DENY ignora pachetul ca si cand nu ar fi fost primit. REJECT ignora pachetul, insa (daca nu a fost un pachet ICMP) trimite un pachet replica ICMP catre sursa care spune ca destinatia nu poate fi atinsa (destination unreachable). Urmatoarea regula, MASQ spune kernelului sa masqueradeze pachetul. Pentru ca aceasta tinta sa poate fi folosita trebuie sa fie compilat kernelul cu suport pentru "IP Masquerading". Pentru detalii privind masquerading citeste Masquerading-HOWTO si anexa "Diferente intre ipchains si ipfwadm". Aceasta tinta este corecta numai pentru pachetele ce traverseaza chain-ul forward. O alta tinta importnta este REDIRECT care comunica kernelului sa trimita un pachet catre un port local in loc de destinatia spre care se indrepta. Aceasta poate fi specificata doar pentru regulile in care se specifica protocolul TCP sau UDP. Optional, poate fi specificat un port, sub forma de nume sau numar, in continuare la "-j REDIRECT" care va determina ca pachetul sa fie redirectat catre un anumit port, nu spre portul spre care se indrepta. Aceasta tinta este valabila doar pentru pachetele ce traverseaza chain-ul input. Ultima tinta este RETURN, care este similar cu ajungerea pachetului direct la sfarsitul chain-ului (citeste "Setarea policy-ului" de mai jos). Orice alta tinta indica un chain definit de catre utilizator (cum este descris in "Operatii pentru un chain" de mai jos). Pachetul va incepe traversarea regulilor in acel chain. Daca acel chain nu decide soarta pachetului, odata traversarea terminata in acel chain, traversarea este continuata de la urmatoarea regula din chain-ul anterior. Considera doua chain-uri: input (chain-ul predefinit) si test (un chain definit de catre utitlizator). `input' `Test' ---------------------------- ---------------------------- | Rule1: -p ICMP -j REJECT | | Rule1: -s 192.168.1.1 | |--------------------------| |--------------------------| | Rule2: -p TCP -j Test | | Rule2: -d 192.168.1.1 | |--------------------------| ---------------------------- | Rule3: -p UDP -j DENY | ---------------------------- Considera un pachet TCP venind de la 192.168.1.1 si ducandu-se catre 1.2.3.4. Acesta intra in chain-ul INPUT. Rule1 nu se potriveste cu el, Rule2 se potriveste asa ca urmatoarea regula care este examinata este prima din chain-ul test. Rule1 se potriveste dar nu este specificata nici o tinta, asa ca urmatoarea regula este examinata. Rule2 nu se potriveste asa ca am ajuns la sfarsitul chain-ului. Astfel ne reintoarcem in chain-ul INPUT, unde am examinat Rule2, asa ca examinam Rule3 care nici aceasta nu se potriveste. Deci calea urmata de catre pachet este: v __________________________ `input' | / `Test' v ------------------------|--/ -----------------------|---- | Rule1 | /| | Rule1 | | |-----------------------|/-| |----------------------|---| | Rule2 / | | Rule2 | | |--------------------------| -----------------------v---- | Rule3 /--+___________________________/ ------------------------|--- v Citeste sectiunea "Cum sa iti organizezi regulile firewall-ului" pentru modalitati efective de a folosi chain-uri definite de catre utilizator. 4.1.5.2. Logarea pachetelor (nt. log= jurnal,logare=scriere in fisiere de log) Aceasta este un efect secundare pe care il poate avea faptul ca un pachet sa se potriveasca cu o regula, poti sa decizi ca informatii despre pachetul respectiv sa fie scris in fisierele de log prin folosirea optiunii "-l". In mod normal nu vei dori acest lucru pentru pachetele normale, dar aceasta este o optiune folositoare in cazul unor anumite pachete. Kernelul scrie aceste informatii astfel: Packet log: input DENY eth0 PROTO=17 192.168.2.1:53 192.168.1.1:1025 L=34 S=0x00 I=18 F=0x0000 T=254 Mesajul din loguri este special conceput concis, continand informatii folositoare. Contine urmatoarele: 1. "input" este chain-ul care a continut regula care s-a potrivit cu pachetul, cauzand mesajul din loguri. 2. "DENY" este ceea ce a decis regula privind soarta pachetului. Daca aceasta este "-" atunci regula nu a afectat deloc pachetul (o regula de contabilizare). 3. "eth0" este numele interfetei. Cum pachetul a fost logat in chain-ul input, inseamna ca "eth0" este numele interfetei de intrare. 4. "PROTO=17" insemna ca pachetul apartine protocolului 17. O lista cu numerele de protocoale este data in fisierul "/etc/protocols". Cele mai intalnite sunt 1 (ICMP), 6 (TCP) si 17 (UDP). 5. "192.168.2.1" este sursa IP al pachetului. 6. ":53" reprezinta portul sursa al pachetului. Uitandu-ne in fisierul "/etc/services" vedem ca acest numar corespunde portului "domain" (probabil ca este un pachet replica de la serverul DNS). Pentru TCP si UDP, acest numar reprezinta portul sursa. Pentru ICMP, este tipul ICMP. Pentru alte protocoale va fi 65535. 7. "192.168.1.1" este adresa IP destinatie. 8. ":1025" inseamna ca portul destinatie este 1025. Pentru UDP si TCP acesta reprezinta portul destinatie. Pentru ICMP reprezinta codul. Pentru altele va fi 65535. 9. "L=34" inseamna ca pachetul este in marime totala de 34 bytes. 10. "S=0x00" reprezinta tos (type of service). Imparte la 4 aceasta valoare pentru a avea tos in formatul folosit de catre ipchains. 11. "I=18" reprezinta IP ID. 12. "F=0x0000" reprezinta offset-ul de fragment pe 16 biti plus flaguri. O valoare ce incepe cu "0x4" sau "0x5" inseamna ca bit-ul "Don't Fragment" este pus. "0x2" sau "0x3" inseamna ca bitul "More Fragments" este pus; asteapta-te sa urmeze fragmente dupa acesta. Restul numarului reprezinta offsetul pentru acest fragment, impartit la 8. 13. "T=254" reprezinta Time To Live (ttl, timpul de existenta) al pachetului. Aceasta valoare este decrementata la fiecare link pe care il trece, si incepe deobicei la 15 sau 255. 14. "(#5)" in kernelurile mai recente (versiunile peste 2.2.9, inclusiv) reprezinta numarul reguli care a determinat mesajul. Pe sisteme standard Linux, mesajul kernelului este preluat de klogd (daemonul de logare al kernelului) care paseaza mai departe mesajul catre syslogd (deamonul pentru logare al sistemului). Fisierul "/etc/syslog.conf" controleaza comportamentul deamonului syslogd, specificand unde sa afiseze mesajele primite de la un anumit proces si nivelul de loggare al mesajului respectiv. De exemplu, pe sistemul meu, "/etc/syslog.conf" contine doua linii care specifica afisare mesajelor care se potrivesc cu "kern.info". kern.* -/var/log/kern.log *.=info;*.=notice;*.=warn;\ auth,authpriv.none;\ cron,daemon.none;\ mail,news.none -/var/log/messages Aceasta inseamna ca mesajele sunt duplicate in "/var/log/kern.log" si in "/var/log/messages". Pentru mai multe detalii, vezi "man syslogd.conf". 4.1.5.3. Schimbarea tos (type of service) Exista patru biti rar folositi in headerul IP, numiti biti tipul serviciului (TOS). Valorea acestor biti determina modul in care vor fi tratate pachetele; cei patru biti sunt "intarziere minima", "transmitere maxima", "maxima siguranta" si "cost minim". Doar unul dintre acesti biti este permis sa fie setat. Rob van Nieuwkerk, autorul codul de modificare al TOS, exemplifica: In special "intarziere minima" este important pentru mine. L-am setat pentru pachetele "interactive" de pe ruterul linux. Sunt in spatele unei legaturi de 33.6K. Linux da prioritate pachetelor in trei cozi de asteptare. In acest mod am o performanta pentru traficul interactiv in timp ce fac download-uri (ar fi putut merge mai repede, daca nu ar fi fost o asa coada de asteptare in driver-ul pentru portul serial, dar intarziere este acum de numai 1.5 secunde). Nota: evident, nu ai nici un control asupra pachetelor care vin; poti controla numai prioritatea pachetelor care pleaca. Pentru a negocia prioritatile cu celalalt capat este necesar un protocol ca RSVP (nu ma intrebati, nu cunosc nimic despre el). Cea mai intalnita folosire este setarea conexiunilor ftp si telnet "intarziere minima" si datelor FTP "transmitere maxima". Aceasta ar putea fi realizata dupa cum urmeaza: ipchains -A output -p tcp -d 0.0.0.0/0 telnet -t 0x01 0x10 ipchains -A output -p tcp -d 0.0.0.0/0 ftp -t 0x01 0x10 ipchains -A output -p tcp -s 0.0.0.0/0 ftp-data -t 0x01 0x08 Optiunea "-t" are doi parametri, amandoi in format hexazecimal. Aceaste argumete permite modificarea compleza a bitilor TOS: prima valoare si valoarea curenta a TOS-ului sunt adunate pe biti, apoi a doua valoare este XOR-uita cu aceasta. Daca aceasta este prea confuz, foloseste urmatoarea tabela: TOS Name Value Typical Uses Minimum Delay - intarziere minima 0x01 0x10 ftp, telnet Maximum Throughput - transmitere maxima 0x01 0x08 ftp-data Maximum Reliability - maxima siguranta 0x01 0x04 snmp Minimum Cost - cost minim 0x01 0x02 nntp Andi Kleen precizeaza urmatoarele: Poate ar fi folositor sa facem legatura cu parametrul txqueue-len al ifconfig in discutia despre biti TOS. Lungimea default a cozii de asteptare pentru interfata este optimizata pentru placile ethernet, pentru modemuri aceasta este prea lunga rezultand un randament scazut al planificarii in 3 benzi (in care punerea in lista de asteptare este realizata de catre TOS). Este o idee buna sa o setezi cu o valoare optima intre 4-10 pentru modem sau legaturi simple ISDN; pentru mai multe interfete o coada de asteptare mai lunga este necesara. Aceasta este o problema pentru kernelurile 2.0 si 2.1, dar in 2.1 este disponibila o optiune pentru ifconfig (cu o versiune recenta de nettools), pe cand in 2.0 sunt necesare patch-uri pentru codul sursa al driverelor. Deci, pentru a avea beneficii maxime din manipularea TOS pentru conexiuni PPP, da comanda "ifconfig $1 txqueuelen" in scriptul /etc/ppp/ip-up. Numarul care trebuie folosit depinde de viteza modemului si marimea bufferului; dupa cum spune si Andi: Cea mai optima valoare pentru o configuratie data trebuie experimentata. Daca listele de asteptare sunt prea scurte pe un ruter, atunci pachetele vor fi ignorate. Deasemenea exista beneficii chiar fara rescrierea TOS, rescriere TOS este folositoare pentru programele necooperante (dar toate programele standard ce folosesc Linux sunt cooperante). 4.1.5.4. Marcarea unui pachet Acest lucru permite interctiuni puternice si complexe cu noua implemetare Quality of Service apartinand lui Alex Kuznetsov, la fel ca si forwardarea bazata pe marcarea pachetelor in kernelurile versiunea 2.1 si mai avansate. Aceasta optiune este ignorata in ver. 2.0. 4.1.5.5. Operatii pentru un chain O foarte folositoare caracteristica a ipchains-ului este posibilitatea gruparii regulilor in chain-uri. Poti sa denumesti chain-urile cum doresti, atata timp cat nu intra in conflict cu chain-urile predefinite (input, output, forward) sau cu tintele (MASQ, REDIRECT, ACCEPT, DENY, REJECT sau RETURN). Recomand sa folosesti numirea chain-urile cu litere mari, deoarece voi folosi numele mari pentru viitoare extensii. Numele unui chain poate fi in lungime de pana la 8 caractere. 4.1.5.6. Crearea unui chain nou Sa creeam un chain nou cu numele de test. # ipchains -N test # Este simplu. Acum poti sa pui reguli in el in felul in care este prezentat mai sus. 4.1.5.7. Stergerea unui chain Stergerea unui chain este simpla de asemenea. # ipchains -X test # De ce "-X", pentru ca toate literele bune au fost folosite. Exista doua restrictii in ceea ce priveste stergerea de chain-uri: chain-ul trebuie sa fie gol (vezi "Stergerea tuturor regulilor unui chain" de mai jos) si nu trebuie sa fie tinta nici unei reguli. Nu poti sterge nici unul dintre chain-urile predefinite. 4.1.5.8. Stergerea tuturor regulilor unui chain Si acest lucru este simplu de realizat prin optiunea "-F", de exemplu: # ipchains -F forward # Daca nu specifici un chain atunci toate regulile vor fi sterse. 4.1.5.9. Listarea regulilor unui chain Poti lista toate regulile dintr-un chain folosind comanda "-L": # ipchains -L input Chain input (refcnt = 0): (policy ACCEPT) target prot opt source destination ports ACCEPT icmp ----- anywhere anywhere any # ipchains -L test Chain test (refcnt = 1): target prot opt source destination ports DENY icmp ----- localnet/24 anywhere any # "Refcnt-ul" afisat la listarea regulilor din chain-ul test, indica numarul de reguli care au ca tinta chain-ul test. Valoarea acesteia trebuie sa fie 0 (si chain-ul sa fie gol) inainte ca acest chain sa poata fi sters. Daca numele chain-ului este omis atunci toate chain-urile sunt listate chiar si cele goale. Sunt trei optiuni care pot fi folosite impreuna cu "-L". Optiunea "-n" (numeric) este foarte folositoare deorece impiedica ipchains sa incerce rezolvarea IP-lor in nume, care (daca folosesti ca majoritatea oamenilor DNS) va cauza mari intarzieri daca DNS-ul tau nu este configurat corect, sau ai filtrat cererile catre serverele DNS. Cauzeaza deasemenea afisarea porturilor sub forma de numere, mai degraba decat nume. Optiunea "-v" iti arata toate detaliile regulii, cum ar fii counter-ele de pachete si bytes, mask-urile TOS, interfetele si marcajul pachetelor. In caz contrar aceste optiuni sunt omise. De exemplu: # ipchains -v -L input Chain input (refcnt = 1): (policy ACCEPT) pkts bytes target prot opt tosa tosx ifname mark source destination ports 10 840 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any Observati ca valoarea countere-lor pentru pachete si bytes sunt afisate cu ajutorul sufixelor "K", "M" sau "G" pentru 1000, 1.000.000 si respectiv 1.000.000.000. Folosirea optiunii "-x" (expandeaza numerele) afiseaza numerele in format lung in ca bytes. 4.1.5.10. Resetarea (aducerea la 0) a counter-elor Este folositor sa ai posibilitatea de a reseta counter-ele. Aceasta se realizeaza cu ajutorul optiunii "-Z". De exemplu: # ipchains -v -L input Chain input (refcnt = 1): (policy ACCEPT) pkts bytes target prot opt tosa tosx ifname mark source destination ports 10 840 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any # ipchains -Z input # ipchains -v -L input Chain input (refcnt = 1): (policy ACCEPT) pkts bytes target prot opt tosa tosx ifname mark source destination ports 0 0 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any # Problema cand abordezi lucrurile in acest mod este ca uneori doresti sa vezi valorile counter-elor chiar inainte de a le reseta. In exemplul de mai sus, este posibil ca unele pachete sa fii trecut intre comenzile "-L" si "-Z". Din acest motiv este posibila folosirea impreuna a acestor comenzi, sa resetezi valoarea counter-elor chiar in momentul afisarii acestora. Din nefericire, daca faci asta, nu poti sa actionezi doar asupra unui singur chain, trebuie sa listezi si resetezi counter-ele pentru toate chain-urile. # ipchains -L -v -Z Chain input (policy ACCEPT): pkts bytes target prot opt tosa tosx ifname mark source destination ports 10 840 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any Chain forward (refcnt = 1): (policy ACCEPT) Chain output (refcnt = 1): (policy ACCEPT) Chain test (refcnt = 0): 0 0 DENY icmp ----- 0xFF 0x00 ppp0 localnet/24 anywhere any # ipchains -L -v Chain input (policy ACCEPT): pkts bytes target prot opt tosa tosx ifname mark source destination ports 10 840 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any Chain forward (refcnt = 1): (policy ACCEPT) Chain output (refcnt = 1): (policy ACCEPT) Chain test (refcnt = 0): 0 0 DENY icmp ----- 0xFF 0x00 ppp0 localnet/24 anywhere any # 4.1.5.11. Setarea policy-ului Am atins in treacat ce se intampla cand un pachet ajunge la capatul unuia dintre chain-urile predefinite, cand am discutat modul in care pachetele circula prin chain-uri, in capitolul de mai sus "Specificarea unei tinte". In acest caz, politica (policy-ul) chain-ului determina soarta pachetului. Doar chain-urile predefinite (input, output si forward) au policy, deoarece in chain-urile definite de catre utilizator cand se ajunge la capatul acestora, traversarea continua din chain-ul anterior. Policy-ul poate fi unul din primele patru tinte speciale: ACCEPT, DENY, REJECT sau MASQ. MASQ este valid doar pentru chain-ul "forward". Este deasemenea important sa observi ca tinta RETURN intr-o regula intr-unul din chain-urile predefinite este folositoare pentru a se folosi in mod special policy-ul chain-ului, cand un pachet se potriveste cu regula. 4.1.6. Operatii pentru masquerading Sunt cativa parametri pe care ii poti modifica in cazul masquerading-ului. Sunt legate de ipchains, pentru ca nu se merita scrierea unei noi comenzi pentru aceasta. Comanda pentru masqueradare este "-M", si poate fi combinata cu "-L" pentru a lista conexiunile care sunt in mod curent masqueradate, sau cu "-S" pentru a seta parametrii pentru masquerading. Comanda "-L" poate fi insotita de "-n" (afisarea de numere in loc de nume pentru adrese IP si porturi) sau "-v" (afiseaza deltas in numere succesive pentru conexiunile masquradate, doar in caz daca te intereseaza). Comanda "-S" ar trebui urmata de trei valori pentru timeout, fiecare valoare in secunde: pentru sesiunile TCP, pentru sesiunile TCP dupa un pachet FIN, si pentru pachete UDP. Daca nu doresti una din aceste valori, pur si simplu pune valoarea 0. Valorile default sunt listate in "/usr/src/linux/include/net/ip_masq.h" si sunt 15 minute, 2 minute si respectiv 5 minute. Cea mai intalnita valoare ce trebuie schimbata este prima, pentru FTP (vezi mai jos "FTP"). Observa problemele legate de setarea valorile pentru timeout in "Nu pot preciza timeout-uri pentru masquerading". 4.1.7. Verificarea unui pachet Uneori doresti sa vezi ce se intampla cand intra un anumit pachet, cum ar fi pentru testarea regulilor firewall-ului. ipchains are comanda "-C", ce permite acest lucru, folosind exact aceleasi rutine pe care le foloseste kernelul pentru diagnosticarea pachetelor reale. Poti stipula care chain sa testeze pachetul cu optiunea "-C" urmat de numele pachetului. In timp ce kernelul incepe intodeauna traversarea in chain-urile input, output sau forward, ai puterea sa incepi traversarea in orice chain in scopul testarii. Detaliile in ceea ce priveste "pachetul" sunt specificate folosind aceeasi sintaxa din specificarea regulilor. In special, protocolul "-p", adresa sursa "-s", adresa destinatie "-d", si interfata "-i" sunt obligatorii. Daca protocolul este TCP sau UDP, atunci un singur port destinatie si un singur port sursa trebuie specificat, daca protocolul este ICMP atunci trebuie specificat tipul si codul (doar daca nu este specificata optiunea "-f" pentru a preciza un fragment, caz in care aceste optiuni sunt ilegale). Daca protocolul este TCP (si optiunea "-f" nu este specificata), optiunea "-y" poate fi specificata, pentru a indica faptul ca pachetul de test are bitul SYN pus. Dam mai jos un exemplu de testare a unui pachet ce vine de la 192.168.1.1, portul 60000 catre 192.168.1.2, portul www, intrand prin interfata eth0, in chain-ul "input". Acesta este un caz clasic de initiere a unei conexiuni www: # ipchains -C input -p tcp -y -i eth0 -s 192.168.1.1 60000 -d 192.168.1.2 www packet accepted # 4.1.8. Mai multe reguli dintr-o data si ceea ce se intampla atunci Uneori o singura linie de comanda poate produce mai multe efecte. Aceasta se realizeaza in doua moduri. Intai, poti sa specifici un hostname care este rezolvat (folosind DNS) in mai multe adrese IP, ipchains se va comporta ca si cum ai fi dat mai multe comenzi pentru fiecare adresa IP in parte. De exemplu, daca hostname-ul "www.foo.com" este rezolvat in trei adrese IP, si hostname-ul "www.bar.com" in doua adrese IP, atunci comanda "ipchains -A input -j reject -s www.bar.com -d www.foo.com" ar fi echivalenta cu introducerea a sase reguli diferite in chain-ul input, daca s-ar folosi adrese IP. Un alt mod prin care sa determini ipchains sa realizeze mai multe actiuni este prin folosirea optiunii bidirectionale "-b". Aceasta optiune determina ipchains sa se comporte ca si cum ai fi dat comanda de doua ori, insa a doua oara cu parametrii de la sursa si destinatie inversati. De exemplu, pentru a evita forwardarea catre sau de la 192.168.1.1: # ipchains -b -A forward -j reject -s 192.168.1.1 # Personal, nu imi place prea mult aceasta optiune "-b"; daca doresti utilitate citeste "Folosirea ipchains-save" de mai jos. Optiunea "-b" poate fi folosita langa comenzile de introducere de reguli ("-I"), stergere ("-D") (dar nu varianta care accepta un numar al unei reguli), adaugare ("-A") si verificare ("-C"). O alta optiune folositoare este "-v" care iti afiseaza exact ceea ce ipchains realizeaza prin comenzile date. Acest lucru este folositor daca folosesti comenzi ce pot avea efectul a mai multor reguli. De exemplu, aici verificam comportamentul fragmentelor intre 192.168.1.1 si 192.168.1.2. # ipchains -v -b -C input -p tcp -f -s 192.168.1.1 -d 192.168.1.2 -i lo tcp opt ---f- tos 0xFF 0x00 via lo 192.168.1.1 -> 192.168.1.2 * -> * packet accepted tcp opt ---f- tos 0xFF 0x00 via lo 192.168.1.2 -> 192.168.1.1 * -> * packet accepted # 4.2. Exemple folositoare Am o conexiune dialup PPP (-i ppp0). Citesc stirile (-p TCP -s news.virtual.net.au nntp) si mail-ul (-p TCP -s mail.virtual.net.au pop-3) de fiecare data cand ma conectez. Folosesc metoda de FTP a Debianului pentru a-mi updata sistemul regulat (-p TCP -y -s ftp.debian.org.au ftp-data). Navighez pe web cu ajutorul proxy-ului ISP-ului atata timp cat acesta merge (-p TCP -d proxy.virtual.net.au 8080), dar nu suport bannerele de la doubleclick.net in arhivele Dilbert (-p TCP -y -d 199.95.207.0/24 and -p TCP -y -d 199.95.208.0/24). Nu ma deranjeaza ca oameni sa incerce sa faca ftp pe masina mea cat timp sunt online (-p TCP -d $LOCALIP ftp), dar nu vreau ca nimeni din exterior sa pretinda ca are una din adresele retelei mele interne (-s 192.168.1.0/24). Acest lucru este numit spoofare IP, si exista o modalitate mai buna de a te proteja impotriva acesteia in kernelurile 2.1.x si mai avansate: citeste "Cum realizez protectia impotriva spoofarii IP". Aceasta configurare este destul de simpla, pentru ca nu sunt in mod curent alte hosturi in reteaua mea interna. Doresc ca nici un proces local (ex. lynx, netscape) sa se conecteze la doubleclick.net: # ipchains -A output -d 199.95.207.0/24 -j REJECT # ipchains -A output -d 199.95.208.0/24 -j REJECT # Acum doresc sa realizez prioritati asupra a pachete variate ce pleaca (nu prea are sens sa fac acest lucru pentru pachetele ce intra). Cum am un numar mai mare de acest tip de reguli, are sens sa le pun pe toate intr-un singur chain, numit ppp-out. # ipchains -N ppp-out # ipchains -A output -i ppp0 -j ppp-out # Intarziere minima pentru traficul www si telnet. # ipchains -A ppp-out -p TCP -d proxy.virtual.net.au 8080 -t 0x01 0x10 # ipchains -A ppp-out -p TCP -d 0.0.0.0/0 telnet -t 0x01 0x10 # Cost minim pentru canalul de date ftp, nntp, si pop3: # ipchains -A ppp-out -p TCP -d 0.0.0.0/0 ftp-data -t 0x01 0x02 # ipchains -A ppp-out -p TCP -d 0.0.0.0/0 nntp -t 0x01 0x02 # ipchains -A ppp-out -p TCP -d 0.0.0.0/0 pop-3 -t 0x01 0x02 # Sunt cateva restrictii pentru pachetele ce vin prin interfata ppp0: se cream atunci un chain numit "ppp-in": # ipchains -N ppp-in # ipchains -A input -i ppp0 -j ppp-in # Acum, nici un pachet care vine prin interfata ppp0, nu are voie sa pretinda ca are adresa sursa 192.168.1.*, asa ca le igoram si le logam: # ipchains -A ppp-in -s 192.168.1.0/24 -l -j DENY # Permit pachetele catre DNS (rulez un server de nume care inainteaza toate cererile catre 203.29.16.1, asa ca ma astept la pachete replica DNS doar de acolo, pachete catre portul ftp, si doar canalul de date pentru conexiunile ftp in exterior (care ar trebui sa fie doar pe un port peste 1023, si pe porturile pentru X11 in jur de 6000). # ipchains -A ppp-in -p UDP -s 203.29.16.1 -d $LOCALIP dns -j ACCEPT # ipchains -A ppp-in -p TCP -s 0.0.0.0/0 ftp-data -d $LOCALIP 1024:5999 -j ACCEPT # ipchains -A ppp-in -p TCP -s 0.0.0.0/0 ftp-data -d $LOCALIP 6010: -j ACCEPT # ipchains -A ppp-in -p TCP -d $LOCALIP ftp -j ACCEPT # Accept replay-urile la pachetele TCP: # ipchains -A ppp-in -p TCP ! -y -j ACCEPT # In sfarsit conexiunile locale sunt ok: # ipchains -A input -i lo -j ACCEPT # Acum, politica default in chain-ul input este DENY, astfel incat orice altceva este ignorat: # ipchains -P input DENY # Observatie: Nu mi-as configura chain-urile in aceasta ordine, deoarece pachetele ar putea sa treaca in timp ce introduc regulile. Cel mai sigur este sa setezi politica DENY intai, apoi sa introduci regulile. Bineinteles, daca regulile tale au nevoie de cereri DNS pentru a rezolva numele, s-ar putea sa fi in necaz. 4.2.1. Folosirea ipchains-save Configurarea regulilor pentru firewall in modul in care doresti, si apoi sa incerci sa memorezi comenzile pe care le-ai folosit ca sa faci acelasi lucru din nou este chinuitor. Asa ca, ipchains-save este un script care citeste configuratia curenta a chain-urilor si le salveaza intr-un fisier. Deocamdata te tin in suspans cu privire la ce realizeaza ipchains-retore. ipchains-save poate salva un singur chain, sau toate chain-urile (daca nici un nume de chain, nu este specificat). Singura optiune permisa este "-v" care afiseaza regulile pe masura ce acestea sunt salvate. Politica acestor chain-uri este deasemenea salvata pentru chain-urile input, output si forward. # ipchains-save > my_firewall Saving `input'. Saving `output'. Saving `forward'. Saving `ppp-in'. Saving `ppp-out'. # 4.2.2. Folosirea ipchains-restore ipchains-restore restaureaza chain-urile salvate cu ipchains-save. Poate avea doua optiuni: "-v" care afiseaza fiecare regula pe masura ce este adaugata, si "-f" care obliga stergerea chain-urile definite de catre utilizator daca exista, in modul descris mai jos. Daca este gasit un chain definit de utilizator este gasit in fisierul din care se restaureaza regulile, ipchains verifica daca nu exista deja acel chain. Daca exista, atunci vei fi intrebat daca fie chain-ul respectiv sa fie golit de reguli, fie sa fie sarit. Daca specifici "-f" in linia de comanda, nu vei mai fi intrebat, chain-ul va fi golit de reguli. De exemplu: # ipchains-restore < my_firewall Restoring `input'. Restoring `output'. Restoring `forward'. Restoring `ppp-in'. Chain `ppp-in' already exists. Skip or flush? [S/f]? s Skipping `ppp-in'. Restoring `ppp-out'. Chain `ppp-out' already exists. Skip or flush? [S/f]? f Flushing `ppp-out'. # 5. Diverse Aceasta parte contine toate informatiile si FAQ-urile pe care nu am putut sa le introduc in structura de mai sus. 5.1. Cum sa iti organizezi regulile firewall-ului Aceasta intrebare cere putina gandire. Poti incerca sa le organizezi pentru a optimiza viteza (minimizezi numarul de reguli pentru cele mai comune pachete) sau sa cresti manevrabilitatea. Daca ai o legatura care se intrerupe, sa spunem o conexiune PPP, ai putea dori ca prima regula in chain-ul input sa fie "-i ppp0 -j DENY" in timpul bootarii, apoi sa ai ceva de genul acesta in scriptul ip-up: # Re-create the `ppp-in' chain. ipchains-restore -f < ppp-in.firewall # Replace DENY rule with jump to ppp-handling chain. ipchains -R input 1 -i ppp0 -j ppp-in Scriptul ip-down ar arata astfel: ipchains -R input 1 -i ppp0 -j DENY 5.2. Ce anume sa nu filtrezi spre afara Sunt cateva lucruri de care trebuie sa fi constient inainte de a incepe filtrarea pachetelor pe care nu le doresti. 5.2.1. Pachete icmp ICMP este folosit (printre alte lucruri) pentru a indica esecul alte protocoale (cum ar fi TCP si UDP). Pachetele "destination-unreachable" in special. Blocarea acestor pachete inseamna ca niciodata nu vei avea erori de genul "Host unreachable" sau "No route to host"; orice conexiune doar va astepta o replica (replay) care nu va veni niciodata. Aceasta este iritabil, dar rar fatal. O problema mai grava este rolul ICMP in descoperirea MTU-ului. Toate implementarile bune TCP (Linux este inclus) folosesc descoperirea MTU pentru a incerca sa isi dea seama care este marimea maxima a unui pachet care poate ajunge la destinatie fara sa fie fragmentat (fragmentarea incetineste performanta, in special cand fragmente ocazionale sunt pierdute). Descoperirea MTU functioneaza prin transmiterea de pachete cu bit "nu fragmenta" pus, si apoi transmiterea de pachete mai mici daca primeste replica ICMP indicand ca este necesarea fragmentarea. Acesta este un tip de pachet "destination-unreachable", si daca nu este primit, sistemul nu isi va reduce MTU-ul, si performantele nu vor exista. Observa faptul ca este comun sa blochezi toate pachetele ICMP de redirectare (de tip 5); aceastea pot fi folosite pentru a manvevra rutarea (deasemenea stive bune IP au masuri de protectie), asa ca sunt vazute ca risc minim. 5.2.2. Conexiunile TCP catre servere DNS (servere de nume) Daca incerci sa blochezi conexiunile TCP catre exterior, tine minte ca DNS nu foloseste intodeauna UDP; daca raspunsul de la server depaseste 512 bytes, clientul foloseste o conexiune TCP (tot spre portul 53) pentru date. Aceasta poate fi o capcana deoarece DNS va merge in mare parte. Daca nu permiti asemenea transferuri TCP; este posibil sa experimentezi intarzieri mari si alte probleme ocazionale DNS. Daca aceste cereri DNS sunt intodeauna catre aceeasi sursa externa (fie direct prin folosirea liniei de nameserver din /etc/resolv.conf, fie folosind un nameserver pentru cache in mod forward), atunci ai nevoie doar sa permiti conexiunile TCP catre portul 53 pe acel nameserver de la portul local 53 (in caz in care folosesti nameserver pentru cache) sau de la un port local (>1023) daca folosesti /etc/resolv.conf. 5.2.3. FTP Problema clasica a filtrului de pachete este FTP. FTP are doua moduri; cel traditional care este numit mod activ, si cel mai recent care este numit ftp pasiv. Browsere-le web folosesc de obicei default modul pasiv, pe cand ftp-urile din linia de comanda modul activ. In mod activ, cand celalalt capat doreste sa trimita un fisier (sau chiar ca rezultat a unei comenzi ls sau dir) incerca sa deschida o conexiune TCP catre masina locala. Asta inseamna ca nu poti sa filtrezi aceste conexiuni TCP fara sa impiedici conexiunile ftp active. Daca ai posibilitatea sa folosesti ftp pasiv, atunci este bine; modul pasiv creaza conexiuni TCP de la client la server, chiar si pentru datele care vin. In caz contrar, este recomandat sa lasi conexiunile TCP pe porturile locale mai mari de 1024 si nu intre 6000 si 6010 (6000 este folosit de X). 5.3. Filtrarea Pingului Mortii Sistemele Linux sunt acum imune la celebrul Ping al Mortii, care presupune trimiterea de pachetele ICMP anormal de mari care umple bufferele in stiva TCP de pe sistem cauzand blocarea acestuia. Daca protejezi sisteme care ar putea fi vulnerabile, poti in mod simplu sa ignori fragmentele ICMP. In mod normal pachetele ICMP nu sunt atat de mari pentru a fi nevoie de fragmentarea acestora, asa ca nu va influenta nimic in rau, exceptand ping-urile cu pachete de marime mare. Am auzit (neconfimat) rapoarte cum ca pentru unele sisteme ar fi suficient numai ultimul fragment al unui asemenea pachet ICMP, pentru a bloca sistemul, deci blocarea numai a primului fragment nu este recomandata. In timp ce exploiturile pe care le-am vazut foloseau numai protocolul ICMP pentru aceste atacuri, nu exista nici un motiv pentru care TCP si UDP sa nu fie folosit in acelasi mod, asa ca blocarea fragmentelor ICMP este doar o solutie temporara. 5.4. Filtrarea pentru Teardrop si Bonk Teardrop si Bonk sunt doua tipuri de atacuri (in principal asupra masinilor ce ruleaza Windows NT) care se bazeaza pe fragmente ce se suprapun partial. Acestea pot fi oprite prin configurarea sistemului Linux sa realizeze defragmentare sau sa nu permita fragmente catre sistemele vulnerabile. 5.5. Filtrarea fragmentelor in masa Cateva stive TCP mai putin sigure se spune ca au probleme in ceea ce priveste numarul mare de fragmente de pachete, atunci cand nu primesc toate fragmentele. Linux nu are aceasta problema. Poti filtra aceste fragmente (care pot sa impiedice folosirea lor legitima) sau sa compilezi kernelul cu optiunea "IP: always defragment" setata "Y" (doar daca sistemul tau linux este singura ruta pentru aceste pachete). 5.6. Schimbarea regulilor din firewall Sunt cateva probleme legate de viteza cu care pot fi schimbate regulile din firewall. Daca nu esti atent, poti sa lasi pachete sa intre cand esti la jumatatea acestor modificari. O rezolvare simpla ar fi: # ipchains -I input 1 -j DENY # ipchains -I output 1 -j DENY # ipchains -I forward 1 -j DENY ... realizeaza modificari ... # ipchains -D input 1 # ipchains -D output 1 # ipchains -D forward 1 # Se ignora astfel toate pachetele pe durata modificarilor. Daca schimbarile tale sunt doar intr-un singur chain, ai putea crea un nou chain cu noile reguli, si apoi sa inlocuiesti ("-R") regula care facea referire la vechiul chain cu o noua regula catre noul chain: apoi poti sa stergi vechiul chain. Aceasta inlocuire va fi automata. 5.7. Cum realizez protectia impotriva spoofarii IP Spoofarea IP este o tehnica in care un host trimite pachete care pretind ca sunt de la un alt host. Cum filtrarea de pachete ia decizii bazandu-se pe adresa sursa, spoofarea IP este folosita pentru a pacali filtrele de pachete. Este folosita deasemenea pentru a ascunde identitatea atacatorilor care folosesc atacuri SYN, Teardrop, Ping of Death si similare (nu iti face griji daca nu stii ce inseamna). Cea mai buna cale de a te proteja contra spoofarii este Verificarea adresei sursa, si este realizata de catre codul de rutare, si deloc de catre cel al firewall-ului. Verifica existenta fisierului /proc/sys/net/ipv4/conf/all/rp_filter. Daca exista, atunci pornirea Verificarii adresei sursa este solutia potrivita pentru tine. Pentru a realiza acest lucru, introduce urmatoarele linii undeva in scripturile de pornire, inainte de initializarea oricarei interfete de retea: # Aceastea este cea mai buna metoda: # da drumu la Verificarea adresei sursa si ai protectie anti-spoof # pentru toate interfetele curente si viitoare. if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]; then echo -n "Setting up IP spoofing protection..." for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f done echo "done." else echo PROBLEMS SETTING UP IP SPOOFING PROTECTION. BE WORRIED. echo "CONTROL-D will exit from this shell and continue system startup." echo # Start a single user shell on the console /sbin/sulogin $CONSOLE fi (nt. sau in fisierul sysctl.conf adauga: # Controls source route verification net.ipv4.conf.default.rp_filter = 1 ) Daca nu poti realiza acest lucru, atunci poti in mod manual sa introduci reguli pentru a proteja fiecare interfata. Aceasta cere insa cunoasterea fiecarei interfete. Kernelurile 2.1 rejecteaza automat pachetele care pretind a veni de la adresele 127.* (rezervate pentru interfata loopback, lo). De exemplu, sa presupunem ca avem trei interfete, eth0, eth1 si ppp0. Folosim ifconfig pentru a vedea adresele interfetelor si netmaskul acestora. Sa zicem ca eth0 este atasata unei retele 192.168.1.0 cu netmask-ul 255.255.255.0, eth1 apartine unei retele 10.0.0.0 cu netmask 255.0.0.0, si ppp0 este conectata la Internet (unde orice adrese, exceptand cele din clasele private, sunt permise). Introducem regulile: # ipchains -A input -i eth0 -s ! 192.168.1.0/255.255.255.0 -j DENY # ipchains -A input -i ! eth0 -s 192.168.1.0/255.255.255.0 -j DENY # ipchains -A input -i eth1 -s ! 10.0.0.0/255.0.0.0 -j DENY # ipchains -A input -i ! eth1 -s 10.0.0.0/255.0.0.0 -j DENY # Aceasta rezolvare a problemei nu este atat de buna cum este Verificarea adresei sursa, deoarece daca reteaua se schimba, trebuie sa iti modifici regulile din firewall. Daca ai un kernel ver 2.0, ai dori sa iti protejezi chiar si interfata loopback: # ipchains -A input -i ! lo -s 127.0.0.0/255.0.0.0 -j DENY # 5.8. Proiecte mai avansate Exista o biblioteca pe care am scris-o, inclusa in distributia surselor numita "libfw". Aceasta foloseste posibilitatea din IP Chains ver 1.3 si peste, de a copia un pachet pentru a putea fi folosit in mediul utilizator (folosind optiunea IP_FIREWALL_NETLINK). Valorea cu care este marcat pachetul poate fi folosita pentru a specifica parametrii de Calitate a serviciului pentru pachete, sau pentru a specifica cum ar trebui sa fie facuta forwardarea de porturi pentru pachete. Nu am folosit nici una dintre acestea, dar daca ai vreo observatie contacteaza-ma. Lucuri cum ar fi verificarea dupa stare (prefer termenul de firewall dinamic) pot fi implementate in mediul utilizator prin folosirea acestei biblioteci. Alta idee mai interesanta ar fi controlarea pachetelor intr-un mediu utilizator cu ajutorul unui daemon, destul de usor de realizat. 5.8.1. SPF: filtrare dupa starea pachetului (stateful packet filtering) ftp://ftp.interlinx.bc.ca/pub/spf este site-ul proiectului SPF, apartinand lui Brian Murrell, care realizeaza urmarirea conexiunile in mediu utilizator. Se adauga astfel securitate simnificativa pentru site-uri cu banda limitata. In prezent nu este disponibila multa documentatie, dar iata postari pe o lista de discutii in care Brian raspunde la niste intrebari: > cred ca se realizeaza exact ce doresc. Intra in functiune o regula > temporara pentru a permite intrarea pachetele ce vin ca raspuns la o > cerere anterioara Da, exact asta se realizeaza. Cu cat este mai compatibil cu mai multe protocoale, cu atat regula temporara este corecta. Pentru moment suporta (din cate imi amintesc, scuzati eventualele erori sau omisiuni) FTP (atat activ, cat si pasiv, inautru sau spre exterior), RealAudio, traceroute, ICMP si ICQ simplu (conexiuni dinspre servere ICQ, si conexiuni TCP directe, dar conexiuni secundare directe TCP pentru lucruri ca transferul de fisiere, nu sunt inca realizate) > este un inlocuitor pentru ipchains sau un lucru suplimentar? Este un lucru suplimentar. Gandeste-te la ipchains ca la un engine care permite sau interzice pachetelor traversarea printr-un sistem linux. SPF este driver-ul, care monitorizeaza constant traficul si comunica ipchains-ului ce anume sa schimbe in reguli pentru a permite un anumit tip de trafic. 5.8.2. "Hack-ul" ftp-data al lui Michael Hasenstein Michael Hasenstein, de la SuSE, a scris un patch de kernel care adauga urmarirea conexiunilor ftp pentru ipchains. Poate fi gasit la http://www.suse.de/~mha/patch.ftp-data-2.gz . 5.9. Planuri de viitor Realizarea de firewall si NAT-ul au fost rescrise pentru 2.4. Planuri si discutii sunt disponibile pe lista de discutii de la netfilter (vezi http://lists.samba.org ). Aceste versiuni noi ar trebui sa rezolve multe dintre problemele actuale de utilizare (realizarea de masquerading si firewall nu ar trebui sa fie asa de grea) si sa permite dezvoltarea de firewall-uri mai flexibile. 6. Probleme des intalnite 6.1. ipchains -L ingheata! Probabil ca ai blocate cererile catre DNS; eventual va da timeout. Incearca sa folosesti optiunea "-n" (numeric), care previne ipchains sa rezolve numele. 6.2. Specificarea inversa nu poate fi realizata! Trebuie sa pui semnul "!" singur, cu spatii de o parte si de alta. O greseala clasica este: # ipchains -A input -i !eth0 -j DENY # Nu va exista niciodata o interfata numita "!eth0", dar ipchains nu isi da seama de acest lucru. 6.3. Masqueradarea/Forwardarea nu se realizeaza! Verifica daca forwardarea pentru pachete este setata (in kernelurile recente default este scos, insemnand ca pachetele nici macar nu vor incerca sa traverseze chain-ul "forward"). Poti sa ii pornesti aceasta facilitate prin: # echo 1 > /proc/sys/net/ipv4/ip_forward # Daca aceasta comanda functioneaza, o poti pune intr-unul din scripturile ce ruleaza la bootare, pentru a avea tot timpul aceasta facilitate; desi vei dori sa iti configurezi firewall-ul, in caz contrar exista posibilitatea ca unele pachete sa treaca. 6.4. Tinta -j REDIR nu merge! Trebuie sa permiti forwardarea de pachete (citeste mai sus) pentru ca redirectarea sa fie posibila; altfel codul de rutare ignora pachetul. Asa ca daca folosesti doar redirect, si nu ai forwarding-ul setat, ar trebui sa iti dai seama ca este de la asta. Observa ca REDIR (fiind in chain-ul input) nu afecteaza conexiunile catre procesele locale. 6.5. Specificare mai multor interfete (ex "-i ppp+") nu merge! Exista un defect de programare in kernelurile ver. 2.1.102 si 2.1.103 (si in unele patch-uri mai vechi pe care le-am relizat) care determina comanda ipchains de specificare a mai multor interfete (ex "-i ppp+") sa nu mearga. Acest lucru a fost indreptat in kernelurile recente si in patch-ul 2.0.34 de pe site-ul web. Poti deasemenea sa il indrepti manual, in sursele kernelului modificand linia 63 din fisierul include/linux/ip_fw.h: #define IP_FW_F_MASK 0x002F /* All possible flag bits mask */ In loc de 0x002F ar trebui sa fie "0x003F". Modifica si recompileaza kernelul. 6.6. TOS nu merge! Aceasta este greseala mea: setarea campului TOS nu a setat in realitate TOS in kernelurile ver. 2.1.102 pana la 2.1.111. Aceasta problema a fost rezolvata in 2.1.112. 6.7. ipautofw si ipportfw nu merg! Pentru 2.0.x, aceasta este adevarat; nu am avut timp pentru a crea si mentine un patch pentru ipchains si ipautofw/ipportfw. Pentru 2.1.x, downloadeaza ipmasqadm al lui Juan Ciarlante de la: si foloseste-l la fel ca si cum ai fi folosit ipautofw si ipportfw, cu exceptia faptului ca in loc de ipportfw tastezi ipmasqadm portfw, si in loc de ipautofw tastezi ipmasqadm autofw. 6.8. xosview este stricat! Fa upgrade la versiunea 1.6.0 sau mai avansata, unde nu este necesar nici un fel de reguli in firewall pentru kernelurile 2.1.x. Se pare ca iar nu functioneaza in ver. 1.6.1.; te rog contacteaza autorul (nu este greseala mea!). 6.9. Segmentation Fault din cauza tintei "-j REDIRECT"! Acesta este o eroare de programare in ipchains, ver. 1.3.3. Upgrade. 6.10. Nu pot preciza valori de timeout pentru masquerading! Este adevarat (pentru kernelurile 2.1.x) pana la ver. 2.1.123. In 2.1.124, incercarea de a seta valori pentru timeout-ul din masqueradig cauza o blocare a kernelului (schimba return cu ret la linia 1328 din fisierul net/ipv4/ip_fw.c). In 2.1.125, functioneaza cum trebuie. 6.11. Vreau sa filtrez IPX! Asta se pare ca vor si altii. Din pacate codul meu acopera doar IP. Insa, exista posibilitatea pentru a filtra IPX! Trebuie doar sa scrii codul, te voi ajuta unde este posibil. 7. Un exemplu serios Acest exemplu a fost luat de la Michael Neuling si tutorialul meu din LinuxWorld din Martie 1999; acesta nu este singura cale pentru a rezova problema data, dar este probabil cea mai simpla. Sper ca o sa o gasesti interesanta. 7.1. Topologia retelei - O retea interna masqueradata (sisteme de operare variate), pe care o numim "GOOD". - Servere expuse intr-o retea separata (numita "DMZ" de la zona demilitarizata). - Conexiunea PPP catre Internet (numita "BAD"). Retea externa (BAD) | | ppp0| --------------- | 192.84.219.1| Reteaua de servere (DMZ) | |eth0 | |---------------------------------------------- | |192.84.219.250 | | | | | | | | |192.168.1.250| | | | --------------- -------- ------- ------- | eth1 | SMTP | | DNS | | WWW | | -------- ------- ------- | 192.84.219.128 192.84.219.129 192.84.218.130 | Retea interna (GOOD) 7.2. Scopurile Filtrul de pachete de pe ruter: PING orice retea Aceasta este folositor pentru a verifica daca un sistem este oprit. TRACEROUTE orice retea Inca odata, folositor pentru analize. Acces DNS Pentru a face ping-ul si DNS-ul mai folositor In cadrul DMZ: Serverul de mail (SMTP): - SMTP catre exterior - Permiterea accesului SMTP din interior si exterior - Permiterea accesului POP3 din interior. Serverul de nume (DNS): - Trimitere de pachete DNS catre exterior - Permiterea accesului DNS din reteaua interna, externa si de pe ruter. Serverul WWW: - Permiterea accesului http din exterior si interior - Permiterea accesului rsync din interior Reteaua interna: Permiterea accesului www, ftp, ssh si traceroute Aceastea sunt lucruri permise destul de standard, in unele locuri sistemele au voie sa faca orice, dar aici vom fi mai restrictivi. Permiterea accesului SMTP catre serverul de mail Evident, dorim ca sa aiba posibilitatea sa trimita mailuri. Permiterea accesului POP3 catre serverul de mail In acest mod isi pot citi mail-ul. Permiterea accesului DNS catre nameserver Au nevoie de posibilitatea de a rezolva numele externe pentru www, ssh, ftp, si traceroute. Permiterea accesului rsync catre serverul de web Acesta este modul prin care vor sincroniza serverul extern de web cu cel intern. Permiterea accesului WWW catre serverul de WEB Evident, trebuie sa poata fi accesat serverul nostru extern de web. Permiterea ping-ului catre ruter Pentru a realiza daca este jos ruterul, ca sa nu dea vina pe noi daca un server extern este jos. 7.3. Inainte de realizarea filtrarii de pachete - Anti-spoofing Cum nu avem de a face cu rutare asimetrica, putem in mod simplu sa dam drumul la anti-spoofing pentru toate interfetele. # for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f; done # - Configurarea filtrului de pachete sa interzica (DENY) toate pachetele Permitem insa traficul pentru interfata loopback, dar nu permiterm nimic alceva. # ipchains -A input -i ! lo -j DENY # ipchains -A output -i ! lo -j DENY # ipchains -A forward -j DENY # - Configurarea interfetelor Aceasta este de obicei realizata in scripturile de initializare. Fii sigur ca pasii de mai sus sunt realizati inainte de configurarea interfetelor, pentru a preveni scaparea eventualelor pachete. - Introduce modulele de masquerading specifice protocolului Este necesar sa introducem modulul de masquerading pentru FTP, astfel incat ftp activ si pasiv sa fie disponibile din reteaua interna. # insmod ip_masq_ftp # 7.4. Filtrarea de pachete pentru pachetele directe Deorece se realizeaza masquerading, cel mai bine este sa le filtrezi in chain-ul forward. Imparte chain-ul forward in diferite chain-uri definite de catre utilizator in functie de interfata sursa/destinatie; aceasta abordare imparte problema in bucati. ipchains -N good-dmz ipchains -N bad-dmz ipchains -N good-bad ipchains -N dmz-good ipchains -N dmz-bad ipchains -N bad-good Acceptarea erorile standard ICMP este un lucru obisnuit, asa ca specificam un chain pentru acestea. ipchains -N icmp-acc 7.4.1. Trecerea spre alte chain-uri din chain-ul forward Din nefericire, in chain-ul forward cunoastem doar interfata de iesire. De aceea, pentru a realiza interfata pe unde a intrat pachetul, ne folosim de adresa sursa (facilitatea anti-spoofing previne adresele sursa false). Observa ca logam toate pachetele cu adresa sursa falsa (evident, aceasta nu ar trebui sa se intample niciodata). ipchains -A forward -s 192.168.1.0/24 -i eth0 -j good-dmz ipchains -A forward -s 192.168.1.0/24 -i ppp0 -j good-bad ipchains -A forward -s 192.84.219.0/24 -i ppp0 -j dmz-bad ipchains -A forward -s 192.84.219.0/24 -i eth1 -j dmz-good ipchains -A forward -i eth0 -j bad-dmz ipchains -A forward -i eth1 -j bad-good ipchains -A forward -j DENY -l 7.4.2. Definirea chain-ului icmp-acc Pachetele care sunt erori ICMP sunt acceptate, in caz contrar, traversarea va continua din chain-ul anterior. ipchains -A icmp-acc -p icmp --icmp-type destination-unreachable -j ACCEPT ipchains -A icmp-acc -p icmp --icmp-type source-quench -j ACCEPT ipchains -A icmp-acc -p icmp --icmp-type time-exceeded -j ACCEPT ipchains -A icmp-acc -p icmp --icmp-type parameter-problem -j ACCEPT 7.4.3. Reguli pentru conexiuni reteaua interna ==> DMZ Restrictii interne: - Este permis accesul WWW, ftp, traceroute, ssh catre exterior - Este permis accesul accesul SMTP catre serverul de mail - Este permis accesul pop3 catre serverul de mail - Este permis accesul DNS la namerserver - Este permis rsync catre serverul de Web - Este permis accesul WWW catre serverul de Web - Este permis ping catre ruter Am putea sa realizam masquerading din reteaua interna catre DMZ, dar nu facem acest lucru. Cum nimeni din reteaua interna nu ar trebui sa incerce sa faca lucruri rele, logam toate pachetele ce sunt interzise. Observati ca in versiunile mai vechi de Debian numesc "pop3" "pop-3" care nu respecta RFC1700. ipchains -A good-dmz -p tcp -d 192.84.219.128 smtp -j ACCEPT ipchains -A good-dmz -p tcp -d 192.84.219.128 pop3 -j ACCEPT ipchains -A good-dmz -p udp -d 192.84.219.129 domain -j ACCEPT ipchains -A good-dmz -p tcp -d 192.84.219.129 domain -j ACCEPT ipchains -A good-dmz -p tcp -d 192.84.218.130 www -j ACCEPT ipchains -A good-dmz -p tcp -d 192.84.218.130 rsync -j ACCEPT ipchains -A good-dmz -p icmp -j icmp-acc ipchains -A good-dmz -j DENY -l 7.4.5. Reguli pentru conexiuni din reteaua interna ==> reteaua externa Restrictionare in reteaua DMZ numai la: - serverul de mail: - SMTP catre exterior - acceptare acces SMTP din interior si exterior - acceptare acces pop3 din interior - serverul de nume: - trimitere cereri DNS catre exterior - acceptarea acces DNS din reteaua interna, externa si ruter - serverul de web: - acceptare acces HTTP din exterior si interior - acceptare acces rsync din interior Lucruri pe care le permitem din Internet catre DMZ - nu logam violarile, deoarece se pot intampla. ipchains -A bad-dmz -p tcp -d 192.84.219.128 smtp -j ACCEPT ipchains -A bad-dmz -p udp -d 192.84.219.129 domain -j ACCEPT ipchains -A bad-dmz -p tcp -d 192.84.219.129 domain -j ACCEPT ipchains -A bad-dmz -p tcp -d 192.84.218.130 www -j ACCEPT ipchains -A bad-dmz -p icmp -j icmp-acc ipchains -A bad-dmz -j DENY 7.4.5. Reguli pentru conexiuni din reteaua interna ==> reteaua externa Restrictionare in reteaua interna numai la: - permiterea in exterior traficului WWW, ftp, traceroute, ssh - acceptare acces SMTP catre serverul de mail - acceptare acces POP-3 catre serverul de mail - acceptare acces DNS catre nameserver - acceptare acces rsync catre nameserver - acceptare acces WWW catre serverul de web - acceptare ping catre ruter - logare a violarilor - porturile UDP destinatie 33434 sunt permise si folosite de traceroute Multi oameni permit totul din reteaua locala, noi nu. Ftp pasiv este utilizat cu ajutorul modulului de masquerading. ipchains -A good-bad -p tcp --dport www -j MASQ ipchains -A good-bad -p tcp --dport ssh -j MASQ ipchains -A good-bad -p udp --dport 33434:33500 -j MASQ ipchains -A good-bad -p tcp --dport ftp -j MASQ ipchains -A good-bad -p icmp --icmp-type ping -j MASQ ipchains -A good-bad -j REJECT -l 7.4.6. Reguli pentru conexiuni din DMZ ==> reteaua interna Restrictionare in reteaua interna numai la: - permiterea in exterior traficului WWW, ftp, traceroute, ssh - acceptare acces SMTP catre serverul de mail - acceptare acces POP-3 catre serverul de mail - acceptare acces DNS catre nameserver - acceptare acces rsync catre nameserver - acceptare acces WWW catre serverul de web - acceptare ping catre ruter Daca realizam masquerading din reteaua interna catre DMZ, pur si si simplu refuzam pachetele ce vin din cealalta parte. Astfel, permitem pachetele care nu pot fi decat parte a unei conexiuni stabilite. ipchains -A dmz-good -p tcp ! -y -s 192.84.219.128 smtp -j ACCEPT ipchains -A dmz-good -p udp -s 192.84.219.129 domain -j ACCEPT ipchains -A dmz-good -p tcp ! -y -s 192.84.219.129 domain -j ACCEPT ipchains -A dmz-good -p tcp ! -y -s 192.84.218.130 www -j ACCEPT ipchains -A dmz-good -p tcp ! -y -s 192.84.218.130 rsync -j ACCEPT ipchains -A dmz-good -p icmp -j icmp-acc ipchains -A dmz-good -j DENY -l 7.4.7. Reguli pentru conexiuni din DMZ ==> reteaua externa Restrictionare in reteaua DMZ numai la: - serverul de mail: - SMTP catre exterior - acceptare acces SMTP din interior si exterior - acceptare acces pop3 din interior - serverul de nume: - trimitere cereri DNS catre exterior - acceptarea acces DNS din reteaua interna, externa si ruter - serverul de web: - acceptare acces HTTP din exterior si interior - acceptare acces rsync din interior ipchains -A dmz-bad -p tcp -s 192.84.219.128 smtp -j ACCEPT ipchains -A dmz-bad -p udp -s 192.84.219.129 domain -j ACCEPT ipchains -A dmz-bad -p tcp -s 192.84.219.129 domain -j ACCEPT ipchains -A dmz-bad -p tcp ! -y -s 192.84.218.130 www -j ACCEPT ipchains -A dmz-bad -p icmp -j icmp-acc ipchains -A dmz-bad -j DENY -l 7.4.8. Reguli pentru conexiuni din reteaua externa ==> reteaua interna - Nu permitem nici o conexiune nemasqueradata din reteaua externa catre reteaua interna ipchains -A bad-good -j REJECT 7.4.9. Filtrul de pachete pentru insusi sistemul care este ruter - Daca doresti sa filtrezi pachetele ce au ca destinatie insusi ruterul, aceasta sa realizeaza in chain-ul input. Cream cate un chain pentru fiecare interfata destinatie. ipchains -N bad-if ipchains -N dmz-if ipchains -N good-if - Cream reguli pentru a sari la aceste chain-uri ipchains -A input -d 192.84.219.1 -j bad-if ipchains -A input -d 192.84.219.250 -j dmz-if ipchains -A input -d 192.168.1.250 -j good-if 7.4.9.1. Interfata catre reteaua externa Restrictionarea ruterului numai la: - PING catre orice retea - TRACEROUTE catre orice retea - acces catre DNS - Interfata externa primeste deasemenea replay-uri la pachetele masqueradate (masquerading foloseste porturile sursa 61000 si 65095), erorile ICMP pentru acestea si replay-urile la PING. ipchains -A bad-if -i ! ppp0 -j DENY -l ipchains -A bad-if -p TCP --dport 61000:65095 -j ACCEPT ipchains -A bad-if -p UDP --dport 61000:65095 -j ACCEPT ipchains -A bad-if -p ICMP --icmp-type pong -j ACCEPT ipchains -A bad-if -j icmp-acc ipchains -A bad-if -j DENY 7.4.9.2. Interfata catre reteaua de servere (DMZ) Restrictionarea ruterului numai la: - PING catre orice retea - TRACEROUTE catre orice retea - acces catre DNS - interfata catre DMZ primeste replay-uri DNS, ping si erori ICMP ipchains -A dmz-if -i ! eth0 -j DENY ipchains -A dmz-if -p TCP ! -y -s 192.84.219.129 53 -j ACCEPT ipchains -A dmz-if -p UDP -s 192.84.219.129 53 -j ACCEPT ipchains -A dmz-if -p ICMP --icmp-type pong -j ACCEPT ipchains -A dmz-if -j icmp-acc ipchains -A dmz-if -j DENY -l 7.4.9.3. Interfata catre reteaua interna Restrictionarea ruterului numai la: - PING catre orice retea - TRACEROUTE catre orice retea - acces catre DNS Restrictionarea retelei interne numai la: - permiterea in exterior traficului WWW, ftp, traceroute, ssh - acceptare acces SMTP catre serverul de mail - acceptare acces POP-3 catre serverul de mail - acceptare acces DNS catre nameserver - acceptare acces rsync catre nameserver - acceptare acces WWW catre serverul de web - acceptare ping catre ruter - interfata interna primeste ping-uri, replay-uri la ping si erori ICMP ipchains -A good-if -i ! eth1 -j DENY ipchains -A good-if -p ICMP --icmp-type ping -j ACCEPT ipchains -A good-if -p ICMP --icmp-type pong -j ACCEPT ipchains -A good-if -j icmp-acc ipchains -A good-if -j DENY -l 7.5. In final - Stergerea regulilor ce blocheaza pachetele: ipchains -D input 1 ipchains -D forward 1 ipchains -D output 1 8. Anexa: Diferente intre ipchains si ipfwadm Unele dintre aceste modificari sunt un rezultat al schimbarilor din kernel, si unele al faptului ca ipchains este diferit de ipfwadm 1. Multe argumente au fost schimbate: literele mari indica o comanda, literele mici indica o optiune. 2. Chain-uri arbitrare sunt posibile, deci chiar si chain-urile predefinite au nume intregi in loc de argumente (ex. "input" in loc de "-I"). 3. Optiunea "-k" a disparut: foloseste "! -y". 4. Optiunea "-b" defapt introduce/sterge/adauga doua reguli, ma degraba decat o singura regula bidirectionala. 5. Optiunea "-b" poate fi folosita impreauna cu "-C" pentru a realiza doua verificari (cate una in fiecare directie). 6. Optiunea "-x" in folosire cu "-l" a fost inlocuit cu "-v". 7. Porturi multiple sursa si destinatie nu mai sunt suportate. Din fericire faptul ca se pot nega siruri de porturi a indreptat pe undeva acest lucru. 8. Interfetele pot fi specificate numai prin nume (nu si prin adrese). Vechea sintaxa s-a schimbat in liniste oricum pentru kernelurile versiunea 2.1. 9. Fragmentele sunt examinate, nu mai sunt permise automat. 10. Accounting chain-urile explicite au fost inlaturate 11. Protocoale diferite peste IP pot fi testate. 12. Comportamentul vechi pentru potrivirea SYN si ACK (care inainte a fost ignorat pentru pachetele non-TCP) s-a schimbat; optiunea SYN nu este valida pentru reguli care nu sunt specifice TCP. 13. Counterele sunt acum pe 64 de biti pentru masini pe 32 de bit, nu pe 32 de biti. 14. Inversarea optiunilor este posibila. 15. Codurile ICMP sunt suportate acum. 16. Definirea mai multe interfete odata este suportata. 17. Manipularea TOS este acum verificata: inainte kernelul te oprea in liniste, acum ipchains returneaza o eroare pentru cazurile invalide. 8.1. Tabel pentru informare rapida [ In principal, argumentele pentru comenzi sunt cu litere mari, si argumentele pentru optiuni sunt cu litere mici ] Inca un lucru de observat, masquerading este specificat prin "-j MASQ", este complet diferit fata de "-j ACCEPT", si nu tratat doar ca un efect secundar, cum face ipfwadm. ================================================================ | ipfwadm | ipchains | Note ---------------------------------------------------------------- | -A [both] | -N acct | Creeaza un chain "acct" | |& -I 1 input -j acct | si determina pachetele din | |& -I 1 output -j acct | chain-ul input si output | |& acct | sa il traverseze ---------------------------------------------------------------- | -A in | input | O regula fara nici o tinta ---------------------------------------------------------------- | -A out | output | O regula fara nici o tinta ---------------------------------------------------------------- | -F | forward | Foloseste acesta ca [chain]. ---------------------------------------------------------------- | -I | input | Foloseste acesta ca [chain]. ---------------------------------------------------------------- | -O | output | Foloseste acesta ca [chain]. ---------------------------------------------------------------- | -M -l | -M -L | ---------------------------------------------------------------- | -M -s | -M -S | ---------------------------------------------------------------- | -a policy | -A [chain] -j POLICY | (dar vezi -r si -m). ---------------------------------------------------------------- | -d policy | -D [chain] -j POLICY | (dar vezi -r si -m). ---------------------------------------------------------------- | -i policy | -I 1 [chain] -j POLICY| (dar vezi -r si -m). ---------------------------------------------------------------- | -l | -L | ---------------------------------------------------------------- | -z | -Z | ---------------------------------------------------------------- | -f | -F | ---------------------------------------------------------------- | -p | -P | ---------------------------------------------------------------- | -c | -C | ---------------------------------------------------------------- | -P | -p | ---------------------------------------------------------------- | -S | -s | Accepta un port sau un sir | | | nu valori multiple. ---------------------------------------------------------------- | -D | -d | Accepta un port sau un sir | | | nu valori multiple. ---------------------------------------------------------------- | -V | | Foloseste -i [nume]. ---------------------------------------------------------------- | -W | -i | ---------------------------------------------------------------- | -b | -b | Acum sunt defapt 2 reguli. ---------------------------------------------------------------- | -e | -v | ---------------------------------------------------------------- | -k | ! -y | Nu functioneaza daca nu | | | este specificat -p tcp. ---------------------------------------------------------------- | -m | -j MASQ | ---------------------------------------------------------------- | -n | -n | ---------------------------------------------------------------- | -o | -l | ---------------------------------------------------------------- | -r [redirpt] | -j REDIRECT [redirpt] | ---------------------------------------------------------------- | -t | -t | ---------------------------------------------------------------- | -v | -v | ---------------------------------------------------------------- | -x | -x | ---------------------------------------------------------------- | -y | -y | Nu functioneaza daca nu | | | este specificat -p tcp. ---------------------------------------------------------------- 8.2. Exemple de comenzi ipfwadm translatate in ipchains Comanda veche: ipfwadm -F -p deny Comanda noua: ipchains -P forward DENY Comanda veche: ipfwadm -F -a m -S 192.168.0.0/24 -D 0.0.0.0/0 Comanda noua: ipchains -A forward -j MASQ -s 192.168.0.0/24 -d 0.0.0.0/0 Comanda veche: ipfwadm -I -a accept -V 10.1.2.1 -S 10.0.0.0/8 -D 0.0.0.0/0 Comanda noua: ipchains -A input -j ACCEPT -i eth0 -s 10.0.0.0/8 -d 0.0.0.0/0 (Observa ca nu exista nici un echivalent pentru a specifica interfata prin adresa: foloseste numele interfetei. Pe aceasta masina, 10.1.2.1 corespunde cu eth0). 9. Anexa: Folosirea scriptului ipfwadm-wrapper Scriptul ipfwadm-wrapper ar trebui sa fie un inlocuitor pentru ipfwadm pentru compatibilitate cu ipfwadm 2.3a. Singura optiune pe care nu o poate folosi este "-V". Cand aceasta este folosita un avertisment este afisat. Daca optiunea "-W" este deasemenea folosita, optiunea "-V" este ignorata. In caz contrar, scriptul incearca sa gaseasca numele interfetei asociata cu aceea adresa folosind ifconfig. Daca acest lucru nu reuseste (cum ar fi din cauza ca interfata nu este activata) atunci scriptul se opreste cu un mesaj de eroare. Acest avertizment poate fi ascuns daca se inlocuieste "-V" cu "-W", sau redirectand output-ul scriptului catre /dev/null. Daca gasesti greseli in acest script, sau lucruri care sunt diferite intre realul ipfwadm si acest script, te rog sa imi trimiti bug-ul: trimite un e-mail la rusty@linuxcare.com cu "BUG-REPORT" in campul subiectului. Te rog sa listezi versiunea ta de ipfwadm (ipfwadm -h), versiunea de ipchains (ipchains --version) si versiunea scriptului ipfwadm wrapper (ipfwadm-wrapper --version). Trimite de asemenea output-ul pentru ipchains-save. Multumiri anticipate. Folosirea impreuna a acestui script si ipchains este riscul tau. 10. Anexa: Multumiri. Multe multumiri pentru Michael Neuling, care a realizat prima versiune de cod pentru IP chains in timp ce lucra pentru mine. Imi cer scuze in mod public pentru ca nu am luat in considerare ideea sa de result-caching, pe care a propus-o mai tarziu Alan Cox, si pe care in final am inceput sa o implementez, observand greselile mele. Multumiri lui Alan Cox, pentru tech suport de 24 de ore prin e-mail, si pentru incurajari. Multumiri tuturor autorilor codului ipfwadm si ipfw, in special lui Jos Vos. Multumiri pentru beta-testeri si vanatorii de bug-uri in special lui: Jordan Mendelson, Shaw Carruthers, Kevin Moule, Dr. Liviu Daia, Helmut Adams, Franck Sicard, Kevin Littlejohn, Matt Kemner, John D. Hardin, Alexey Kuznetsov, Leos Bitto, Jim Kunzman, Gerard Gerritsen, Serge Sivkov, Andrew Burgess, Steve Schmidtke, Richard Offer, Bernhard Weisshuhn, Larry Auton, Ambrose Li, Pavel Krauz, Steve Chadsey, Francesco Potorti`, Alain Knaff, Casper Boden-Cummins and Henry Hollenberg. 10.1. Traduceri Oamenii care realizeaza traduceri ar trebui sa se puna la inceputul paginii de Multumiri, astfel:"Multe multumiri lui XXX, pentru traducerea exacta din engleza. Apoi spune-mi despre traducere ta, pentru a putea sa te includ aici. Arnaud Launay, asl@launay.org: http://www.freenix.fr/unix/linux/HOWTO/IPCHAINS-HOWTO.html Giovanni Bortolozzo, borto@pluto.linux.it: http://www.pluto.linux.it/ildp/HOWTO/IPCHAINS-HOWTO.html Herman Rodríguez, herman@maristas.dhis.org: http://netfilter.kernelnotes.org/ipchains/spanish/HOWTO.html