[Precedente: Packet Filtering]
[Indice]
[Successivo: Reindirizzamento (Port Forwarding)]
PF: NAT
Indice
Introduzione
La Network Address Translation (NAT) è il modo di mappare un'intera
rete (o più di una) con un singolo indirizzo IP. La NAT è necessaria
quando il numero di indirizzi IP assegnati dall'Internet Service
Provider è inferiore al numero totale di computer che si vorrebbe
avessero accesso a Internet. La NAT è descritta nella
RFC 1631,
"L'IP Network Address Translator (NAT)."
La NAT sfrutta il blocco di indirizzi riservati descritti nella
RFC 1918,
"Allocazione di Indirizzi per Reti Private."
Di solito la rete locale viene creata utilizzando uno o più dei
seguenti blocchi di network. Essi sono:
10.0.0.0/8 (10.0.0.0 - 10.255.255.255)
172.16.0.0/12 (172.16.0.0 - 172.31.255.255)
192.168.0.0/16 (192.168.0.0 - 192.168.255.255)
Un sistema OpenBSD che esegue la NAT avrà almeno due interfaccie di
rete, una per Internet e l'altra per la rete locale. La NAT trasla
le richieste provenienti dalla rete locale così da apparire come se
venissero tutte dal sistema OpenBSD.
Come funziona la NAT
Quando un client di una rete locale contatta un host su Internet,
invia pacchetti destinati a quell'host. Questi pacchetti contengono
tutte le informazioni di indirizzamento necessari per raggiungere la
loro destinazione. NAT interagisce con queste informazioni:
- Indirizzo IP sorgente (per esempio, 192.168.1.35)
- Porta TCP o UDP sorgente (per esempio, 2132)
Quando i pacchetti attraversano il gateway NAT, questi saranno
modificati così da apparire come se venissero direttamente dal
gateway NAT. Il gateway NAT registrerà i cambiamenti effettuati nella
sua tabella di stato così può a) eseguire le operazioni inverse sui
pacchetti di ritorno e b) assicurarsi che i pacchetti di ritorno siano
passati attraverso il firewall e non siano bloccati. Per esempio
possono essere fatti i seguenti cambiamenti:
- Indirizzo IP sorgente: sostituito con l'indirizzo esterno del
gateway (per esempio, 24.5.0.5)
- La porta sorgente: sostituita con una porta non usata del gateway
scelta a caso (per esempio, 53136)
Sia l'host locale che quello di Internet non si accorgono di questi
cambiamenti. Per il computer della rete locale, il sistema NAT è
semplicemente il gateway per Internet. L'host di Internet è
completamente ignaro dell'esistenza della workstation locale e il
pacchetto apparirà come se venisse direttamente dal sistema NAT.
Quando l'host di Internet risponde ai pacchetti ricevuti dalla
workstation locale, lo fa indirizzando i pacchetti all'IP del gateway
NAT (24.5.0.5) e alla porta traslata (53136). Il gateway NAT cercherà
nella tabella di stato una corrispondenza tra i pacchetti in arrivo
e una connessione già stabilita. Verrà trovata un'unica corrispondenza
basata sulla combinazione IP/porta che consente a PF di capire che il
pacchetto appartiene a una connessione esistente iniziata dall'host
locale 192.168.1.35. PF farà quindi gli opposti necessari cambiamenti
e invierà i pacchetti di risposta alla workstation interna.
La traslazione dei pacchetti ICMP avviene allo stesso modo ma senza
modificare la porta sorgente.
NAT e Packet Filtering
NOTA: I pacchetti traslati devono ancora
passare attraverso il firewall e saranno bloccati o passeranno in base
alle regole che sono state definite. Una sola eccezione a
questa regola si ha quando la keyword pass viene usata con la
regola di nat. Questo permette ai pacchetti traslati di
oltrepassare le regole del firewall.
Dato che la traslazione avviene prima del filtraggio occorre
prestare attenzione al fatto che il firewall vedrà i pacchetti
traslati con IP e porta ottenuti in Come lavora la NAT.
IP Forwarding
Dato che la NAT è quasi sempre usata su routers e network gateway,
probabilmente su una macchina OpenBSD sarà necessario abilitare l'IP
forwarding per consentire ai pacchetti di viaggiare tra diverse
interfaccie di rete. L'IP forwarding è abilitato usando il meccanismo
sysctl(3):
# sysctl net.inet.ip.forwarding=1
# sysctl net.inet6.ip6.forwarding=1 (se si usa IPv6)
Per rendere questi cambiamenti permanenti occorre aggiungere le
seguenti linee al file
/etc/sysctl.conf:
net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1
Nell'installazione di default queste linee sono presenti ma commentate
(con il prefisso #). Rimuovere i # e salvare il file.
L'IP forwarding sarà abilitato al riavvio del computer.
Configurare la NAT
La regola di NAT in pf.conf ha una sintassi del tipo:
nat [pass] [log] on interface [af] from src_addr
[port src_port] to \
dst_addr [port dst_port] ->
ext_addr [pool_type] [static-port]
- nat
- La keyword presente all'inizio di una regola di NAT.
- pass
- Consente ai pacchetti traslati di oltrepassare le regole del
firewall.
- log
- esegue il log di pacchetti che hanno una corrispondenza utilizzando
pflogd(8).
Di solito in una connessione solo il primo pacchetto che ha una
corrispondenza viene loggato.
Per loggare tutti i pacchetti che hanno una corrispondenza
usare log (all).
- interface
- Il nome dell'interfaccia o il gruppo di interfaccie di rete
sulle quali effettuare la traslazione dei pacchetti.
- af
- La famiglia di indirizzi inet per IPv4 o inet6
per IPv6. Di solito PF è in grado di determinare questi parametri
sulla base degli indirizzi sorgente/destinazione.
- src_addr
- L'indirizzo sorgente (interno) dei pacchetti che saranno
traslati. L'indirizzo sorgente può essere specificato come:
- Un singolo indirizzo IPv4 o IPv6.
- Un blocco di network
CIDR.
- Un nome di dominio assegnato che sarà risolto via DNS quando
saranno caricate le regole di configurazione. Nelle regole tutti gli
indirizzi IP verranno sostituiti ai nomi di dominio.
- Il nome di un'interfaccia di rete. Ogni indirizzo IP assegnato
all'interfaccia verrà sostituito al nome nella regola durante il
caricamento di queste.
- Il nome di un'interfaccia di rete seguito da una
/netmask (per esempio /24). Ogni indirizzo IP
assegnato all'interfaccia è associato con una netmask per formare un
blocco CIDR network sostituito nella regola.
- Il nome di un'interfaccia di rete seguito da uno di queti
parametri:
- :network - sostituisce un blocco di CIDR network
(per esempio, 192.168.0.0/24)
- :broadcast - sostituisce l'indirizzo di broadcast
di una network (esempio, 192.168.0.255)
- :peer - sostituisce l'indirizzo IP peer su un link
point-to-point
- Inoltre il parametro :0 può essere aggiunto sia a
un nome di interfaccia che ad ognuno dei parametri visti
precedentemente per indicare a PF che nella sostituzione non dovrebbero
essere inclusi indirizzi IP alias. Questi parametri possono anche
essere usati quando l'interfaccia è tra parentesi.
Esempio: fxp0:network:0
- A tabella.
- Ognuno degli indirizzi specificati precedentemente ma negati
utilizzando il parametro ! ("not").
- Un set di indirizzi usando una lista.
- La keyword any con il significato di tutti gli indirizzi
- src_port
- La porta sorgente nell'header del layer 4 del pacchetto. Le porte
possono essere specificate come:
- Un numero tra 1 e 65535
- Un nome di servizio valido da
/etc/services
- Un set di porte utilizzando una lista
- Un range:
- != (diverso)
- < (minore)
- > (maggiore)
- <= (minore uguale)
- >= (maggiore uguale)
- >< (range)
- <> (range inverso)
- Gli ultimi due operatori sono binari (prendono due
argomenti) che non includono gli argomenti nel range.
- : (range inclusivo)
- Anche il range inclusivo è un operatore binario e include
gli argomenti nel range.
Solitamente l'opzione port non è utilizzata nelle regole di
nat perchè l'obiettivo è di effettuare la NAT per tutto il
traffico indipendentemente dalle porte utilizzate.
- dst_addr
- L'indirizzo di destinazione dei pacchetti da traslare.
L'indirizzo destinazione è specificato allo stesso modo dell'indirizzo
sorgente.
- dst_port
- La porta destinazione nell'header del layer 4 del pacchetto.
Questa porta è specificata allo stesso modo della src_port.
- ext_addr
- L'indirizzo pubblico del gateway NAT utilizzato per la
traslazione dei pacchetti. L'indirizzo esterno sarà specificato come:
- Un singolo indirizzo IPv4 o IPv6.
- Un blocco CIDR
network.
- Un nome di dominio assegnato che verrà risolto via DNS quando
saranno caricate le regole di configurazione.
- Il nome di un'interfaccia di rete esterna. Ogni indirizzo IP
assegnato all'interfaccia verrà sostituito al nome nella regola
durante il caricamento di queste.
- Il nome di un'interfaccia di rete esterna tra parentesi
( ). Questo suggerisce a PF di eseguire l'update delle regole
se dovesse cambiare l'indirizzo IP assegnato all'interfaccia. Questo è
molto utile quando l'interfaccia esterna ottiene il suo indirizzo IP
via DHCP o dial-up così da evitare di ricaricare le regole di
configurazione ad ogni cambiamento di indirizzo.
- Il nome di un'interfaccia di rete seguita da ognuno di questi
parametri:
- :network - sostituisce un blocco CIDR network (per
esempio 192.168.0.0/24)
- :peer - sostituisce l'indirizzo IP peer su un link
point-to-point
- Inoltre il parametro :0 può essere aggiunto sia a un
nome di interfaccia che ad ognuno dei parametri visti precedentemente
ad indicare a PF che nella sostituzione non dovrebbero essere inclusi
indirizzi IP alias. Questi parametri possono anche essere usati quando
l'interfaccia è tra parentesi.
Per esempio: fxp0:network:0
- Un set di indirizzi usando una lista.
- pool_type
- Specifica il tipo di pool di indirizzi
da usare nella traslazione.
- static-port
- Dice a PF di non traslare la porta sorgente nei pacchetti TCP e UDP.
Questo ci porterebbe alla seguente semplice regola:
nat on tl0 from 192.168.1.0/24 to any -> 24.5.0.5
Questa regola dice di effettuare la NAT sull'interfaccia tl0
per ogni pacchetto che giunge da 192.168.1.0/24 sostituendo l'indirizzo
sorgente con 24.5.0.5.
Anche se la regola precedente è corretta, si tratta di una forma
sconsigliata. Il mantenimento potrebbe essere difficoltoso, ogni cambio
di network esterno o interno richiederebbe la modifica della linea.
Confrontate con la seguente regola facile da aggiornare (tl0
è l'interfaccia esterna mentre dc0 è interna):
nat on tl0 from dc0:network to any -> tl0
Il vantaggio dovrebbe essere chiaro, si possono cambiare gli indirizzi
IP su entrambe le interfaccie di rete senza cambiare la regola.
Quando si specifica il nome di un'interfaccia per la traslazione degli
indirizzi come nell'esempio appena visto, l'indirizzo IP è determinato
nell'istante di caricamento di pf.conf e non in tempo reale.
Quindi l'uso di un DHCP per configurare l'interfaccia esterna può
essere un problema. Se l'indirizzo IP assegnato dovesse cambiare,
la NAT continuerà ad effettuare la traslazione dei pacchetti usando
il vecchio indirizzo IP. Questo bloccherà le connessioni.
Per risolvere questo problema si può dire a PF di aggiornare
automaticamente la traslazione di indirizzo racchiudendo tra parentesi
il nome dell'interfaccia:
nat on tl0 from dc0:network to any -> (tl0)
Questo metodo funziona per traslazioni di indirizzi IPv4 e IPv6.
Mappa bidirezionale (1:1 mapping)
Una mappatura bidirezionale può essere ottenuta usando la regola
binat. La regola binat stabilisce una mappatura uno a
uno tra un indirizzo IP locale e un indirizzo esterno. Per esempio
questo è utile per realizzare un web server sulla rete locale con un
suo corrispondente indirizzo IP. Connessioni da Internet all'indirizzo
esterno saranno traslate all'indirizzo interno e connessioni dal web
server (come richieste DNS) saranno traslate all'indirizzo esterno.
A differenza di come avviene con le regole di nat, con le
regole di binat le porte TCP e UDP non saranno mai modoficate.
Esempio:
web_serv_int = "192.168.1.100"
web_serv_ext = "24.5.0.6"
binat on tl0 from $web_serv_int to any -> $web_serv_ext
Eccezioni alla regola di traslazione
Eccezioni alla regola di traslazione si ottengono con la keyword
no. Per esempio, se si modificasse la riga precedente:
no nat on tl0 from 192.168.1.208 to any
nat on tl0 from 192.168.1.0/24 to any -> 24.2.74.79
L'intera network 192.168.1.0/24 avrebbe i suoi pacchetti traslati
all'indirizzo esterno 24.2.74.79 fatta eccezione dell'indirizzo
192.168.1.208.
C'è da notare che viene rispettata la prima regola che ha una
corrispondenza, se è una regola negata il pacchetto non è traslato.
La keyword no può anche essere usata con le regole
binat e rdr.
Controllo dello stato della NAT
Per vedere le traslazioni NAT attive si usa
pfctl(8) con l'opzione -s state.
Questa opzione elencherà tutte le sessioni NAT attive:
# pfctl -s state
fxp0 TCP 192.168.1.35:2132 -> 24.5.0.5:53136 -> 65.42.33.245:22 TIME_WAIT:TIME_WAIT
fxp0 UDP 192.168.1.35:2491 -> 24.5.0.5:60527 -> 24.2.68.33:53 MULTIPLE:SINGLE
Spiegazione (solo per la prima riga):
- fxp0
- Indica l'interfaccia che è nello stato di bound to. Apparirà la
parola self se lo stato è
floating.
- TCP
- Il protocollo utilizzato nella connessione.
- 192.168.1.35:2132
- L'indirizzo IP (192.168.1.35) della workstation sulla rete
locale. Dopo l'indirizzo viene mostrata la porta sorgente (2132).
Questo è anche l'indirizzo sorgente che è sostituito nell'header IP.
- 24.5.0.5:53136
- L'indirizzo IP (24.5.0.5) e la porta (53136) utilizzati dalla
NAT nella traslazione.
- 65.42.33.245:22
- L'indirizzo IP (65.42.33.245) e la porta (22) dell'host su
Internet con il quale è connessa la workstation.
- TIME_WAIT:TIME_WAIT
- Indica lo stato con il quale PF considera la connessione TCP in
corso.
[Precedente: Packet Filtering]
[Indice]
[Successivo: Reindirizzamento (Port Forwarding)]
www@openbsd.org
$OpenBSD: nat.html,v 1.2 2008/03/20 15:57:35 saad Exp $