NAT ovvero Network Address Tranlation permette di manipolare un pacchetto IP modificando l'indirizzo IP sorgente o di destinazione.
Ovviamente il dispositivo che esegue il NAT quando riceve il pacchetto di ritorno esegue l'operazione inversa, sulla base di una tabella di natting che si tiene in memoria.
Il Nat viene utilizzato in varie occasioni, dove si ha la necessità ad esempio di redirezionare il traffico su un unico IP, oppure forwardare il traffico con una certa porta di destinazione ad un'altro host oppure su un'altra porta.
Su Linux si usa definire il natting con due modalità specifiche:
SNAT: Source NAT, cioè l'alterazione dell'IP sorgente del primo pacchetto che apre la connessione. Avviene sempre dopo che il pacchetto ha subito il routing (post-routing).
Un esempio di SNAT è il masquerading, con cui tutti gli IP sorgenti di una rete locale vengono convertiti in un unico IP sorgente (del dispositivo che fa masquerading) con cui i pacchetti vengono mandati in rete.
DNAT: Destination NAT, cioè l'alterazione dell'IP di destinazione del primo pacchetto.
A differenza del SNAT il DNAT avviene sempre prima che il pacchetto subisca il routing (pre-routing).
Una forma di DNAT è il port-forwarding e trasparent proxy.
Per quanto riguarda iptables, le catene (chain) da considerare per i vari tipi di NAT sono:
PREROUTING (DNAT, per i pacchetti in arrivo).
Esiste inoltre un "caso speciale" chiamato redirection. E' un DNAT effettuato esclusivamente sull'interfaccia di ingresso del pacchetto. Ovvero si può eseguire un redirect di tuti i pacchetti provenienti su eth0 con destination port 80 e redirezionarli sempre su eth0 ma sulla porta 12345.
OUTPUT (DNAT, per i pacchetti generati della macchina locale)
POSTROUTING (SNAT, per i pacchetti in uscita)
Esempi di NAT:
Port forwarding
iptables -A PREROUTING -t nat -p tcp -d 10.0.0.150 --dport 8080 -j DNAT --to 172.16.1.128:80
Ovvero tutti i pacchetti che hanno destinazione 10.0.0.150 sulla porta 8080vengono riderizionati al'ip 172.16.1.128 alla porta 80.
Source Natting
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 10.0.0.1
Tutti i pacchetti che escono dall'interfaccia eth0, subiscono una variazione dell'ip sorgente in 10.0.0.1
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 10.0.0.1-10.0.0.254
Come sopra, con la differenza che l'ip sorgente può essere alterato sia in 10.0.0.1 o 10.0.0.154
Masquerading
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
Tutto ciò che passa in uscita dal proprio modem viene mascherato con l'ip pubblico assegnato dal proprio ISP.
Destination Natting
iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth1 -j DNAT --to 10.0.0.1:8080
Tutti i pacchetti TCP, arrivati dall'interfaccia eth1 con destinazione porta 80 vengono "dirottati" all'ip 10.0.0.1 alla porta 8080.
Segue un esempio di script che esegue il masquerading di una rete locale e il destination natting di un server PPTP interno a dei limitati IP pubblici.
Può essere modificato e adattato ai propri scopi.
#!/bin/sh
#
# masquerading.sh - Version 20040531 - Coresis
#
#### DEBUGGING ###
set -x
### FLUSHING CHAIN ### Azzera e pulisce ogni regola esistente
/sbin/iptables -F
/sbin/iptables -F -t nat
/sbin/iptables -X
/sbin/iptables -Z
### DEFAULT CHAIN ### Imposta le policy di default
/sbin/iptables -P INPUT DROP
/sbin/iptables -P FORWARD DROP
/sbin/iptables -P OUTPUT DROP
/sbin/iptables -t nat -P POSTROUTING DROP
/sbin/iptables -t nat -P PREROUTING DROP
### SETTING IPFORWARDING ### Abilita il forwarding di pacchetti non locali - FONDAMENTALE
/bin/echo "1" > /proc/sys/net/ipv4/ip_forward
### DISABLE RESPOND TO BROADCAST ### Non risponde ai ping inviati al browadcast della subnet
/bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
### ENABLE BAD ERROR MESSAGE PROTECTION ### Ignora finti messaggi di errore ICMP
/bin/echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
### DISABLE ICMP REDIRECT ACCEPTANCE ### Non accetta pacchetti ICMP di route redirection
/bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects
### SETTING ANTISPOOFING PROTECTION ###
/bin/echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
### DON'T RESPOND TO BROADCAST PINGS ###
/bin/echo "1" > /proc/sys/net/ipv4/conf/all/log_martians
### Qui vengono definite alcune variabili che successivamente sono usate nelle regole - MODIFICARE SECONDO I PROPRI PARAMETRI
# External Public Interface
EXTIF="eth1"
# Internal Private Interface
INTIF="eth0"
# Host Public IP (su eth1)
EGO="211.121.111.111"
# Internal LAN IP (su eth0)
LANIN="10.0.0.0/24"
# Trusted public network (da cui si permettono collegamenti SSH)
TRUSTED="13.18.151.0/24"
# IP/rete di un utente esterno abilitato a connetterci al server VPN interno
USER="112.56.10.32/28"
# IP Interno del server VPN
VPNSERVER="10.0.0.77"
# RFC IPs Classi di indirizzi dedicate a utilizzi privati o particolari e non routate su Internet
LOOPBACK="127.0.0.0/8"
CLASS_A="10.0.0.0/8"
CLASS_B="172.16.0.0/12"
CLASS_C="192.168.0.0/16"
CLASS_D_MULTICAST="224.0.0.0/4"
CLASS_E_RESERVED_NET="240.0.0.0/5"
# ANTISPOOF Adesso iniziano le regole vere e proprie. Le prime sono generiche regole anti-spoof per IP noti dall'interfaccia pubblica.
/sbin/iptables -A INPUT -i $EXTIF -s $EGO -j DROP
/sbin/iptables -A INPUT -i $EXTIF -s $CLASS_A -j DROP
/sbin/iptables -A INPUT -i $EXTIF -s $CLASS_B -j DROP
/sbin/iptables -A INPUT -i $EXTIF -s $CLASS_C -j DROP
/sbin/iptables -A INPUT -i $EXTIF -s $CLASS_D_MULTICAST -j DROP
/sbin/iptables -A INPUT -i $EXTIF -s $CLASS_E_RESERVED_NET -j DROP
/sbin/iptables -A INPUT -i $EXTIF -d $LOOPBACK -j DROP
# LOOP RULE Permettiamo il traffico di loopback
/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A OUTPUT -o lo -j ACCEPT
# LAN IN ACCESS Regole che permettono l'accesso al firewall Linux dagli IP della rete Interna - Potrebbero essere più ristrette e limitarsi all'IP dell'amministratore
/sbin/iptables -A INPUT -i $INTIF -s $LANIN -j ACCEPT
/sbin/iptables -A OUTPUT -o $INTIF -d $LANIN -j ACCEPT
# LAN IN OUT Seguono le regole che gestiscono il masquerading della rete interna
/sbin/iptables -A FORWARD -s $LANIN -d 0/0 -j ACCEPT Forwarda tutti i pacchetti dalla rete interna a qualsiasi destinazione
/sbin/iptables -A FORWARD -m state --state ESTABLISHED,RELATED -d $LANIN -j ACCEPT Permette il forwarding di tutti i pacchetti correlati a comunicazioni esistenti
/sbin/iptables -t nat -A POSTROUTING -o $EXTIF -s $LANIN -j MASQUERADE Maschera gli IP sorgenti Interni con l'IP dell'interfaccia pubblica
# GENERAL Regole generali per permettere all'host locale di collegarsi a IP remoti e ricevere i pacchetti di risposta (Nota: si riferiscono alle attività che vengono fatte direttamente dalla macchina Linux locale e non dagli host che la usano come firewall)
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
# SSH Regole per permettere l'accesso al server SSH locale da un IP esterno fidato precedentemente indicato
/sbin/iptables -A INPUT -s $TRUSTED -p TCP --dport 22 -j ACCEPT
# VPN NATTING Esegue un DNAT di un server VPN che usa pptp (TCP porta 1723) e GRE (IP type 47) e permette l'accesso al server solo da un IP sorgente definito
/sbin/iptables -A FORWARD -s $USER -p TCP --dport 1723 -j ACCEPT
/sbin/iptables -t nat -A PREROUTING -d $EGO -p tcp --dport 1723 -j DNAT --to-dest $VPNSERVER:1723
/sbin/iptables -t nat -A PREROUTING -d $EGO -p 47 -i eth1 -j DNAT --to-dest $VPNSERVER
# LOGGING Log di tutti i pacchetti, esclusi i broadcast, prima di essere droppati dalla regole di default. I logging viene fatto con livello debug per isolarlo da altri log di sistema. Per cui è necessario scrivere in /etc/syslog.conf una riga tipo:
kern.debug /var/log/iptables.log
/sbin/iptables -A INPUT -m pkttype --pkt-type ! broadcast -j LOG --log-level=DEBUG --log-prefix="[INPUT DROP] : "
/sbin/iptables -A OUTPUT -m pkttype --pkt-type ! broadcast -j LOG --log-level=DEBUG --log-prefix="[OUTPUT DROP] : "
Segue un semplice esempio di configurazione di un Linux che agisce come firewall fra una rete locale e Internet. E' applicabile ad un caso abbastanza tipico in cui Linux è il default gateway della rete interna e gestisce il natting e l'uscita (secondo diversi gruppi con criteri di accesso applicabili ai singoli indirizzi IP della lan, nll'esempio 10.42.42.0/24).
L'interfaccia eth1 è quella collegata alla rete interna, i pacchetti che arrivano da essa vengono nattata e mascherati in uscita sull'interfaccia esterna eth0.
Sono definite le seguenti classi di accesso:
- ACCESSO-MAIL: Permesso soltanto l'accesso ad un server di posta esterno (della azienda) e niente altro.
- ACCESSO-WEB: Permesso l'accesso al server di posta e alla navigazione (porta 80 e 443)
- ACCESSO-COMPLETO: Accesso senza limiti ad Internet su tutte le porte
Ad ogni IP interno viene applicata una di queste classi di accesso.
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:ACCESSO-COMPLETO - [0:0]
:ACCESSO-MAIL - [0:0]
:ACCESSO-WEB - [0:0]
# Si definisce un host (di un admin) che può accedere in SSH al firewall per gestione e manutenzione remota
-A INPUT -p tcp --dport 22 -s 10.42.42.250 -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -j LOG
# Si associano i singoli indirizzi IP interni a diverse classi di accesso
-A FORWARD -s 10.42.42.11 -i eth1 -j ACCESSO-WEB
-A FORWARD -s 10.42.42.10 -i eth1 -j ACCESSO-WEB
-A FORWARD -s 10.42.42.5 -i eth1 -j ACCESSO-COMPLETO
-A FORWARD -s 10.42.42.4 -i eth1 -j ACCESSO-COMPLETO
-A FORWARD -s 10.42.42.3 -i eth1 -j ACCESSO-COMPLETO
# Caso particolare, in cui si permette l'accesso completo all'host che presenta uno specifico mac address, invece di identificarlo tramite indirirro IP
-A FORWARD -i eth1 -m mac --mac-source 00:00:86:3F:D5:C3 -j ACCESSO-COMPLETO
# Di default tutti i client interni possono accedere alla posta
-A FORWARD -s 10.42.42.0/255.255.255.0 -i eth1 -j ACCESSO-MAIL
# Si gestiscono i pacchetti di ritorno delle connessioni forwardate dal firewall
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# Si permette libera uscita per i pacchetti che partono dal firewall stesso. Volendo è possibile essere più rigorosi e stringenti, a scapito dell'usabilità del sistema
-A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
# Si definisce la classe ACCESSO-COMPLETO, dove è abilitato il forwarding su tutte le porte
-A ACCESSO-COMPLETO -j ACCEPT
# La classe ACCESSO-MAIL permette ldi raggiungere un solo IP (il server di posta) sulle porte 110 (pop3) e 25 (smtp). Viene concessa la possibilità di usare qualsiasi server dns esterno (si potrebbe specificare l'indirizzo di un solo DNS server)
-A ACCESSO-MAIL -p udp -m udp --dport 53 -j ACCEPT
-A ACCESSO-MAIL -p tcp -m tcp --dport 25 -d 213.215.144.242 -j ACCEPT
-A ACCESSO-MAIL -p tcp -m tcp --dport 110 -d 213.215.144.242 -j ACCEPT
# La classe ACCESSO-WEB, rispetto al precedente aggiunge la possibilità di raggiungere le porte 80 e 443 e quindi la navigazione
-A ACCESSO-WEB -p tcp -m tcp --dport 80 -j ACCEPT
-A ACCESSO-WEB -p tcp -m tcp --dport 443 -j ACCEPT
-A ACCESSO-WEB -j ACCESSO-MAIL
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# Con questa regola si nattato tutti gli IP sorgenti della rete interna sull'interfaccia esterna. Notare che l'effettiva possibilità di uscire su Internet da parte dei singoli IP è determinata delle regole di FORWARD sopra definite
-A POSTROUTING -s 10.42.42.0/255.255.255.0 -o eth0 -j MASQUERADE
COMMIT