Translacja adresów (ang. Network Address Translation - NAT) daje możliwość
zmapowania całej sieci (lub wielu sieci) do pojedynczego adresu IP. NAT
jest niezbędny, gdy liczba adresów IP przydzielonych przez
Dostawcę Usług Internetowych (ISP) jest mniejsza niż całkowita liczba
maszyn, który mają mieć dostęp do Internetu. NAT jest opisany w
RFC 1631
"The IP Network Address Translator (NAT)".
NAT pozwala korzystać z dobrodziejstw zarezerwowanych bloków adresów
zdefiniowanych w
RFC 1918
"Address Allocation for Private Internets".
Zwykle, wewnętrzna sieć będzie skonfigurowana przy użyciu jednego lub
więcej z tych bloków, a są to:
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)
Maszyna z OpenBSD realizująca NAT będzie miała co najmniej dwa adaptery
sieciowe, jeden do Internetu, drugi do sieci wewnętrznej. NAT będzie
tłumaczył wywołania z sieci wewnętrznej tak, aby wydawało się, że pochodzą
one z maszyny OpenBSD realizującej NAT.
Jak działa NAT
Gdy klient w sieci wewnętrznej łączy się z maszyną w Internecie,
wysyła pakiety IP zaadresowane do tej maszyny. Pakiety te zawierają
wszystkie informacje adresowe, niezbędne aby dotrzeć do celu.
NAT zajmuje się następującymi danymi:
Źródłowy adres IP (na przykład, 192.168.1.35)
Źródłowy port TCP lub UDP (na przykład, 2132)
Gdy pakiety przechodzą przez bramkę NAT, są modyfikowane tak aby wydawały się
pochodzić z samej bramki (ang. gateway) NAT. Bramka NAT zapamiętuje zmiany,
wykonywane na pakietach, w swojej tabeli stanów, aby móc: a) odwrócić
zmiany w powracających pakietach oraz b) zapewnić, że powracające pakiety
są przepuszczane przez firewall i nie są blokowane. Na przykład, mogą
wystąpić następujące zmiany:
Źródłowe IP: zamienione na zewnętrzny adres bramki
(na przykład, 24.5.0.5)
Źródłowy port: zamieniony na losowo wybrany, nieużywany port na
bramce (na przykład, 53136)
Ani wewnętrzna maszyna, ani host w Internecie nie obawiają się tych translacji.
Dla komputera z sieci lokalnej, system realizujący NAT jest po prostu bramką.
Dla hosta w Internecie, pakiety wydają się pochodzić wprost z systemu, na którym
realizowany jest NAT; nawet nie zdaje sobie sprawy, że wewnętrzne stacje
robocze w ogóle istnieją.
Kiedy host w Internecie odpowiada na pakiety wewnętrznej maszyny, są one
adresowane do zewnętrznego IP bramki realizującej NAT (24.5.0.5) i na
przetłumaczony port (53136). Bramka NAT przeszuka wówczas tabelę stanów,
aby sprawdzić, czy powracające pakiety pasują do jakiegoś już nawiązanego
połączenia. Niepowtarzalne dopasowanie zostaje dokonane na podstawie
kombinacji IP/port, która mówi PF, że datagramy należą do połączenia
zainicjowanego przez wewnętrzną maszynę 192.168.1.35. PF wykona wówczas
odwrócone zmiany w stosunku do wychodzących pakietów i przekaże je
do maszyny w sieci wewnętrznej.
Translacje pakietów ICMP odbywają się w podobny sposób, ale bez modyfikacji
portu źródłowego.
NAT a filtrowanie pakietów
Uwaga: Pakiety podlegające translacji
są także przetwarzane przez reguły filtrujące i zostaną przez nie
zablokowane lub przepuszczone zgodnie z tym jak zadeklarowano.
Jedynym odstępstwem od tej reguły jest użycie słowa kluczowego
pass w samej regule nat.
Spowoduje to przepuszczanie przez filtr pakietów podlegających NAT.
Należy być świadomym, iż ponieważ translacje mają miejsce przed
filtrowaniem, reguły filtrujące widzą pakiety po translacji,
już z podmienionym adresem IP oraz portem, zgodnie z tym
Jak działa NAT.
Przekazywanie pakietów IP (IP Forwarding)
Ponieważ NAT jest prawie zawsze stosowany w routerach i bramkach sieciowych,
najprawdopodobniej konieczne będzie aktywowanie przekazywania pakietów IP
(ang. IP forwarding), aby umożliwić ich przekazywanie pomiędzy interfejsami
sieciowymi na maszynie OpenBSD.
Przekazywanie pakietów IP jest aktywowane przy pomocy mechanizmu
sysctl(3):
# sysctl net.inet.ip.forwarding=1
# sysctl net.inet6.ip6.forwarding=1 (jeśli używany jest IPv6)
Aby zmienne ty były ustawiane podczas każdego startu systemu, następujące
linie powinny zostać dodane do
/etc/sysctl.conf:
Linie te są tam już obecne w domyślnej instalacji, ale są tylko komentarzem
(poprzedzone znakiem #). Wystarczy usunąć znak # i zapisać
plik. Przekazywanie pakietów IP będzie włączone po kolejnym starcie systemu.
Konfiguracja NAT
Ogólna składnia reguł NAT w pf.conf wygląda tak:
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
słowo kluczowe rozpoczynające regułę NAT.
pass
Powoduje, że pakiety podlegające translacji są zawsze przepuszczane
przez reguły filtrujące.
log
Pozwoli logować pakiety poprzez
pflogd(8).
Normalnie logowany jest tylko pierwszy pasujący pakiet.
Aby logować wszystkie pakiety, użyj log (all).
interface
Nazwa interfejsu sieciowego lub grupy interfejsów na którym ma mieć
miejsce translacja pakietów.
af
Rodzina adresów: inet dla IPv4 lub inet6
dla IPv6. PF jest zwykle w stanie zidentyfikować ten parametr na podstawie
adresu(ów) źródłowych/przeznaczenia.
src_addr
Źródłowy (wewnętrzny) adres pakietów, które będą podlegały translacji NAT.
Adres źródłowy może być podany jako:
W pełni określona domena, która będzie rozwinięta przez DNS w czasie
ładowania zestawu reguł. Wszystkie zwrócone adresy IP będą wstawione do reguły.
Nazwa interfejsu sieciowego. Wszystkie adresy IP przypisane do urządzenia
będą wprowadzone podczas ładowania zestawu reguł.
Nazwa interfejsu sieciowego lub grupy interfejsów wraz z
/netmaską (np /24). Każdy adres IP danego interfejsu
jest łączony z każdą maską sieciową aby utworzyć odpowiedni blok sieci CIDR,
który będzie wprowadzony podczas ładowania zestawu reguł.
Nazwa interfejsu sieciowego lub grupy interfejsów z dopisanym na końcu jednym z poniższych
wyrażeń:
:network - odpowiada blokowi sieci CIDR (np
192.168.0.0/24)
:broadcast - odpowiada adresowi rozgłoszeniowemu podsieci
(np 192.168.0.255)
:peer - odpowiada adresowi IP węzła na drugim końcu połączenia
point-to-point
Dodatkowo, wyrażenie :0 może zostać dodane na końcu
zarówno nazwy interfejsu/grupy jak i któregokolwiek z wymienionych słów
kluczowych aby nie były brane pod uwagę dodatkowe, wskazujące adresy IP
(ang. aliased IP addresses) podczas przetwarzania reguł.
Oznaczenia te mogą także być użyte wewnątrz wyrażeń w nawiasach.
Przykład: fxp0:network:0
W pełni określona domena, która będzie rozwijana przez DNS w czasie
ładowania zestawu reguł.
Nazwa zewnętrznego interfejsu sieciowego. Wszystkie adresy IP przypisane do
urządzenia będą wprowadzone podczas ładowania zestawu reguł.
Nazwa zewnętrznego interfejsu sieciowego w nawiasach okrągłych
( ). Mówi to PF, aby odświeżać regułę, jeśli adres(y) IP tego
urządzenia sieciowego ulegną zmianie. Jest to bardzo przydatne gdy zewnętrzne
urządzenie otrzymuje swój adres IP przez DHCP lub dial-up, gdyż zestaw reguł
nie musi być przeładowywany za każdym razem, gdy zmienia się IP.
Nazwa interfejsu sieciowego z dopisanym na końcu jednym z poniższych
wyrażeń:
:network - odpowiada blokowi sieci CIDR (np
192.168.0.0/24)
:peer - odpowiada adresowi IP węzła na drugim końcu połączenia
point-to-point
Dodatkowo, wyrażenie :0 może zostać dodane na końcu
zarówno nazwy interfejsu jak i któregokolwiek z wymienionych słów
kluczowych aby nie były brane pod uwagę dodatkowe, wskazujące adresy IP
(ang. aliased IP addresses) podczas przetwarzania reguł.
Oznaczenia te mogą także być użyte wewnątrz wyrażeń w nawiasach.
Przykład: fxp0:network:0
Określa jaki typ puli adresów ma być
zastosowany dla translacji.
static-port
Mówi PF, aby port źródłowy w pakietach TCP i UDP nie ulegał translacji.
Prowadzi to do najprostszej formy tej linii, podobnej do tej:
nat on tl0 from 192.168.1.0/24 to any -> 24.5.0.5
Reguła ta mówi, aby wykonywać translacje NAT na urządzeniu tl0 dla
wszystkich pakietów z bloku 192.168.1.0/24, oraz aby zastępować źródłowy
adres IP przez 24.5.0.5.
Mimo, że powyższa reguła jest poprawna, nie jest ona polecaną formą.
Jej konserwacja mogłaby być trudna, gdyż jakiekolwiek zmiany w numerach
zewnętrznych lub wewnętrznych adresów będą wymagać modyfikacji tej linii.
Porównaj ją z tą, łatwą w zarządzaniu, regułką (tl0 zewnętrzny
interfejs, dc0 wewnętrzne interfejs):
nat on tl0 from dc0:network to any -> tl0
Zalety powinny być wyraźnie widoczne: można zmieniać adresy IP któregokolwiek
z interfejsów bez zmiany tej reguły.
Gdy podana zostaje nazwa interfejsu dla translacji adresów, jak w
przykładzie powyżej, adres IP jest określony w pf.conf podczas
ładowania, nie od ręki. Jeśli używane jest DHCP, do konfiguracji
zewnętrznego interfejsu, można napotkać następujący problem: jeśli przypisany
adres IP ulega zmianie, NAT nadal będzie tłumaczyć wychodzące pakiety
używając starego adresu IP. Spowoduje to, że wychodzące połączenia przestaną
funkcjonować. Aby to obejść, można nakazać PF automatycznie aktualizować adres
translacji poprzez wstawienie nazwy danego interfejsu w nawiasy okrągłe:
nat on tl0 from dc0:network to any -> (tl0)
Ta metoda translacji działa zarówno dla adresów IPv4 jak i IPv6.
Dwukierunkowe mapowanie adresów (mapowanie 1:1)
Dwukierunkowe mapowanie może być realizowane przy pomocy reguły
binat. Reguła binat realizuje mapowanie jeden do jednego
pomiędzy zewnętrznym i wewnętrznym adresem IP. Może to być użyteczne, aby
serwer web z sieci wewnętrznej był widoczny w Internecie jako serwer web
z własnym zewnętrznym adresem IP. Połączenia z Internetu na ten adres
zewnętrzny będą tłumaczone na adres wewnętrzny , a połączenia z serwera web
(jak na przykład zapytania DNS) będą tłumaczone na adres zewnętrzny. Porty
TCP i UDP nie są nigdy modyfikowane przez reguły binat, co odróżnia
tą regułę od nat.
binat on tl0 from $web_serv_int to any -> $web_serv_ext
Wyjątki w regułach translacji
Wyjątki w regułach translacji mogą być definiowane przy pomocy słowa kluczowego
no. Jeśli wcześniejszy przykład NAT byłby zmodyfikowany
w następujący sposób:
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
Wówczas translacja NAT byłaby realizowana dla całego bloku sieci
192.168.1.0/24, z wyjątkiem hosta 192.168.1.208.
Zwróć uwagę, że w przypadku translacji brana jest pierwsza pasująca reguła -
jeśli jest to regułka no, wtedy pakiet nie będzie poddany translacji.
Słowo kluczowe no może także być używane wraz z regułami
binat i rdr.
Sprawdzanie stanu NAT
Aby wyświetlić listę aktywnych translacji NAT, używa się programu
pfctl(8) z opcją -s state. Opcja ta wyświetli wszystkie obecne sesje NAT:
# 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
Wyjaśnienie (jedynie pierwsza linia):
fxp0
To interfejs z którym związany jest wpis w tabeli stanów.
Słowo kluczowe
self pojawi się gdy stan jest ruchomy (ang.
floating).
TCP
Protokół wykorzystywany przez połączenie.
192.168.1.35:2132
Adres IP (192.168.1.35) maszyny w sieci wewnętrznej. Port źródłowy
(2132) jest wyświetlany po adresie. Jest to adres, który jest zamieniany
w nagłówku IP.
24.5.0.5:53136
Adres IP (24.5.0.5) i port (53136) na bramce, na który pakiety są
tłumaczone.
65.42.33.245:22
Adres IP (65.42.33.245) i port (22), na który łączy się maszyna z
sieci wewnętrznej.
TIME_WAIT:TIME_WAIT
Stan w jakim, według PF, znajduje się połączenie TCP.