[OpenBSD]

[Wstecz: Filtrowanie pakietów] [Spis treści] [Dalej: Przekierowania ruchu]

PF: Translacje adresów (NAT)


Spis treści


Wprowadzenie

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:

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:

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:

net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1

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:
src_port
Port źródłowy w Warstwie 4 nagłówka pakietu. Porty mogą być podawane jako: Opcja port nie jest zwykle wykorzystywana w regułach nat, ponieważ celem jest zwykłe translacja NAT całego ruch bez względu na używane port(y).
dst_addr
Adres docelowy pakietów, który ma ulegać translacji. Adres docelowy jest podawany w ten sam sposób, co adres źródłowy.
dst_port
Port docelowy w Warstwie 4 nagłówka pakietu. Port ten jest podawany w ten sam sposób, co port źródłowy.
ext_addr
Zewnętrzny adres w bramce NAT, na który pakiety będą tłumaczone. Zewnętrzny adres może być podany jako:
pool_type
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.

Przykład:

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

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.

[Wstecz: Filtrowanie pakietów] [Spis treści] [Dalej: Przekierowania ruchu]


[wstecz] www@openbsd.org
$OpenBSD: nat.html,v 1.20 2007/11/12 20:29:59 saad Exp $