Personal tools

Iptables romana

From linux360

Revision as of 10:26, 3 January 2006 by Raptor (talk | contribs) (Ce vezi atunci cand porneste calculatorul)
Jump to: navigation, search

Cuvânt introductiv

Pentru început, vreau să spun că eu nu ştiu mai mult decât alţii şi spun asta pentru că am intrat în contact cu câţiva oameni care într-adevăr ştiu multe despre Linux. Eu nu am făcut decât să traduc acest HowTo, iar dacă (mai mult ca sigur) voi găsiţi greşeli de traducere sau de adaptare, vă rog să îmi atrageţi atenţia scriindu-mi un mesaj de poştă electronică. Dacă intraţi în posesia acestui fişier şi ştiţi pe cineva care îl vrea, vă rog să îl daţi pe gratis, adica aşa cum l-aţi primit şi voi pentru că nici măcar eu nu am cerut bani pe el. Sper sa vă ajute, cel puţin la fel de mult cât m-a ajutat şi pe mine, iar dacă aveţi neclarităţi scrieţi-mi un mesaj şi vă voi răspunde în măsura în care pot şi am timp.

Ce este filtrarea de pachete?

Bazele reţelisticii

Tot traficul dintr-o reţea este transmis sub formă de pachete. De exemplu, descărcând acest document (să zicem că are 50ko) s-ar putea ca tu să primeşti 36 de pachete a câte 1460 octeţi fiecare.

Antetul (engl. header) fiecărui pachet spune unde se duce, de unde vine, tipul pachetului precum şi alte detalii administrative. Restul pachetului, conţinând datele care ne sunt transmise, se numeşte corpul (engl. body) sau conţinutul pachetului.

Câteva protocoale, de exemplu TCP care este folosit (spre exemplu) pentru traficul de web, poştă şi sesiuni de terminal de la distanţă, folosesc principiul de forma o conexiune inainte de a transmite pachete cu datele care ne interesează. Astfel, varii pachete de început (cu antete speciale) sunt schimbate care spun 'Vreau să mă conectez', 'Bine' şi 'Mulţumesc' (procedură cunoscută ca negociere bilaterală -- engl. 3-way handshaking). Abia apoi începe schimbul de pachete conţinând datele ce trebuie să tranziteze conexiunea proaspăt creeată.

Deci ce este un filtru de pachete?

Un filtru de pachete este un program care se uită în header-ul pachetelor care trec şi le decide soarta. El poate să arunce pachetul (să îl neglijeze ca şi cum nu ar fi fost primit), să accepte pachetul (să îl lase să treacă), sau să rejecteze pachetul (îl aruncă dar şi spune sursei de la care a venit că l-a aruncat). Sub Linux, filtrarea de pachete este construită în kernel (ca modul sau chiar în el) şi există câteva lucruri mai deosebite pe care le putem face cu pachetele (putem de exemplu să modificăm sursa sau destinaţia acestuia înainte de a-l trimite mai departe), dar principiul general de a ne uita în antetul pachetului şi să-i decidem soarta este înca acolo.

De ce aş vrea să filtrez pachete?

  • Control:

Cand foloseşti un linux-box ca să conectezi reţeaua ta internă la o altă reţea (să zicem Internetul) ai oportunitatea de a lăsa numai anumite feluri de trafic sa treacă şi să nu laşi să treacă pe altele. De exemplu, antetul pachetului conţine destinaţia sa şi poţi preveni ca pachetele să ajungă într-o anumită parte a reţelei externe. Ca un alt exemplu, eu folosesc Netscape ca sa accesez arhivele Dilbert. Pe acea pagină sunt reclame de la doubleclick.net, şi Netscape-ul îmi pierde timpul deschizându-le. Spunându-i filtrului de pachete să nu lase să treacă pachete spre doubleclick.net sau să vină de la el rezolvă aceasta problemă.

  • Securitate:

Când Linux-box-ul tău este singurul lucru care stă între haosul din Internet şi reţeaua ta privată, este bine de ştiut că poţi restricţiona ceea ce face tărăboi la uşa ta. De exemplu, poţi lăsa să treacă ceea ce pleacă din interiorul reţelei interne, dar ar trebui să te îngrijoreze vestitul 'Ping of Death' care vine de la străini, sau diverşi alţi viruşi ce se propagă prin Internet. Ca un alt exemplu, nu ai vrea ca cei din afară să se conecteze prin ssh (sau mult mai vechiul telnet) la serverul tău, chiar dacă toate conturile din el sunt protejate de o parolă; având un filtru de pachete care să arunce pachetele cu antete speciale care sunt folosite pentru a deschide conexiuni din exterior.

  • Supraveghere:

Uneori o maşină din interior prost configurată (sau un virus de exemplu) poate decide să împraştie pachete lumii exterioare. Este frumos să-i spui filtrului de pachete să te înştiinţeze când se întâmplă ceva care nu face parte din normal,nu de alta dar poate faci ceva în legatură cu lucrul acesta sau poate eşti curios din fire să ştii ceea ce se intâmplă în reţeaua ta internă.

Cum filtrez pachete sub Linux?

Kernel-ele Linux-ului au avut filtre de pachete chiar de la versiunea 1.1. Prima generaţie, bazată pe ipfw de la BSD, a fost introdusă de Alan Cox in 1994. Aceasta a fost modificată şi întărită de Jos Vos şi alţii pentru Linux 2.0. În 1998, pentru Linux 2.2, eu am modificat radical kernelul, cu ajutorul lui Michael Neuling şi am introdus programul 'ipchains'. În final, a patra generaţie a filtrului, 'iptables', şi o altă modificare a kernelului au apărut în 1999 pentru Linux 2.4. Pe iptables ne vom concentra în acest HOWTO. Programul iptables vorbeşte cu kernel-ul şi îi spune ce pachete să filtreze. Dacă nu eşti programator sau prea curios, în acest fel vei controla filtrul de pachete. Programul iptables inserează sau şterge reguli din tabelul de reguli de filtrare al kernelului. Aceasta înseamnă că orice ai seta, se va pierde când vei reporni maşina; vezi #Cum să faci regulile permanente pentru a te asigura că data viitoare când porneşti maşina ele sunt încă acolo. iptables înlocuieşte ipfwadm şi ipchains: vezi [să folosesti ipchains şi ipfwadm] pentru a evita folosirea iptables dacă deja foloseşti ipchains sau ipfwadm.

Cum să faci regulile permanente

Firewall-ul tău curent este stocat în kernel şi de aceea va fi pierdut când reporneşti maşina. Scriind

# iptables-save

şi

# iptables-restore

este ceea ce vă recomand. Între timp, pune comanda necesară pentru a-ţi seta regulile într-un script de iniţializare. Asigură-te că faci ceva inteligent în caz că una din comenzi nu merge (de obicei 'exec /sbin/sulogin').

Cine oare eşti şi de ce te joci cu kernelul meu?

Eu sunt Rusty; eu sunt cel care întreţine Linux IP Firewall şi sunt doar un programator decent care s-a întâmplat să fie la locul potrivit în timpul potrivit. Eu am scris ipchains (mecanismul firewall anterior, din kernelul 2.2) şi am învăţat destule ca să fac să meargă filtrul de pachete iptables cum trebuie. Cel puţin sper.

Cum traversează pachetele filtrul?

Kernel-ul porneşte cu trei liste de reguli; aceste liste se numesc firewall chains sau doar chains. Cele trei chain-uri se numesc INPUT, OUTPUT şi FORWARD. Pentru fanii ASCII-art, chain-urile sunt aranjate cam aşa:

                   _____
                  /     \
-->[Routing ]--->|FORWARD|------->
   [Decision]     \_____/        ^ 
       |                         |
       v                       ____  
      ___                     /    \ 
     /   \                   |OUTPUT|
    |INPUT|                   \____/ 
     \___/                      ^    
       |                        |
        ----> Local Process ----


Cele trei cicluri reprezentate sunt chain-urile menţionate mai sus. Când un pachet ajunge într-un ciclu din diagramă, acel chain este examinat pentru a decide soarta pachetului. Dacă chain-ul decide să arunce pachetul (DROP), va fi omorât acolo, dar dacă chain-ul spune că pachetul trebuie acceptat (ACCEPT), el continuă sa circule prin diagramă către următorul chain. Un chain este un set ordonat de reguli. Fiecare regulă spune 'dacă header-ul pachetului arata aşa, atunci ce vrei să faci cu pachetul'. Dacă regula nu este îndeplinită de pachet, apoi este consultată următoarea regulă din set. În final, dacă nu mai sunt reguli de consultat pentru acel chain, kernel-ul se uită la politica setului de reguli (adică politica chain-ului) pentru a decide ce se va întâmpla cu pachetul. Într-un sistem riguros din punct de vedere al securităţii politica setului de reguli îi spune kernel-ului să arunce pachetul (DROP). Cand un pachet soseşte (să zicem, printr-o interfaţă Ethernet) kernelul se uită prima oară la destinaţia lui: acest lucru se numeşte 'routing' (sau rutare). Dacă pachetul este chiar pentru calculatorul tău, el va merge în jos către chain-ul INPUT. Dacă trece de acesta (după verificarea pachetului împotriva fiecărei reguli din chain) orice proces care îl aşteaptă îl va primi. Altfel, dacă pachetul nu este pentru calculatorul tau şi dacă kernelul nu are forwarding-ul activat, sau nu ştie cum să forward-eze pachetul, acesta va fi aruncat (DROP). Dacă forwarding-ul este activat şi pachetul este destinat către o altă interfaţă de reţea (dacă mai ai încă una), atunci pachetul merge înainte în diagrama noastră spre chain-ul FORWARD. Dacă este acceptat de către acesta el va fi trimis în afară. Şi în sfârşit, un program care rulează chiar în calculatorul tău poate trimite pachete în reţea. Aceste pachete trec prin chain-ul OUTPUT: dacă acesta le acceptă (ACCEPT), atunci pachetul işi continua drumul către destinaţia sa, oricare ar fi aceasta şi prin orice interfaţa.

Folosirea iptables

iptables are un manual foarte detaliat (man iptables), dacă ai nevoie de detalii. Există câteva lucruri diferite pe care le poţi face cu iptables. În primul rând operaţii cu care poţi face management pe un întreg set de reguli. La început există trei chain-uri INPUT, OUTPUT şi FORWARD pe care nu le poţi şterge. Operaţiile sunt:

  • Crearea unui nou chain (-N).
  • Ştergerea unui chain gol (-X).
  • Schimbarea politicii unuia dintre chain-urile standard (INPUT, OUTPUT şi FORWARD). (-P).
  • Listarea regulilor dintr-un chain (-L).
  • Ştergerea tuturor regulilor dintr-un chain (-F).
  • Readucerea la zero a contoarelor regulilor dintr-un chain (-Z).

Există şi moduri de manipulare a unei singure reguli dintr-un chain:

  • Ataşarea unei noi reguli (-A).
  • Inserarea unei noi reguli într-o anume poziţie într-un chain (-I).
  • Înlocuirea unei reguli într-o anume poziţie a unui chain (-R).
  • Ştergerea unei reguli (-D).

Ce vezi atunci cand porneste calculatorul

Pentru moment (Linux 2.3.15), iptables este un modul numit ('iptables.o'). Va trebui să-l inserezi în kernel înainte de a putea folosi comanda iptables. Pe viitor, va fi posibil ca el să fie deja construit în kernel. Înainte de orice comandă iptables să fie rulată (ai grijă: unele distribuţii vor rula iptables în scripturile lor de iniţializare), nu va exista nici o regulă în cele trei chain-uri de bază ('INPUT', 'FORWARD' şi 'OUTPUT'), chain-urile INPUT şi OUTPUT vor avea politica setată pe ACCEPT, şi chain-ul FORWARD va fi setat pe DROP (poţi schimba acest lucru setând 'forward=1' in opţiunile modulului iptables).

Operatii cu o singura regula

Acestea sunt painea si cutitul unui filtru de pachete; manipularea regulilor. Cel mai des probabil ca vei folosi comenzile de atasare (-A) si stergere (-D). Celelalte (-I pentru inserare si -R pentru inlocuire) sunt simple extensii ale acestor concepte. Fiecare regula specifica un set de conditii pe care trebuie sa le indeplineasca un pachet, si ce sa faca in caz ca le indeplineste (o tinta 'target'). De exemplu, vrei sa arunci toate pachetele de tip ICMP care vin de la IP-ul 127.0.0.1. Deci in acest caz conditiile noastre sunt ca protocolul trebuie sa fie ICMP si sursa de la care vin pachetele este IP-ul 127.0.0.1. tinta noastra este aruncarea lor (DROP). 127.0.0.1 este interfata 'loopback', pe care o ai char daca nu ai vreo legatura fizica la vreo retea. Poti folosi programul 'ping' pentru a genera asemenea pachete si a testa o astfel de regula.

# 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 DROP
# 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 ping-ul a avut scces (prin '-c 1' i-am spus programului ping sa trimita un singur pachet). Apoi atasam (-A) chain-ului 'INPUT', o regula in care specificam ca pachetele care vin de la IP-ul 127.0.0.1 ('-s 127.0.0.1') prin protocolul ICMP ('-p icmp') ar terbui sa le dam DROP ('-j DROP'). Apoi testam regula noastra, folosind un al doilea ping. Va fi o pauza pana cand programul renunta sa mai astepte raspunsul care nu va veni niciodata. Putem sterge aceasta regula in mai multe feluri. In primul rand, pentru ca stim ca este singura regula in chain-ul input, putem folosi o stergere in care specificam pozitia reguluii:

# iptables -D INPUT 1

Al doilea mod prin care putem sterge regula este sa oglindim comanda –A, inlocuind –A cu -D. Acest lucru este folositor cand avem un set complex de reguli. In acest caz folosim:

# ipchains -D INPUT -s 127.0.0.1 -p icmp -j DROP

Specificatii ale filtrarii

Am vazut folosirea '-p' pentru a specifica protocolul, si '-s' pentru a specifica adresa sursa, dar sunt si alte optiuni cu care putem specifica caracteristici ale pachetelor

  • Specificarea adresei Sursa si adresa Destinatie.

Sursa ('-s', '--source' or '--src') si destinatia ('-d', '--destination' or '--dst') IP-ului poate fi specificata in patru moduri. Cel mai des intalnit este folosirea numelui intreg, cum ar fi 'localhost' sau 'www.linuxhq.com'. Al doilea mod este folosirea de adrese IP cum ar fi '127.0.0.1'. Al treilea si al patrulea mod este specificarea unui interval de IP-uri, cum sunt '199.95.207.0/24' sau '199.95.207.0/255.255.255.0'. Amandoua specifica orice IP cuprins intre 199.95.207.0 to 199.95.207.255 inclusiv; iar digitii dupa '/' ne spun care parti din IP-uri sunt relevante in cazul nostru. '/32' sau '/255.255.255.255' este modul standard (default). Pentru a specifica orice ip putem folosi '/0', dupa cum urmeaza:

# ipchains -A input -s 0/0 -j DENY

Aceasta este rar folosit pentru ca efectul obtinut este la fel ca in cazul in care nu folosim de loc optiunea '-s'.

  • Specificarea unei inversiuni

Multe flag-uri, incluzand optiunile '-s' and '-d' pot avea argumentele precedate de un '!' pentru a compara adrese care nu sunt echivalente cu cele date in linia de comanda. De exemplu '-s ! localhost' inseamna orice pachet care nu vine de la localhost.

  • Specificarea Protocolului

Protocolul poate fi specificat cu flag-ul '-p'. Protocolul poate fi un numar (daca stii valorile numerice pentru IP) sau un nume pentru cazurile speciale de 'TCP', 'UDP' sau 'ICMP'. Cum este scris nu conteaza, asa ca 'tcp' merge la fel de bine ca si 'TCP'. Numele protocolului poate fi precedat de un '!', pentru a fi inversat, such as '-p ! TCP' (expresia inseamna tot ce nu e TCP).

  • Specificarea unei interfete

Optiunea '-i' (sau '--in-interface') si '-o' (sau '--out-interface') specifica numele interfetei. O interfata este un lucru fizic (modem, placa de retea etc…) prin care pachetul intra ('-i') sau prin care iese ('-o'). Poti folosi comanda

# ifconfig

pentru a vedea interfetele care sunt active. Pentru pachetele care traverseaza chain-ul INPUT nu se poate specifica o interfata de iesire, deci orice regula din acest chain care contine optiunea '-o' este inutila. Similar, pachetele care traverseaza chain-ul OUTPUT nu au interfata de intrare, deci orice regula din acest chain in care exista optiunea '-i' este inutila. Doar pachetele care traverseaza chain-ul FORWARD au atat interfata de intrare cat si interfata de iesire. Nu este gresit daca se specifica o interfata care pentru moment nu este activa; regula nu se va potrivi niciunui pachet pana cand interfata nu va fi activata. Acest lucru este foarte util pentru legaturi dial-up (PPP point to point) de obicei interfata ppp0. Un caz special, un nume de interfata al carei string se termina cu '+' specifica toate interfetele de acelas fel (chiar daca sunt activate sau nu). De exemplu, pentru a specifica o regula care sa se potriveasca pentru toate interfetele de gen PPP, se va folosi expresia-i ppp+. Numele interfetei poate fi precedat de '!', aceasta regula se va referi la pachetele care nu vin sau ies prin acea interfata.

  • Specificarea fragmentelor

Uneori un pachet este prea mare ca sa incapa prin fir intreg. Cand acest lucru se intampla pachetul este divizat in fragmente, si trimis ca mai multe pachete mai mici. Calculatorul care primeste aceste fragmente le va reasambla si va forma pachetul initial. Problema cu aceste pachete este ca doar primul fragment din acestea contine in header informatii despre protocol (cum ar fi TCP, UDP si ICMP) si extensiile lui, iar restul de fragmente nu contin aceste lucruri, iar daca am incerca sa ne uitam in ele ar fi imposibil. Daca tu faci connection tracking sau NAT, atunci toate aceste fragmente vor fi fuzionate inainte de a ajunge la filtrul de pachete, deci nu trebuie sa ne facem griji despre aceste fragmente. Atltfel, poti insera in kernel modulul 'ip_defrag.o' care face acelas lucru (nota, acest lucru este permis doar daca linux-box-ul tau este singura conexiune intre cele doua retele). Altfel, este foarte important sa intelegem cum sunt tratate fragmentele de catre regulile de filtrare. Orice regula care cere informatii de la pe care nu le avem nu se va potrivi, aceasta inseamna ca primul fragment (cel care are specificat in header tot ce este necesar) va fi tratat ca pe un pachet, iar cel de-al doilea si restul de fragmente nu vor fi tratate corespunzator (pentru ca header-ul lor nu contine informatiile necesare). De aceea o regula de genul -p TCP --sport www (care specifica portul sursa al unui server 'www') nu va filtra fragmente (in afara de primul). La fel se va comporta si regula opusa -p TCP --sport ! www. Oricum, poti face o regula special pentru cel de-al doilea si urmatoarele fragmente folosind optiunea '-f' (sau '--fragment'). Valabila este si regula care nu se aplica pentru cel de-al doilea si urmatoarele fragmente daca punem optiunea ! inaintea lui '-f'. De obicei se zice ca este sigur (din punct de vedere al securitatii) sa lasi al doilea si celelalte fragmente sa treaca treaca, pentru ca filtrarea afecteaza decat primul fragment, si deci pachetul nu va putea fi reasamblat in partea cealalta, dar, exista bug-uri care vor face masina sa se prabuseasca doar prin simplul fapt ca aceasta trimite fragmente. Este decizia ta. Ca un exemplu, urmatoarea regula va arunca toate fragmentele care se duc la IP-ul 192.168.1.1:

# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP
  • Extensii la iptables

Iptables este extensibil, asta insemnand ca atat kernel-ul cat si iptables se pot extinde pentru a ne asigura noi posibilitati. Unele dintre aceste extensii sunt standard, si altele sunt mai mult exotice. Extensiile pot fi facute si de alti oameni si distibuite userilor. Extensiile kernel-ului normal se gasesc in subdirectorul lui pentru module, cum este /lib/modules/2.3.15/net. Pe acestea trebuie sa le incarci in kernel automat pentru ca ele nu se autoincarca la cerere(Linux 2.3.15). Pe viitor ele se vor incarca automat. Extensiile programului iptables sunt librarii sheruite care de obicei sunt gasite in directorul /usr/local/lib/iptables/, cu toate ca anumite distributii le pun in /lib/iptables sau /usr/lib/iptables. Extensiile sunt de doua tipuri: tinte noi (new targets), si noi teste (new tests); mai jos vom vorbi despre noi tinte. Anumite protocoale ofera ele noi teste: actual ele sunt TCP, UDP si ICMP cum sunt aratate mai jos. Pe aceste noi teste le vei putea specifica in linia de comanda dupa optiunea '-p', care va incarca extensiile. Pentru teste noi explicite trebuie sa folosestei optiunea '-m' pentru a incarca extensia, doar dupa aceasta va fi aceasta accesibila. Pentru a deschide manualul extensiei dupa ce o incarci ('-p' or '-m') foloseste optiunea '-h' sau '--help'.

    • Extensii TCP

Extensiile TCP sunt incarcate automat daca este folosita comanda '--protocol tcp'. Aceastea vin cu urmatoarele optiuni (niciuna nu se refera si la fragmente, doar la pachete). --tcp-flags Daca dupa ele se pune (optional)'!', atunci doua stringuri te vor ajuta sa filtrezi flaguri specifice protocolului TCP. Primul string este un mask: o lista de flaguri pe care vrei sao examinezi. Al doilea string iti spune pe care vrei sa le filtrezi. De exemplu:

# iptables -A INPUT --protocol tcp --tcp-flags ALL SYN,ACK -j DENY[/code]

Aceasta indica, ca toate flagurile trebuie examinate ('ALL' este sinonim cu 'SYN,ACK,FIN,RST,URG,PSH'), dar doar SYN si ACK vrei sa le setezi. Exista si un argument 'NONE' care inseamna nici un flag. --syn Urmat optional de '!', aceasta este o scurtare a comenzii'--tcp-flags SYN,RST,ACK SYN'. --source-port optional urmat de '!', si apoi de un singur port TCP, sau un interval de porturi. Porturile poti specificate prin numele lor, la fel ca in /etc/services, sau numerice. Intervalele sunt ori doua nume de porturi separate cu'-', sau (pentru a specifica un nr. mai mare sau egal cu portul dat) un port cu '-' inainte lui, sau (pentru a specifica un nr mai mic sau egal cu portul dat), un port precedat de'-'. --sport este sinonim cu '--source-port'. --destination-port and --dport sunt la fel ca si mai sus, numai ca ele specifica destinatia in loc de sursa portului care ne intereseaza sa-l filtram. --tcp-option urmat oprional de '!' siun numar, se refera la un pachet TCP care este egal cu acel numar. Un pachet care nu are un header TCP complet este aruncat (DROP) automat daca i se incearca examinarea optiunilor TCP. O explicatie a flagurilor TCP Este util sa permitem conexiuni TCP intr-o directie, dar nu si in cealalta. De exemplu, ai vrea sa se poata face conexiuni catre un server WWW exterior, dar sa nu existe conexiuni de la acel server la tine. Te poti gandi sa blochezi pachetele care vin de la acel server. Dar din nefericire, ca o conexiune TCP sa mearga trebuie sa existe trafic in ambele directii. Solutia este sa blochezi doar pachetele care cer ca o conexiune sa fi stabilita. Aceste pachete se numesc SYN (ok, tehnic ele sunt pachete cu flagul SYN setat, si flagurile FIN si ACK sunt sterse, dar noi le numim pe scurt pachete SYN). Blocand doar aceste pachete putem opri cererile de conexiuni si astfel niciuna nu poate fi facuta din exterior. Flagul '--syn' este folosit pentru aceasta: este valid doar pentru regulile in care li se specifica ca protocol TCP-ul. Ca exemplu, pentru a specifica incercari de conexiuni de la IP-ul 192.168.1.1 se foloseste: -p TCP -s 192.168.1.1 --syn Acest flag poate fi inversat daca este precedat de un '!', aceasta inseamna orice pachet inafara de cele initiatoare de conexiuni TCP.

    • Extensii UDP

Aceste extensii sunt incarcate automat daca este specificat protocolul UDP '--protocol udp'. Aici avem optiunile '--source-port', '--sport', '--destination-port' si '--dport' detaliate mai sus la protocolul TCP. Extensii ICMP Aceasta extensi este incarcata automat daca se specifica '--protocol icmp'. Aceasta ne da o singura optiune: --icmp-type urmat optional de '!', atunci un unme tip icmp (ex 'host-unreachable'), sau un tip numeric (ex. '3'), sau numeric si cod separat de'/' (ex. '3/3'). O lista de nume tip icmp se poate optine cu comanda '-p icmp --help'. Alte extensii Celelalte doua extensii sunt extensii demonstrative, care (daca sunt instalate) pot fi aduse la viata cu optiunea '-m'. mac acest modul trebuie explicit specificat cu '-m mac' sau '--match mac'. Este folosit pentru a filtra pachetele dupa adresa Ethernet (MAC), si este folositoare doar la regulile din chain-urile INPUT si FORWARD. De aduce o singura optiune: --mac-source optional urmata de '!', apoi o adresa ethernet scrisa in hexazecimale separate de :, ex '--mac-source 00:60:08:91:CC:B7'. limit acest modul trebuie explicit specificat cu '-m limit' sau '--match limit'. Este folosit pentru a limita rata de pachete acceptate. Unitatea de masura este numere de pachete pe secunda (default 3 pachete pe ora, cu o rafala de 5). Aceasta ne aduce doua argumente optionale: --limit urmat de un numar; specifica numarul medie maxim de pachete pe secunda care sunt lasate sa treaca. Numarul poate unitati explicite, folosind '/second', '/minute', '/hour' or '/day', sau parti din ele (deci '5/second' este la fel ca '5/s'). --limit-burst urmata de un numar, defineste lungimea rafalei de pachete acceptate dupa care intra in actiune limita de mai sus. Aceasta optiune poate fi folosita impreuna cu tinta LOG pentru a face rate-limited logging. Prentru a intelege cum functioneaza, hai sa ne uitam la urmatoarea regula, care logheaza pachetele care au limita default:

# iptables -A FORWARD -m limit -j LOG

Prima oara cand regula este indeplinita de un pachet, acesta va fi logat; de fapt, pentru ca rafala este de 5, primele cinci pachete vor fi logate. Dupa aceea, vor mai trece ica douazeci de minute pana cand urmatorul pachet va fi logat de la regula aceasta, netinand cont de cate pachete ajung la ea. Deasemenea, fiecare douazeci de minute care trec fara ca un pachet sa indeplineasca regula , o unitate din rafala va fi recapatata, daca nici un pachet nu se loveste de regula timp de 100 de minute rafala va reveni la 5; la fel ca la inceput. Nu poti creea o regula a carei interval de timp de umplere a rafalei sa depaseasca 59 de ore, deci daca faci o regula care sa se reincarce o data pe zi, rafala trebie sa fie mai mica de 3. unclean Acest modul trebuie explicit specificat cu '-m unclean sau '--match unclean'. Acesta face analize aleatorii asupra integritatii pachetelor. Acesta nu trebuie folosit ca o optiune pentru securitate (probabil ca va inrautatii lucrurile, pentru ca s-ar putea ca sa aiba bug-uri). Nu vine cu nici o optiune.

Specificarea tintelor

Acum stim cum sa examinam un pachet, trebuie sa stim ce sa facem cu pachetele care se potrivesc regulilor noastre. Aceasta se numeste Tinta regulii (rule's target). Exista doua tinte foarte simple: DROP (arunca) si ACCEPT(accepta). Deja le stim pe acestea. Daca pachetul indeplineste regula si tinta ei este una din cele doua, nu vor mai fi consultate alte reguli: soarta pachetului a fost decisa. There are two types of targets other than the built-in ones: extensions and user-defined chains. Chain-uri definite de utilizator (User-defined chains) O puternica abilitate pe care iptables a mostenit-o de la ipchains este abilitatea de a creea chain-uri definite de utilizator (adica alte chain-uri inafara de cele trei de baza INPUT, FORWARD si OUTPUT). Cand un pachet se potriveste unei reguli a carei tinta este un chain definit de utilizator, pachetul incepe sa confrunte reguluile sin chain-ul definit de utilizator. Daca acel chain nu decide soarta pachetului, adica a parcurs toate regulile din acel chain definit de utilizator, atunci pachetul incepe sa confrunte regula imegiat urmatoare regulei a carei tinta a fost chainul definit de utilizator. Din nou este vremea pentru ASCII art. Sa zicem ca avem doua chain-uri Consider two (prostute): INPUT (chain-ul de baza) si test (un chain definit de utilizator cu optiunea -N). CLIC

Chain-urile definite de utilizator pot sari catre alte chain-uri definite de utilizator (dar nu au voie sa fac bucle inchise: pachetele care intra in bucle inchise vor fi aruncate). Extensia: New Targets Clealat tip de tinta este o extensie. Aceastea constau intr-un modul pentru kernel, care ne asigura noi optiuni in linia de comanda. Exista cateva extensii in distributia default a pachetului netfilter:

  • LOG

Acest modul logheaza pachetele care indeplinesc o anumita regula a carei tinta este LOG. Acesta vine cu urmatoarele optiuni: --log-level Urmata de un nume sau numar. Numele sunt (case-insensitive) 'debug', 'info', 'notice', 'warning', 'err', 'crit', 'alert' si 'emerg', care corespund numerelor de la 7 la 0. Uta-te la man page-ul pentru syslog.conf pentru o explicatie a acestor nivele. --log-prefix Urmat de un sting de maxim 14 caractere, acest mesaj este trimis la inceputul logului pentru a fi unic. Acest modul este forte util dupa o tinta care limiteaza pentru a nu-ti inunda (food) logurile.

  • REJECT

Acest modul are acelas efect ca modulul 'DROP', numai ca expeditorului ii este trimis un mesaj de eroare de tip ICMP 'port unreachable'. Nota: mesajul de eroare de tip ICMP nu este trimis daca (vezi RFC 1122): Pachetul filtrat era chiar el un mesaj de eroare de tip ICMP, sau un tip necunoscut de ICMP. Pachetul filtrat nu era primul fragment dintr-un lant de fragmente. Am trimis prea multe mesaje de eroare de tip ICMP la acea destinatie intr-un anumit timp. Tinte speciale Exista doua tinte speciale care vin o dat cu distributia: RETURN si QUEUE.

  • RETURN are acelas efect ca si cum ar sari de la sfarsitul unui chain: pentru unul dintre cele trei chain-uri de baza, soarta pachetului va fi decisa de politica acestuia. Pentru o regula dintr-un chain definit de utilizator, traversarea continua exact dupa regula de la care a fost aruncat pachetul in chain-ul definit de utilizator. Daca o regula (nu este neaparat sa fie ultima din chain) dintr-un chain definit de utilizator are tinta RETURN si aceasta se potriveste unui pachet, aceasta il va trimite inapoi la chainul de unde a venit, cu mentiunea ca este respectata traversearea regulilor, adica la regula exact urmatoare celei care a trimis pachetul in chain-ul definit de utilizator.
  • QUEUE este o tinta speciala, care pastreaza pachetul pentru procesarea facuta de useri. Daca pachetul nu este asteptat de vreo aplicatie acesta va fi aruncat.

Operatii cu un Chain intreg

O abilitate foarte utila a programului iptables este gruparea regurilor in chainuri (seturi de reguli). Poti denumi chainurile definite de utilizator cum vrei, dar este rcomandat sa le denumesti cu caractere mici pentru a nu le confunda cu cele trei chainuri de baza; numele acestora poate sa fie maxim din 16 litere.

  • Crearea unui nou chain

Hai sa creem un nou chain. Pentru ca eu sunt un tip cu imaginatie am sa-l numesc test. Vom folosi optiunile '-N' sau '--new-chain':

# iptables -N test

Este chiar atat de simplu. Acum poti pune reguli in el dupa cum a fost aratat mai sus.

  • Stergerea unui Chain

Stergerea unui chain este la fel de simplu, folosind optiunea '-X' sau '--delete-chain'. De ce '-X'? Pai…, toate literele frumoase au fost luate deja.

# iptables -X test

Exista cateva restrictii cand stergem un chain: acesta trebuie sa fie gol (vezi golirea unui chain mai jos) si nu trebuie sa fie tinta vreunei reguli. Chainurile de baza nu pot fi sterse. Daca nu se specifica numele chainului de sters, atunci toate chain-urile definite de utilizator vor fi sterse, daca este posibil.

  • Golirea unui Chain

Exista un mod simplu prin care se poate goli un cahin de toate regulile care exista in el, folosind comanda '-F' (sau '--flush').

# ipchains -F forward

Daca nu se specifica chain-ul atunci toate chainurile vor fi golite.

  • Listarea unui chain

Poti vedea toate regulile existente intr-un chain cu comanda '-L'. Daca nu este specificat numele chain-ului atunci sunt listate toate regulile existente in filtrul de pachete. Exista trei optiuni care acompaniaza comanda '-L'. Optiunea '-n' (numeric) pentru ca ea previne ca iptables sa incerce sa caute adresa IP, care (daca folosesti DNS ca majoritatea oamenilor) va cauza delay-uri foarte mari in caz ca DNS-ul nu este setat cum trebuie, sau daca filtrezi cererile de DNS (Domain Name Server). Optiunea '-v' va arata toate detaliile unei raguli, cum sunt pachetele si contuarele de biti, comparatiile TOS, si interfetele. Altfel aceste valori sunt omise. Nota: pachetele si contoarele de biti sunt afisate folosin sufixele 'K', 'M' sau 'G' pentru 1000, 1,000,000 si respectiv 1,000,000,000. Folosind optiunea '-x' (expand numbers) vor fi aratate ca numere netinand cont de cat de mari sunt acestea.

  • Resetarea (Zeroing) Contoarelor

Este util sa poti reseta contoarele. Acest lucru poate fi facut cu optiunea '-Z' (sau '--zero') Problema cu acest lucru este ca, uneori, trebuie sa stii valorile contoarelor imediat inainte de a fi aduse la zero. In exemplul de mai sus, anumite pachete pot trece in dupa ce folosesti optiunea '-L' si pana folosesti optiunea '-Z'. Pentru acest motiv, poti folosi optiunile '-L' si '-Z' impreuna, pentru a reseta contuarele in timp ce le vizualizezi.

  • Setarea politicii

Doar chain-urile de baza (INPUT, OUTPUT and FORWARD) au o politica, pentru ca daca un pachete este confruntat cu un regulile dintr-un chain definit de utilizator si inca nu i se decide soarta, acesta isi continua drumul intr-un chain de baza. Politica poate fi ACCEPT(accepta) sau DROP (arunca).


Traducerea si adaptarea a fost facuta (initial) de Razvan Turtureanu (razvan@upb.ro)