Ora conosci come selezionare i pacchetti che vuoi manipolare. Per completare la tua regola, dobbiamo dire al kernel con precisione che cosa vogliamo fare a questi pacchetti.
Se vuoi effettuare il Source NAT allora devi 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
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
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).
Per alterare la destinazione dei pacchetti generati localmente si può usare la catena OUTPUT, ma questo è inusuale.
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 eth1 -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 eth1 -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 eth1 \
-j DNAT --to 5.6.7.8:8080
## Redireziona i pacchetti locali diretti all'indirizzo 1.2.3.4 verso loopback.
# iptables -t nat -A OUTPUT -d 1.2.3.4 -j DNAT --to 127.0.0.1
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 tuo proxy (trasparente)
## squid
# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 \
-j REDIRECT --to-port 3128
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.
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.
Si può usare l'obiettivo `-j ACCEPT' per lasciare che la connessione prosegua senza che avvenga alcuna operazione di 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.
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. Considera il caso di mascheramento, che è comune:
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.
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.
Puoi 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 funziona correttamente.
In aggiunta, puoi mappare gli indirizzi IP reali usati, sempre che questi indirizzi attraversino la box che effettua il mapping. Quindi se hai 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, puoi 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, puoi mappare gli stessi pacchetti su differenti obiettivi, ed essi saranno suddivisi. Per esempio, se non vuoi mappare nulla sopra 1.2.3.5, allora puoi 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
Se la destinazione di un pacchetto generato localmente viene cambiata (es. dalla catena OUTPUT), e questo causa il passaggio del pacchetto attraverso una diversa interfaccia, allora anche l'indirizzo sorgente sarà modificato con quello dell'interfaccia. Per esempio, cambiare la destinazione di un pacchetto di loopback che passa per eth0 risulterà nella sostituzione dell'indirizzo sorgente 127.0.0.1 con l'indirizzo dell'interfaccia eth0; diversamente da altri mapping sulla sorgente questo avviene immediatamente. Naturalmente entrambi questi mapping sono invertiti nei pacchetti di risposta che arrivano.