Pentru inceput, vreau sa spun ca eu nu stiu mai mult decât altii si spun asta pentru ca am intrat in contact cu câtiva oameni care intr-adevar stiu multe . Eu nu am facut decât sa traduc acest ''HowTo'', iar daca (mai mult ca sigur) voi gasiti greseli de traducere sau de adaptare, va rog sa imi atrageti atentia scriindu-mi un mesaj de [mailto:razvan@upb.ro posta electronica]. Daca intrati in posesia acestui fisier si stiti pe cineva care il vrea, va rog sa il dati pe gratis, adica asa cum l-ati primit si voi pentru ca nici macar eu nu am cerut bani pe el. Sper sa va ajute, cel putin la fel de mult cât m-a ajutat si pe mine, iar daca aveti neclaritati scrieti-mi un mesaj si va voi raspunde in masura in care pot si am timp.
==Ce este filtrarea de pachete?==
=== Bazele retelisticii ===
Tot traficul dintr-o retea este transmis sub forma de pachete. De exemplu, descarcând acest document (sa zicem ca are 50ko) s-ar putea ca tu sa primesti 36 de pachete a câte 1460 octeti fiecare.
Antetul (engl. [http://en.wikipedia.org/wiki/Header_%28information_technology%29 header]) fiecarui pachet spune unde se duce, de unde vine, tipul pachetului precum si alte detalii administrative. Restul pachetului, continând datele care ne sunt transmise, se numeste corpul (engl. [http://en.wikipedia.org/wiki/Packet body]) sau continutul pachetului.
Câteva protocoale, de exemplu TCP care este folosit (spre exemplu) pentru traficul de web, posta si sesiuni de terminal de la distanta, folosesc principiul de forma o conexiune inainte de a transmite pachete cu datele care ne intereseaza. Astfel, varii pachete de ''inceput'' (cu antete speciale) sunt schimbate care spun 'Vreau sa ma conectez', 'Bine' si 'Multumesc' (procedura cunoscuta ca negociere bilaterala -- engl. [http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_establishment_.283-way_handshake.29 3-way handshaking]). Abia apoi incepe schimbul de pachete continând datele ce trebuie sa tranziteze conexiunea proaspat creeata.
===Deci ce este un ''filtru de pachete''?===
Un filtru de pachete este un program care se uita in header-ul pachetelor care trec si le decide soarta. El poate sa ''arunce'' pachetul (sa il neglijeze ca si cum nu ar fi fost primit), sa ''accepte'' pachetul (sa il lase sa treaca), sau sa ''rejecteze'' pachetul (il arunca dar si spune sursei de la care a venit ca l-a aruncat).
Sub Linux, filtrarea de pachete este construita in kernel (ca modul sau chiar in el) si exista câteva lucruri mai deosebite pe care le putem face cu pachetele (putem de exemplu sa modificam sursa sau destinatia acestuia inainte de a-l trimite mai departe), dar principiul general de a ne uita in antetul pachetului si sa-i decidem soarta este inca acolo.
===De ce as vrea sa filtrez pachete?===
*Control:
Cand folosesti un ''linux-box'' ca sa conectezi reteaua ta interna la o alta retea (sa zicem Internetul) ai oportunitatea de a lasa numai anumite feluri de trafic sa treaca si sa nu lasi sa treaca pe altele. De exemplu, antetul pachetului contine destinatia sa si poti preveni ca pachetele sa ajunga intr-o anumita parte a retelei externe. Ca un alt exemplu, eu folosesc Netscape ca sa accesez arhivele Dilbert. Pe acea pagina sunt reclame de la doubleclick.net, si Netscape-ul imi pierde timpul deschizându-le. Spunându-i ''filtrului de pachete'' sa nu lase sa treaca pachete spre doubleclick.net sau sa vina de la el rezolva aceasta problema.
*Securitate:
Când Linux-box-ul tau este singurul lucru care sta intre haosul din Internet si reteaua ta privata, este bine de stiut ca poti restrictiona ceea ce face ''taraboi la usa ta''. De exemplu, poti lasa sa treaca ceea ce pleaca din interiorul retelei interne, dar ar trebui sa te ingrijoreze vestitul 'Ping of Death' care vine de la straini, sau diversi alti virusi ce se propaga prin Internet. Ca un alt exemplu, nu ai vrea ca cei din afara sa se conecteze prin ssh (sau mult mai vechiul telnet) la serverul tau, chiar daca toate conturile din el sunt protejate de o parola; având un filtru de pachete care sa ''arunce'' pachetele cu antete speciale care sunt folosite pentru a deschide conexiuni din exterior.
*Supraveghere:
Uneori o masina din interior prost configurata (sau un virus de exemplu) poate decide sa imprastie pachete lumii exterioare. Este frumos sa-i spui ''filtrului de pachete'' sa te instiinteze când se intâmpla ceva care nu face parte din normal,nu de alta dar poate faci ceva in legatura cu lucrul acesta sau poate esti curios din fire sa stii ceea ce se intâmpla in reteaua ta interna.
===Cum filtrez pachete sub Linux?===
Kernel-ele Linux-ului au avut filtre de pachete chiar de la versiunea 1.1. Prima generatie, bazata pe ''ipfw'' de la BSD, a fost introdusa de Alan Cox in 1994. Aceasta a fost modificata si intarita de Jos Vos si altii pentru Linux 2.0. În 1998, pentru Linux 2.2, eu am modificat radical kernelul, cu ajutorul lui Michael Neuling si am introdus programul 'ipchains'. În final, a patra generatie a filtrului, 'iptables', si o alta modificare a kernelului au aparut in 1999 pentru Linux 2.4. Pe iptables ne vom concentra in acest HOWTO.
Programul iptables vorbeste cu kernel-ul si ii spune ce pachete sa filtreze. Daca nu esti programator sau prea curios, in acest fel vei controla ''filtrul de pachete''.
Programul iptables insereaza sau sterge reguli din ''tabelul'' de reguli de filtrare al kernelului. Aceasta inseamna ca orice ai seta, se va pierde când vei reporni masina; vezi [[#Cum sa faci regulile permanente]] pentru a te asigura ca data viitoare când pornesti masina ele sunt inca acolo.
iptables inlocuieste ipfwadm si ipchains: vezi [[http://www.telematik.informatik.uni-karlsruhe.de/lehre/seminare/LinuxSem/downloads/netfilter/iptables-HOWTO-6.html|Cum sa folosesti ipchains si ipfwadm]] pentru a evita folosirea iptables daca deja folosesti ipchains sau ipfwadm.
===Cum sa faci regulile permanente===
Firewall-ul tau curent este stocat in kernel si de aceea va fi pierdut când repornesti masina. Scriind
# iptables-save
si
# iptables-restore
este ceea ce va recomand.
Între timp, pune comanda necesara pentru a-ti seta regulile intr-un script de initializare. Asigura-te ca faci ceva inteligent in caz ca una din comenzi nu merge (de obicei 'exec /sbin/sulogin').
==Cine oare esti si de ce te joci cu kernelul meu?==
Eu sunt Rusty; eu sunt cel care intretine ''Linux IP Firewall'' si sunt doar un programator decent care s-a intâmplat sa fie la locul potrivit in timpul potrivit. Eu am scris ipchains (mecanismul firewall anterior, din kernelul 2.2) si am invatat destule ca sa fac sa mearga ''filtrul de pachete'' iptables cum trebuie. Cel putin sper.
==Cum traverseaza pachetele filtrul?==
Kernel-ul porneste cu trei liste de reguli; aceste liste se numesc ''firewall chains'' sau doar ''chains''. Cele trei chain-uri se numesc INPUT, OUTPUT si FORWARD.
Pentru fanii ASCII-art, chain-urile sunt aranjate cam asa:
_____ / \ -->[Routing ]--->|FORWARD|-------> [Decision] \_____/ ^ | | v ____ ___ / \ / \ |OUTPUT| |INPUT| \____/ \___/ ^ | | ----> Local Process ----
Cele trei cicluri reprezentate sunt chain-urile mentionate mai sus. Când un pachet ajunge intr-un ciclu din diagrama, acel chain este examinat pentru a decide soarta pachetului. Daca chain-ul decide sa arunce pachetul (DROP), va fi ''omorât'' acolo, dar daca chain-ul spune ca pachetul trebuie acceptat (ACCEPT), el continua sa circule prin diagrama catre urmatorul chain.
Un chain este un ''set ordonat de reguli''. Fiecare regula spune 'daca header-ul pachetului arata asa, atunci ce vrei sa faci cu pachetul'. Daca regula nu este indeplinita de pachet, apoi este consultata urmatoarea regula din set. În final, daca nu mai sunt reguli de consultat pentru acel chain, kernel-ul se uita la politica ''setului de reguli'' (adica politica chain-ului) pentru a decide ce se va intâmpla cu pachetul. Într-un sistem riguros din punct de vedere al securitatii politica ''setului de reguli'' ii spune kernel-ului sa arunce pachetul (DROP).
Cand un pachet soseste (sa zicem, printr-o interfata Ethernet) kernelul se uita prima oara la destinatia lui: acest lucru se numeste 'routing' (sau rutare).
Daca pachetul este chiar pentru calculatorul tau, el va merge in jos catre chain-ul INPUT. Daca trece de acesta (dupa verificarea pachetului impotriva fiecarei reguli din chain) orice proces care il asteapta il va primi.
Altfel, daca pachetul nu este pentru calculatorul tau si daca kernelul nu are forwarding-ul activat, sau nu stie cum sa forward-eze pachetul, acesta va fi aruncat (DROP). Daca forwarding-ul este activat si pachetul este destinat catre o alta interfata de retea (daca mai ai inca una), atunci pachetul merge inainte in diagrama noastra spre chain-ul FORWARD. Daca este acceptat de catre acesta el va fi trimis in afara.
Si in sfârsit, un program care ruleaza chiar in calculatorul tau poate trimite pachete in retea. Aceste pachete trec prin chain-ul OUTPUT: daca acesta le accepta (ACCEPT), atunci pachetul isi continua drumul catre destinatia sa, oricare ar fi aceasta si prin orice interfata.
==Folosirea iptables==
iptables are un manual foarte detaliat (man iptables), daca ai nevoie de detalii.
Exista câteva lucruri diferite pe care le poti face cu iptables. În primul rând operatii cu care poti face management pe un intreg ''set de reguli''. La inceput exista trei chain-uri INPUT, OUTPUT si FORWARD pe care nu le poti sterge.
Operatiile sunt:
*Crearea unui nou chain (-N).
*Stergerea unui chain gol (-X).
*Schimbarea politicii unuia dintre chain-urile standard (INPUT, OUTPUT si FORWARD). (-P).
*Listarea regulilor dintr-un chain (-L).
*Stergerea tuturor regulilor dintr-un chain (-F).
*Readucerea la zero a contoarelor regulilor dintr-un chain (-Z).
Exista si moduri de manipulare a unei singure reguli dintr-un chain:
*Atasarea unei noi reguli (-A).
*Inserarea unei noi reguli intr-o anume pozitie intr-un chain (-I).
*Înlocuirea unei reguli intr-o anume pozitie a unui chain (-R).
*Stergerea unei reguli (-D).
===Ce vezi atunci cand porneste calculatorul===
Pentru moment (Linux 2.3.15), iptables se afla intr-un modul numit ('iptables.o'). Va trebui sa-l inserezi in kernel inainte de a putea folosi comanda iptables. Pe viitor, va fi posibil ca el sa fie deja construit in kernel.
Înainte de orice comanda iptables sa fie rulata (ai grija: unele distributii vor rula iptables in scripturile lor de initializare), nu va exista nici o regula in cele trei chain-uri de baza ('INPUT', 'FORWARD' si 'OUTPUT'), chain-urile INPUT si OUTPUT vor avea politica setata pe ACCEPT, si chain-ul FORWARD va fi setat pe DROP (poti schimba acest lucru setând 'forward=1' in optiunile 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.linux.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).