NAT HOWTO

De la Wiki.lug.ro
Versiunea din 14 septembrie 2011 06:28, autor: Bmbogdan (Discuție | contribuții) (Reveniri la ultima modificare de către 190.3.106.164 (discuţie); revenire la ultima versiune de către Rz)

Salt la: navigare, căutare

Aceasta este o traducere a NAT HOWTO publicată de proiectul netfilter la http://www.netfilter.org/documentation/HOWTO//NAT-HOWTO.html

Documentul este publicat sub licenţă GNU GPL, (C) 2002 Paul `Rusty' Russell.

Traducera originală a fost preluată de la http://www.ibiblio.org/pub/Linux/docs/HOWTO/translations/ro/text/NAT-HOWTO şi începe cu următorul text:


traducere ver. 0.2 de catre Riddl

Multumiri tuturor celor care m-au ajutat,  in special lui Gushterul.
Observatie f importanta: probabil ca exista unele greseli in acest document.
Am tradus si eu cum m-am priceput mai bine, daca descoperiti greseli de
traducere si pentru observatii pertinente trimiteti-mi mail pentru Riddl la
"discutzii at gmx dot net". Nu uitati sa precizati numele documentului.
Multumesc anticipat.
Aceasta versiune este  putin modificata fata de original, deorece unii termeni
sunau foarte ciudat in ro.

Lecturare placuta!

Linux 2.4 NAT HOWTO Rusty Russell, lista de discutii netfilter@lists.samba.org $Revision: 1.3 $ $Date: 2002/06/05 13:21:56 $

Acest document descrie cum să realizezi masquerading, transparent proxy, forwardare de porturi, si alte forme de NAT pentru kernelurile Linux ver 2.4.


Introducere

Bine ai venit!

Eşti pe cale să începi să înveţi fascinanta (şi uneori înspăimântătoare) lume a NAT-ului: traducerea adreselor de reţea. Acest Howto îţi va fi oarecum un ghid pentru kernelurile din linux ver. 2.4 şi peste.

În kernelul de linux ver. 2.4, a fost introdus suport pentru modificarea pachetelor, numit "netfilter". Un nivel deasupra acestuia pune la dispoziţie NAT (translatarea adreselor de reţea), complet rescris fata de versiunile din kernelurile anterioare.

(C) 2000 Paul "Rusty" Russell. Sub licenţă GNU GPL.


Care este site-ul oficial şi care sunt listele de discuţii?

Exiată trei site-uri oficiale:

o       Mulţumiri lui Filewatcher <http://netfilter.filewatcher.org/>.
o       Mulţumiri Echipei Samba şi SGI <http://netfilter.samba.org/>.
o       Mulţumiri lui Harald Welte <http://netfilter.gnumonks.org/>.

Le poţi accesa pe toate folosind round-robin DNS la: http://www.netfilter.org/ şi http://www.iptables.org/

Pentru lista de discuţii oficiala de la netfilter, vezi: http://www.netfilter.org/contact.html#list


Ce înseamnă NAT?

În mod normal, pachetele într-o reţea se deplasează de la sursă (cum ar fi computerul tău) la destinaţie (cum ar fi www.securityorg.net) prin mai multe legături de reţea diferite: de exemplu cam 19 de la locaţia în care mă aflu eu. Nici una din aceste legături nu îţi modifica pachetul, care pur şi simplu este trimis mai departe aşa cum este.

Dacă una din aceste legături ar fi făcut NAT, atunci ar fi modificat sursa sau destinaţia pachetului ce intră. După cum îţi imaginezi nu aşa a fost conceput sistemul să funcţioneze, şi din această cauză NAT este întotdeauna ceva neobişnuit. De obicei legătura care a făcut NAT va ţine minte cum a modificat pachetul, şi când un pachet replică vine din cealaltă parte, va realiza modificarea inversă a pachetului replică, aşa că totul va funcţiona.


De ce aş dori să realizez NAT?

Într-o lume perfectă nu ai avea nevoie. Principale motive sunt:

Conexiunile prin modem la internet

Cele mai multe ISP-uri îţi dau doar o singura adresă IP când te conectezi la ei. Poţi trimite pachete cu orice adresă sursă pe care o doreşti, dar doar pachetele cu adresa IP specificată de ISP se vor întoarce la tine. Dacă doreşti să foloseşti mai multe sisteme (cum ar fi reţeaua de acasă) pentru a le conecta la internet prin aceasta singură legătură vei avea nevoie de NAT.

Aceasta este de departe cel mai răspândit mod de folosire al NAT-ului din zilele noastre, cunoscut şi sub numele de "masquerading" în lumea Linuxului. Eu numesc aceasta SNAT, deoarece modifici adresa sursă a primului pachet.

Servere multiple

Uneori doreşti să modifici direcţia în care să se îndrepte pachetele ce intră în reţeaua ta. În mod frecvent aceasta este (ca şi mai sus) deoarece ai doar o singură adresă IP, dar doreşti ca oameni să poată să ajungă la computerele din spatele sistemului cu adresa IP "reala".

Dacă rescrii adresa destinaţie a pachetelor care intra, poţi realiza acest lucru. Acest tip de NAT a fost numit forwardare (înaintare) de porturi în versiunile anterioare de Linux.

O variaţie des întâlnită a acestei aplicaţii a NAT-ului este load-sharing-ul (încărcare partajată), unde se mapează mai multe sisteme pe o singură adresă IP. Dacă realizezi acest lucru la o scară mare, ar fi bine să te uiţi pe Linux Virtual Server <http://linuxvirtualserver.org/>.

Proxy transparent

Uneori doreşti să pară că fiecare pachet care trece prin sistemul tău Linux este destinat pentru un program rulând chiar pe sistemul tău. Acest lucru este folosit pentru a realiza proxy-uri transparente: un proxy este un program care se interpune între reţeaua ta şi lumea exterioară, mediând comunicarea între ele. Se numeşte transparent deoarece reţeaua ta nici nu va realiza că foloseşte un proxy, doar dacă bineînţeles, proxy-ul nu funcţionează.

Squid poate fi configurat să ruleze în acest mod, şi aceasta era numită redirectare sau realizare de proxy transparent în versiunile anterioare de linux.

Doua tipuri de NAT

Am împărţit NAT-ul în două tipuri: NAT pentru sursă (SNAT) şi NAT pentru destinaţie (DNAT).

SNAT este realizat atunci când modifici adresa sursă a pachetului (schimbi sursa conexiunii). SNAT are întotdeauna loc după procesul de rutare a pachetelor, chiar înainte ca acestă să fie trimis pe conexiune. Masquerading este o forma particulară de SNAT.

DNAT este realizat când modifici adresa destinaţie a pachetului (schimbi destinaţia conexinunii). DNAT are întotdeauna loc înainte de rutarea pachetelor, când pachetul tocmai a venit prin interfaţă. Forwardare de porturi, load-sharing-ul, şi proxy-ul transparent sunt toate forme de DNAT.


Trecere rapida de la kernelurile 2.0 şi 2.2

Îmi pare rău pentru aceia dintre dumneavastră şocaţi de trecerea de la versiunea 2.0 (ipfwadm) la 2.2 (ipchains). Există veşti bune şi veşti proaste.

În primul rând, poţi în mod simplu să foloseşti ipchains şi ipfwadm ca mai înainte. Pentru aceasta trebuie să încarci (insmod) modulele pentru kernel "ipchains.o" sau "ipfwadm.o" ce se găsesc în ultima distribuţie netfilter. Acestea se exclud reciproc (ai fost avertizat), şi nu ar trebui folosite cu nici un alt modul din netfilter.

Odată ce unul din aceste module a fost încărcat, vei putea folosi ipchains şi ipfwadm în mod normal, însă cu unele diferenţe:

- Setarea de timeout-uri pentru masquerading cu ipchains  -M -S, sau ipfwadm
     -M -s nu rezolva nimic. Cum timeout-urile sunt mai mari pentru noua
     infrastructura NAT, acest lucru nu ar trebui să conteze.

- Câmpurile init_seq, delta şi previous_delta în listarea detaliată a 
     masqueradarii sunt întotdeauna zero.

- Resetarea şi listarea counter-elor simultană "-Z -L" nu mai este posibilă:
     countere-le nu vor fi resetate.
 
- Nivelul de compatibilitate nu este foarte bun pentru un număr de conexiuni
     foarte mare: nu îl poţi foloşi pentru gateway-ul corporaţiei.

Hackerii pot de asemenea să observe:

- Acum te poţi lega şi pe porturile 61000-65095 chiar dacă realizezi
     masquerading. Codul pentru masqueradare obişnuia să considere ca nimic în
     aceasta raza ar fi fost ceva corect, aşa ca programele nu puteau să o
     folosească.

- "Hack-ul" (nedocumentat) "getsockname", pe care programele ce realizau proxy
     transparent îl puteau foloşi pentru a afla adresa reala a conexiunilor nu
     mai este disponibil.

- "Hack-ul" (nedocumentat) bind-to-foreign-address (ataşare pe o adresă
     străină) nu mai este de asemnea implementat; acesta era folosit pentru a
     completa iluzia de proxy transparent.


Doresc să realizez doar masquerading! Help!

Aceasta este ce vor majoritatea oamenilor. Dacă ai o adresă PPP IP dinamică, vrei în mod simplu să spui sistemului tău că toate pachetele ce vin din reţeaua internă ar trebui să fie modificate astfel încât să pară că vin de la sistemul tău.

# Încarcă modulul NAT (acesta introduce toate modulele necesare)
modprobe iptable_nat

# În tabela NAT (-t nat) în chain-ul POSTROUTING adaugă o regula 
# pentru toate pachetele care ies prin ppp0 (-p ppp0) care precizează
# să masqueradeze conexiunea (-j MASQUERADE).
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

# Da drumul la forwardarea IP
echo 1 > /proc/sys/net/ipv4/ip_forward

Observaţie: aici nu faci nici un fel de filtrare a pachetelor: pentru aceasta citeşte Packet Filtering HOWTO: capitolul "Folosirea împreună a NAT-ului şi a filtrării de pachete".


Dar despre ipmasqadm?

Nu este cazul să ne facem probleme prea mari pentru compatibilitate. Poţi folosi în mod simplu "iptables -t nat" pentru a realiza forwardare de porturi. De exemplu, în Linux 2.2 ai fi făcut:

# Linux 2.2
# Forwardeaza pachetele TCP către portul 8080, adresa 1.2.3.4, spre
# portul 80, adresa 192.168.1.1
ipmasqadm portfw -a -P tcp -L 1.2.3.4 8080 -R 192.168.1.1 80

Acum ar trebui să faci:

# Linux 2.4
# Adaugă o regula înainte de procesul rutării în chain-ul PREROUTING
# (-A PREROUTING) în tabela NAT (-t nat) pentru ca pachetele TCP 
# (-p tcp) care vin spre adresa 1.2.3.4 (-d 1.2.3.4), portul 8080
# (--dport 8080) să aibă destinaţia mapată (-j DNAT) către
# 192.168.1.1, portul 80 (--to 192.168.1.1:80)
iptables -A PREROUTING -t nat -p tcp -d 1.2.3.4 --dport 8080 \
        -j DNAT --to 192.168.1.1:80


Controlul a ceea ce dorim să facem cu NAT?

Ai nevoie să scrii reguli NAT pentru a spune kernelului ce conexiuni să schimbe, şi cum să le schimbe. Pentru a realiza aceasta folosim comanda iptables, şi precizam ca dorim să schimbăm tabela NAT prin specificarea opţiunii "-t nat".

Tabela regulilor NAT cuprinde trei liste numite "chain-uri": fiecare regulă este examinată în chain până când una se potriveşte. Două chain-uri sunt numite PREROUTING (pentru DNAT, pentru pachetele care tocmai au intrat) şi POSTROUTING (pentru SNAT, pentru pachetele care sunt pe cale să iasă). Al treilea chain (OUTPUT) va fi ignorat în cele ce urmează.

Următoarea diagrama ilustrează destul de bine cum stau lucrurile:

            _____                                     _____
           /     \                                   /     \
         PREROUTING -->[Routing ]----------------->POSTROUTING----->
           \D-NAT/     [Decision]                    \S-NAT/
                           |                            ^
                           |                            |
                           |                            |
                           |                            |
                           |                            |
                           |                            |
                           |                            |
                           --------> Local Process ------


La fiecare dintre punctele de mai sus, când un pachet trece este determinat cărei conexiuni îi este asociat. Dacă este o conexiune nouă, este determinat chain-ul corespunzător în tabela NAT pentru a determina ce să facem cu acel pachet. Răspunsul va fi aplicat pentru toate pachetele viitoare aparţinând acelei conexiuni.


Selectare simpla folosind iptables

iptables admite un număr de opţiuni standard care sunt listate mai jos. Toate opţiunile care încep cu "--" pot fi prescurtate, atât timp cât iptables poate să le deosebească de alte opţiuni. Dacă kernelul tău are iptables compilat ca modul, este necesar să încarci întâi modulul iptables: "insmod ip_tables".

Cea mai importanta opţiune în acest caz este opţiunea de selectare a tabelei, "-t". Pentru toate acţiune NAT, vei dori să foloseşti "-t nat" pentru tabela NAT. A doua cea mai importanta opţiune este "-A" pentru a adaugă o nouă regulă la sfârşitul unui chain ("-A POSTROUTING"), sau "-I" pentru a insera o regulă la începutul unui chain ("-I PREROUTING").

Poţi specifica sursa ("-s" sau "--source") şi destinaţia ("-d" sau "--destination") pachetelor pe care le doreşti să le prelucrezi prin NAT. Aceste opţiuni pot fi urmate de o singura adresă IP (192.168.1.1), un nume (www.securityorg.net), sau o adresă de reţea (192.168.1.0/24 sau 192.168.1.0/255.255.255.0).

Poţi specifica interfaţa cu care să se potrivească regula, de intrare ("-i" sau "--in-interface") sau de ieşire ("-o" sau "--out-interface"), dar ceea ce poţi specifica depinde şi de chain-ul în care introduci regula: pentru chain-ul PREROUTING poţi selecta numai interfeţe prin care intra pachetele, şi în chain-ul POSTROUTING poţi selecta numai interfeţe de ieşire. Dacă foloseşti o interfaţă greşită iptables îţi va da eroare.


Aspecte delicate în privinţă selectării pachetelor ce le dorim modificate

Am spus mai sus ca poţi preciza o adresă sursă şi destinaţie. Dacă vei omite opţiunea privitoare la adresa sursă, atunci regula se va potrivi pentru orice adresă sursă. Analog, dacă omiţi opţiunea pentru adresa destinaţie, atunci regula se va potrivi pentru orice adresa destinaţie.

Poţi de asemenea indica un protocol specific ("-p" sau "--protocol"), cum ar fi TCP sau UDP; doar pachetele de acest tip se vor potrivi cu regula. Principalul motiv pentru a preciza unul dintre aceste protocoale este de a selecta porturi specifice: "--source-port" şi "--destination-port" (prescurtate "--sport" şi "--dport").

Aceste opţiuni îţi permite să specifici că numai pachetele cu anumite porturi destinaţie sau porturi sursă se vor potrivi cu regulii. Aceste opţiuni sunt folositoare, de exemplu, pentru redirectarea cererilor web (porturile TCP 80 sau 8080) şi nemodificarea celorlalte pachete.

Aceste opţiuni trebuie să fie introduse după opţiunea "-p" (care are ca alt efect încărcarea opţiunilor extinse pentru acel protocol). Poţi foloşi pentru porturi numere, sau nume precum cele din fişierul /etc/services.

Toate caracteristicile după care poţi selecta un pachet sunt detaliate în pagina de manual pentru iptables (man iptables).


Cum modificăm pachetele

În concluzie, acum ştim cum selectăm pachetele pe care le dorim modificate. Pentru a scrie regulile complete trebuie să spunem kernelului cu exactitate ceea ce dorim să facem pachetelor.


Folosirea NAT pentru modificarea adresei sursă

Doreşti să faci SNAT; să schimbi adresa sursă a conexiunilor cu ceva diferit. Acesta este realizat în chain-ul POSTROUTING, chiar înainte de a fi trimis pachetul; acesta este un detaliu important, deoarece înseamnă că orice altceva în sistemul Linux (rutare, filtrare de pachete) va vedea doar pachetul neschimbat. Mai înseamnă de asemenea că opţiunea "-o" (interfaţa de ieşire) poate fi folosită.

SNAT este specificat folosind opţiunea "-j SNAT"; iar opţiunea "--to-source" specifică o adresă IP, un şir de adrese IP, şi un port opţional sau un şir de porturi (doar în cazul protocoalelor UDP şi TCP).

## Schimba adresa sursă cu 1.2.3.4
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4

## Schimba adresa sursă cu 1.2.3.4, 1.2.3.5 sau 1.2.3.6
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6

## Schimba adresa sursă cu 1.2.3.4, şi porturile intre 1-1023
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4:1-1023


Masquerading

Există un caz particular de SNAT numit masquerading: ar trebui să fie folosit numai pentru adrese IP asignate dinamic, cum ar fi în cazul celor ce se conectează prin dial-up (pentru adrese IP statice, foloseşte SNAT ca mai sus).

Nu este necesar când faci masquerading să specifici adresa sursă: deoarece vei folosi adresa sursă a interfeţei prin care va ieşi pachetul. Dar ce este mai importat, dacă legătura cu ISP-ul cade, conexiunile (care acum sunt pierdute oricum) sunt uitate, acest lucru generând mai puţine probleme tehnice când legătura cu ISP-ul revine cu o nouă adresă IP.

## masqueradare pentru ppp0
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE


Folosirea NAT pentru modificarea adresei destinaţie (DNAT)

Aceasta se realizează în chain-ul PREROUTING, exact după primirea pachetului, aceasta însemnă că orice în sistemul Linux (rutare, filtrare de pachete) va vedea pachetul cu noua adresă destinaţie. Mai înseamna că opţiunea "-i" (interfaţă de intrare) poate fi folosita.

Se specifică folosirea DNAT cu ajutorul opţiunii "-j DNAT", iar opţiunea "--to-detination" specifică o adresă IP, un şir de adrese IP, şi un port opţional sau un şir de porturi (acest lucru fiind valabil doar pentru protocoalele UPD şi TCP).

 ## Schimba adresa destinaţie cu 5.6.7.8
 # iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8

 ## Schimba adresa destinaţie cu  5.6.7.8, 5.6.7.9 sau 5.6.7.10.
 # iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8-5.6.7.10

 ##Schimba adresa destinaţie a traficului spre portul 80 cu 5.6.7.8, port 8080.
 # iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 \
         -j DNAT --to 5.6.7.8:8080


Redirectare

Există un caz particular de DNAT numit redirectare: este o simplă convenţie care este echivalentă cu realizarea DNAT către adresa interfeţei prin care intră pachetele.

## Trimite traficul care vine pe portul 80 către squid (proxy-ul transparent
# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 \
         -j REDIRECT --to-port 3128

Observaţie: squid trebuie să fie configurat pentru a putea fi folosit ca proxy transparent!


Mapare complexă

Există câteva lucruri rafinate în folosirea NAT pe care majoritatea oamenilor nu vor avea nevoie să le folosească. Aceste lucruri sunt documentate mai jos pentru curioşi.


Selectarea de adrese multiple dintr-un sir

Dacă un şir de adrese IP este specificat, adresa IP care va fi folosită este cea cu cele mai puţine coexiuni active. Acest comportament furnizează load-balancing primar.


Realizarea de mapare NAT nulă

Poţi folosi ţinta "-j ACCEPT" pentru a permite realizarea conexiunii fără NAT


=Comportamentul NAT standard

Comportamentul obişnuit este să modifice conexiunea cât mai puţin posibil, cu excepţia regulilor date de către utilizator. Aceasta înseamna că nu vor fi remapate porturile decât dacă suntem obligaţi să realizăm acest lucru.


Mapare implicită a porturilor sursă

Chiar dacă folosirea NAT nu este ceruta pentru o conexiune, translatarea portului sursă poate fi făcut automat, dacă o alta conexiune a fost mapată peste una nouă. De exemplu consideraţi un caz care este comun în masquerading:

1. O conexiune web este realizată de la un sistem cu IP-ul 192.1.1.1 cu portul sursă 1024 către www.securityorg.net portul 80.

2. Aceasta conexiune este masqueradată de un sistem care se ocupa cu acest lucru, pentru a folosi IP-ul sursă al sistemului ce realizează masqueradarea (1.2.3.4)

3. Însuşi sistemul ce realizează masquerading iniţiază o conexiune către www.securityorg.net, portul 80, de la 1.2.3.4 (adresa interfeţei externe) portul 1024

4. Codul NAT va modifica portul sursă al celei de-a doua conexiuni cu 1025, astfel ca să nu existe conflict între cele două conexiuni.

Când se realizează aceasta mapare automată a sursei, porturile sunt împărţite în trei clase:

o Porturile sub 512
o Porturile între 512 şi 1023
o Porturile de la 1024, inclusiv, în sus

Un port nu va fi niciodată mapat automat într-o clasă diferită.


Ce se întâmplă când NAT-area nu reuşeşte

Dacă nu mai este disponibil nici un mod în care să se realizeze maparea unică a conexiunii cerute de către utilizator, conexiunea va fi abandonată. Acest comportament se aplica şi în cazurile în care pachetele nu au putut fi clasificate ca parte a unei conexiuni, deoarece sunt malformate, sau sistemul nu mai are memorie libera, etc.


Mapari multiple, Suprapuneri şi Conflicte

Dacă ai reguli care folosesc NAT pentru mapare de porturi aflate într-o rază comună, codul NAT este destul de inteligent pentru a evita conflicte. Aceasta pentru că, având doua reguli, este corectă maparea adresei sursă pentru 192.168.1.1 şi respectiv 192.168.1.2 în adresa 1.2.3.4.

Mai mult, poţi face mapare peste adrese IP reale folosite, atât timp cât aceste adrese trec de asemenea prin maşina care realizează maparea. Aşa că dacă ai o reţea asignată (1.2.3.0/24), dar ai o reţea interna care foloseşte aceasta clasa de IP-uri şi încă o reţea care foloseşte o clasă de adrese IP private 192.168.1.0/24, poţi să realizezi SNAT pentru adresele cu sursă IP 192.168.1.0/24 peste adresele din reţeaua 1.2.3.0, fără să îţi fie teamă de conflicte:

# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 \
          -j SNAT --to 1.2.3.0/24

Aceeaşi logică se aplică adreselor folosite de însuşi sistemul ce realizează NAT: în acest fel funcţionează şi masquerading-ul (prin folosirea împreună a adresei interfaţei de către pachetele masqueradate şi pachetele "reale" venite de la însuşi sistemul ca realizează masquerading-ul).

De altfel, poţi mapa aceleaşi pachete pe mai multe sisteme diferite, şi acestea vor fi folosite în comun. De exemplu, dacă nu doreşti să mappezi nimic peste adresa 1.2.3.5, ai putea să dai următoarea comandă:

# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 \
           -j SNAT --to 1.2.3.0-1.2.3.4 --to 1.2.3.6-1.2.3.254


Schimbarea destinaţiei conexiunilor generate local

Codul NAT îţi permite să introducî reguli în chainul OUTPUT având ca ţintă DNAT, dar acest lucru nu este în întregime suportat în kernelurile 2.4 (poate fi programat dar are nevoie de noi opţiuni, testări, şi putină programare, aşa că dacă nimeni nu îl contactează pe Rusty pentru al scrie, nu o să fie disponibil prea devreme).

Limitarea curenta este faptul că poţi să schimbi destinaţia pachetelor doar către sistemul local ( "-j DNAT --to 127.0.0.1"), nu şi către alte sisteme, în caz contrar replicile nu vor fi primite în mod corect înapoi.


Protocoale speciale

Unele protocoale nu accepta să fie NAT-uite. Pentru fiecare dintre aceste protocoale, două module speciale trebuiesc scrie; unul pentru urmărirea conexiunilor şi al doilea pentru operaţia de NAT-are propriu-zisă.

În cadrul distribuţiei netfilter, exista module pentru ftp: ip_conntrack_ftp.o şi ip_nat_ftp.o. Dacă le inserezi în kernel (insmod) sau le compilezi în kernel, atunci realizarea oricărui tip de NAT pentru conexiuni ftp ar trebui să funcţioneze. Dacă nu, atunci poţi foloşi ftp pasiv, şi chiar şi atunci s-ar putea să nu funcţioneze foarte sigur dacă vrei să realizezi altceva decât SNAT.


Avertismente privind folosirea NAT

Dacă realizezi NAT pentru o conexiune, pachetele venind din ambele sensuri (din afara şi din înăuntrul reţelei) trebuie să treacă prin sistemul care realizează NAT-area, în caz contrar lucrurile nu vor funcţiona sigur. În special, codul urmării conexiunilor reasamblează fragmentele, care înseamnă că nu numai depistarea conexiunilor nu va fi sigură, dar chiar şi pachetele s-ar putea să nu treacă deloc, ca fragmente fiind reţinute.


Folosirea SNAT şi rutarea

Dacă doreşti să realizezi SNAT, vei dori să fii sigur că fiecare maşină la care ajung pachete care sunt parte a unei conexiuni SNAT, vor trimite pachetele replică înapoi la sistemul care realizează SNAT-ul. De exemplu, dacă mapezi nişte pachete ce ies, cu adresa sursă 1.2.3.4, atunci ruterul extern trebuie să ştie că trebuie să trimită pachetele replica înapoi (care vor avea adresa destinaţie 1.2.3.4) către acest sistem. Acest lucru poate fi realizat în următoarele moduri:

1. Dacă realizezi SNAT peste adresa propriului sistem (pentru care rutarea şi toate celelalte merg deja), nu trebuie să faci nimic

2. Dacă realizezi SNAT peste o adresa nefolosita din propriul LAN (de exemplu, mapezi peste 1.2.3.99, o adresă IP nefolosită din reţeaua ta 1.2.3.0/24), sistemul ce realizează NAT va trebui să răspundă la cereri ARP pentru acea adresă ca şi pentru propria sa adresă: cea mai simpla metodă de a rezolva acest lucru este să creezi un alias pentru adresa IP, de exemplu:

# ip address add 1.2.3.99 dev eth0

3. Dacă realizezi SNAT peste o adresă complet diferită, va trebui să te asiguri că maşinile la care vor ajunge pachetele SNAT-atate vor ruta aceasta adresă înapoi către sistemul pe care se realizează SNAT-ul. Aceasta este realizata deja dacă sistemul care realizează SNAT-ul este gateway-ul lor default, în caz contrar va trebui să adaugi o rută pe fiecare sistem prin care trec pachetele modificate.


Folosirea DNAT pentru adrese aflate în aceeaşi reţea.

Dacă realizezi forwardare de porturi înapoi în aceeaşi reţea, trebuie să fii sigur ca atât pachetele viitoare cât şi pachetele ce vin în replică vor trece prin sistemul ce realizează DNAT-ul (pentru ca acestea să fie modificate). Codul NAT va bloca (înca din ver. 2.4.0-test6) pachetele ICMP de redirectare care rezultă atunci când pachetele NAT-ate se îndreaptă către aceeaşi interfaţă spre care au venit, dar serverul care primeşte acele pachete va încercă în continuare să răspundă direct către client (care nu va recunoaşte pachetele replică).

Cazul clasic este când un sistem din reţeaua internă încearcă să acceseze serverul www "public", care este de fapt DNAT-at de la adresa publică (1.2.3.4) către un sistem din reţeaua internă (192.168.1.1), astfel:

# iptables -t nat -A PREROUTING -d 1.2.3.4 \
     -p tcp --dport 80 -j DNAT --to 192.168.1.1

O cale este să rulezi un server de DNS intern care să ştie adresa IP reală (internă) al site-ului public de web, şi să înainteze toate celelalte cereri către un server DNS extern. Aceasta înseamna ca va fi folosita o conexiune directă către server-ul de web, fără să mai fie nevoie de a trece prin sistemul care realizează NAT.

Cealaltă cale este să realizezi, pe sistemul care face DNAT, maparea adresei sursă spre propria lui adresă pentru conexiunile venind din reţeaua internă, păcălind serverul de web să trimită pachetele replică spre maşina care se ocupă cu NAT-area. Pentru acest exemplu vom proceda astfel (presupunem ca adresa IP a sistemului care realizează NAT este 192.168.1.250):

# iptables -t nat -A POSTROUTING -d 192.168.1.1 -s 192.168.1.0/24 \
      -p tcp --dport 80 -j SNAT --to 192.168.1.250

Deoarece regula din chain-ul PREROUTING este executată prima, pachetele vor fi deja destinate pentru server-ul de web intern: putem preciza care din pachete sunt din reţeaua internă după adresa IP sursă.


Mulţumiri

Mulţumirile sunt în primul rând pentru WatchGuard, şi David Bonn, care a crezut în ideea netfilter destul pentru a mă susţine să o transform în realitate. Şi pentru toţi ceilalţi, care m-au suportat când făceam pe grozavul când am învăţat despre urâţenia NAT-ului, în special celor ce mi-au citit jurnalul.

Rusty.