Avanti Indietro Indice

6. Spiega come manipolare i pacchetti

Ora si è appreso come selezionare i pacchetti che si vogliono manipolare. Per completare la propria regola è inoltre necessario specificare al kernel con precisione che cosa si vuole fare a questi pacchetti.

6.1 Source NAT

Se si vuole effettuare il Source NAT allora si deve cambiare l'indirizzo sorgente della connessione con qualcosa di differente. Questo però deve essere fatto nella catena POSTROUTING, appena prima che il pacchetto sia inviato. Questo è un dettaglio importante, perché solo così qualsiasi altra cosa nella Linux box (instradamento, filtraggio dei pacchetti) vedrà il pacchetto come invariato. Ciò significa inoltre che si potrà utilizzare l'opzione `-o' (interfaccia uscente).

Il Source NAT si specifica usando `-j SNAT', l'opzione `--to-source' permette di indicare un indirizzo o un intervallo di indirizzi IP e opzionalmente una o un intervallo di porte (però solo con i protocolli UDP e TCP).

## Cambia l'indirizzo sorgente in 1.2.3.4.
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4

## Cambia l'indirizzo sorgente in 1.2.3.4, 1.2.3.5 oppure 1.2.3.6
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6

## Cambia l'indirizzo sorgente in 1.2.3.4, porte 1-1023
# iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023

Masquerading

Esiste un caso specializzato di Source NAT denominato mascheramento (masquerading): dovrebbe essere utilizzato solo se gli indirizzi IP sono assegnati dinamicamente, come ad esempio nel caso di connessione via modem (dial up), nel caso di indirizzi IP statici invece si usi il già citato SNAT.

Non è necessario con il mascheramento (masquerading) indicare esplicitamente l'indirizzo sorgente in quanto sarà utilizzato l'indirizzo dell'interfaccia da cui il pacchetto uscirà. Ancora più importante è il fatto che se il collegamento dovesse interrompersi, la connessione sarà dimenticata (sarebbe comunque persa), in questo modo non ci saranno grossi problemi quando la connessione sarà ristabilita, naturalmente con un nuovo indirizzo IP.

## Maschera qualsiasi cosa esca da ppp0.
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

6.2 Destination NAT

Questo avviene nella catena PREROUTING, appena il pacchetto arriva; ciò significa che qualsiasi cosa nella Linux box (instradamento, filtraggio dei pacchetti) vedrà il pacchetto arrivato con il suo indirizzo di destinazione `reale'. Ciò permette di utilizzare l'opzione `-i' (interfaccia ingresso).

Destination NAT si specifica usando `-j DNAT', l'opzione `--to-destination' permette di specificare un indirizzo o un intervallo di indirizzi IP e opzionalmente una o un intervallo di porte (solo per i protocolli UDP e TCP).

## Cambia l'indirizzo di destinazione in 5.6.7.8
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8

## Cambia l'indirizzo di destinazione in 5.6.7.8, 5.6.7.9 oppure 5.6.7.10.
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8-5.6.7.10

## Cambia l'indirizzo di destinazione del traffico web in 5.6.7.8, porta 8080.
# iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 \
        -j DNAT --to 5.6.7.8:8080

Redirezione

Esiste un caso specializzato di Destination NAT chiamato redirection (redirezione), ed è semplicemente una comodità in più in quanto esattamente uguale al DNAT effettuato però esclusivamente sull'indirizzo associato all'interfaccia di ingresso.

## Invia i pacchetti diretti alla porta 80 verso il proxy (trasparente) 
## squid
# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 \
        -j REDIRECT --to-port 3128

Si tenga presente che squid deve essere configurato in modo tale da sapere che deve agire come proxy trasparente!

6.3 Mapping in dettaglio

Ci sono alcune sottigliezze nel NAT con cui la maggior parte delle persone non avrà mai a che fare. Queste sono documentate qui di seguito per i curiosi.

Selezione di indirizzi multipli in un intervallo

Se è dato un intervallo di indirizzi IP, l'indirizzo IP da usare è scelto in base all'IP correntemente meno utilizzato per le connessioni conosciute dalla macchina. Questo garantisce il load-balancing primitivo.

Creare mapping NAT nullo

Si può utilizzare l'obiettivo `-j ACCEPT' per lasciare che la connessione prosegua senza che avvenga alcuna operazione di NAT.

Comportamento Standard del NAT

Il comportamento standard è di alterare la connessione il meno possibile entro i vincoli delle regole date dall'utente. Questo significa che le porte non saranno rimappate a meno che non ce ne sia bisogno.

Mapping implicito delle porte sorgenti

Anche quando il NAT non è richiesto per una connessione, la traduzione della porta sorgente può avvenire implicitamente se un'altra connessione è stata mappata sopra la nuova. Si consideri il caso del mascheramento che è comune:

  1. Una connessione è stabilita da una box 192.1.1.1 dalla porta 1024 verso www.netscape.com porta 80
  2. Questa è mascherata dalla masquerading box per usare il suo indirizzo IP sorgente (1.2.3.4).
  3. La masquerading box prova a effettuare una connessione web con www.netscape.com sulla porta 80 dall'indirizzo 1.2.3.4 (indirizzo dell'interfaccia esterna) porta 1024.
  4. Il codice NAT altera la porta sorgente della seconda connessione ponendola a 1025, così le due non si intralciano.

Quando si ha questo mapping implicito della sorgente, le porte sono divise in tre classi:

Una porta non sarà mai mappata implicitamente in una classe differente.

Cosa succede quando il NAT fallisce

Se non esiste un modo per mappare unicamente una connessione come richiede l'utente, allora sarà rifiutata. Questo accade anche ai pacchetti che non possono essere classificati come appartenenti ad una qualsiasi connessione, in quanto malformati o perché la box ha esaurito la memoria, ecc.

Mapping multipli, sovrapposizioni, conflitti

Si possono avere regole NAT che mappano i pacchetti sullo stesso intervallo; il codice del NAT è sufficientemente abile ad evitare conflitti. Perciò pur avendo due regole che mappano gli indirizzi sorgente 192.168.1.1 e 192.168.1.2 su 1.2.3.4 tutto funzionerà correttamente.

In aggiunta si possono mappare gli indirizzi IP reali usati, sempre che questi indirizzi attraversino la box che effettua il mapping. Quindi se si ha una rete assegnata (1.2.3.0/24) e una rete interna che usa questi indirizzi, e un'altra ancora che usa indirizzi internet privati del tipo 192.168.1.0/24, si può effettuare tranquillamente il NAT dei pacchetti con indirizzo sorgente 192.168.1.0/24 sulla rete 1.2.3.0, senza aver paura di eventuali sovrapposizioni.

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

La stessa logica si può applicare agli indirizzi usati dalla NAT box stessa: è così che funziona il masquerading (condividendo l'indirizzo dell'interfaccia tra pacchetti mascherati e pacchetti reali provenienti dalla box stessa).

Inoltre, si possono mappare gli stessi pacchetti su differenti obiettivi, ed essi saranno suddivisi. Per esempio, se non si vuole mappare nulla sopra 1.2.3.5, allora si può usare:

# 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

Alterare la destinazione delle connessioni generate localmente

Il codice NAT consente di inserire delle regole nella catena OUTPUT ma ciò non è pienamente supportato nel kernel 2.4 (potrebbe esserlo ma richiederebbe una nuova opzione di configurazione, una fase di test e lo sviluppo di una buona quantità di codice, quindi fino a quando qualcuno non contatterà Rusty per realizzarlo esso non sarà disponibile in tempi brevi.

L'attuale limitazione consente di cambiare la destinazione solo verso la macchina locale (es. `j DNAT --to 127.0.0.1') e non verso una qualsiasi altra macchina. In caso contrario le risposte non saranno tradotte correttamente.


Avanti Indietro Indice