Jetzt wissen wir also, wie wir die Pakete, die wir veraendern wollen, auswaehlen koennen. Um unsere Regel zu vervollstaendigen, muessen wir dem Kernel sagen, was genau er mit dem Paket tun soll.
Du moechtest Source NAT machen; veraendere die Quelladresse von Paketen zu etwas anderem. Dies wird in der POSTROUTING-Kette gemacht, kurz bevor das Paket schliesslich geschickt wird; dies ist ein wichtiges Detail, da es bedeutet, dass alles andere auf dem Linuxrechner selbst (Routing, Paketfilter) das unveraenderte Paket sehen wird. Es bedeutet auch, dass die '-o' (ausgehende Schnittstelle) Option verwendet werden kann.
Source NAT wird durch '-j SNAT' bestimmt und die '--to-source' Option bestimmt eine IP-Adresse, eine Reihe von IP-Adressen, und einen optionalen Port oder eine Reihe von Ports (nur fuer UDP und TCP Protokolle).
## Quelladresse auf 1.2.3.4 aendern
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4
## Quelladresse auf 1.2.3.4, 1.2.3.5, oder 1.2.3.5 aendern
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6
## Quelladresse zu 1.2.3.4, Ports 1 - 1023, aendern
# iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to \
# 1.2.3.4:1-1023
Es gibt einen Spezialfall von Source NAT, der Masquerading genannt wird: es sollte nur fuer dynamisch zugeordnete IP-Adressen verwendet werden wie bei normalen Waehlverbindungen (Benutze bei statischen IP-Adressen SNAT weiter oben).
Beim Masquerading musst Du die Quelladresse nicht explizit angeben: es wird die Quelladresse der Schnittstelle nehmen, an der das Paket ausgeht. Wichtiger ist, dass, wenn der Link unterbrochen wird, die Verbindungen (die jetzt sowieso verloren sind) vergessen werden, was weniger Stoerungen bedeutet, wenn die Verbindung mit einer neuen IP-Adresse wieder aufgebaut wird.
## Maskiere alles, was an ppp0 ausgeht
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
Dies wird in der PREROUTING-Kette erledigt, wenn das Paket gerade eingegangen ist; das bedeutet, dass alles andere auf dem Linuxrechner selbst (Routing, Paketfilter) das Paket zum 'wirklichen' Ziel gehen sehen wird. Es bedeutet auch, dass die '-i' Option (eingehende Schnittstelle) verwendet werden kann.
Um das Ziel von lokal generierten Paketen zu aendern, kann auch die OUTPUT-Kette benutzt werden, das ist aber eher ungewoehnlich.
Destination NAT wird durch '-j DNAT' bestimmt und die '--to-destination' Option bestimmt eine IP-Adresse, eine Reihe von IP-Adressen, und einen optionalen Port oder eine Reihe von Ports (nur fuer UDP und TCP Protokolle).
## Zieladresse zu 5.6.7.8 aendern
# iptables -t nat -A PREROUTING -i eth1 -j DNAT --to 5.6.7.8
## Zieladresse zu 5.6.7.8, 5.6.7.9 oder 5.6.7.10 aendern
# iptables -t nat -A PREROUTING -i eth1 -j DNAT --to 5.6.7.8-5.6.7.10
## Aendern der Zieladresse von Webtraffic auf 5.6.7.8 Port 8080
# iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth1 \
-j DNAT --to 5.6.7.8:8080
## Lokale Pakete fuer 1.2.3.4 an das Loopback umleiten
# iptables -t nat -A OUTPUT -d 1.2.3.4 -j DNAT --to 127.0.0.1
Es gibt einen speziellen Fall von Destination NAT, der Redirection genannt wird: Es ist eine einfache Bequemlichkeit, die genau das gleiche tut wie NAT auf der eingehenden Schnittstelle.
## Eingehenden Webtraffic an Port 80 an unseren (transparenten) Squid-
# Proxy weiterleiten
# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 \
-j REDIRECT --to-port 3128
Es ist gibt ein paar subtile Einzelheiten bei NAT, um die sich die meisten Leute nie werden kuemmern muessen. Fuer die Neugierigen sind sie hier dokumentiert.
Wenn eine Reihe von IP-Adressen gegeben ist, wir diejenige ausgewaehlt, die im Moment am wenigsten fuer IP-Verbindungen, von denen die Maschine weiss, benutzt wird. Dies macht primitives 'load-balancing' moeglich.
Du kannst das '-j ACCEPT' Ziel verwenden, um eine Verbindung zuzulassen, ohne dass irgendein NAT stattfindet.
Gewoehnlich veraendert man eine Verbindung so wenig wie moeglich, entsprechend den Vorgaben einer durch den Benutzer gegebenen Regel. Das bedeutet, dass wir Ports nicht 're-mappen' werden, solange wir es nicht unbedingt tun muessen.
Sogar, wenn fuer eine Verbindung kein NAT benoetigt wird, kann Quellport- veraenderung stillschweigend auftreten, wenn eine andere Verbindung ueber die neue gemappt wurde. Stell Dir den Fall von Masquerading vor, der recht gewoehnlich ist:
Wenn dieses implizite Quell-Mapping auftaucht, werden Ports in drei Klassen aufgeteilt:
Ports werden niemals implizit in eine andere Klasse gemappt.
Wenn es keine Moeglichkeit gibt, eine Verbindung einheitlich zu mappen wie es der Benutzer verlangt, so wird sie verworfen werden. Dies trifft auch auf Pakete zu, die nicht als Teil einer Verbindung klassifiziert werden konnten, weil sie beschaedigt sind, oder der Rechner nicht genug Speicher hat, etc.
Du kannst NAT-Regeln haben, die Pakete in denselben Bereich mappen; der NAT-Code ist clever genung, um Zusammenstoesse zu vermeiden. Es ist also okay, zwei Regeln zu haben, die die Quelladressen 192.168.1.1 und 192.168.1.2 jeweils auf 1.2.3.4 mappen.
Ausserdem kannst Du ueber wirklich verwendete IP-Adressen mappen, solange diese Adressen auch durch den Mapping-Rechner muessen. Wenn Du also ein zugewiesenes Netzwerk (1.2.3.0/24) hast, aber auch ein internes Netzwerk, das dieselben Adressen benutzt, und eins, das private Internet Adressen (192.168.1.0/24) verwendet, kannst Du die 192.168.1.0/24-er Adressen auf das 1.2.3.0/24-er Netzwerk mappen, ohne Dir Sorgen um Zusammenstoesse machen zu muessen:
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 \
-j SNAT --to 1.2.3.0/24
Dieselbe Logik kann auf Adressen angewandt werden, die der NAT-Rechner selbst benutzt: So funktioniert Masquerading (indem die Adressen der Schnittstellen von maskierten Paketen mit den 'wirklichen' Paketen, die durch den Rechner gehen, geteilt werden).
Ausserdem kannst die dieselben Pakete auf viele verschiedene Ziele mappen, und sie werden aufgeteilt werden. Du koenntest zum Beispiel, wenn Du nichts ueber 1.2.3.5 mappen willst, folgendes tun:
# 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
Wenn das Ziel eines lokal-generierten Pakets geaendert wird (ich meine durch die OUTPUT-Kette) und das bewirkt, dass das Paket durch eine andere Schnittstelle muss, wird die Quelladresse auch zu der Adresse der Schnittstelle geaendert. Wenn Du zum Beispiel das Ziel eines Loopback-Pakets auf eth0 aenderst, wird die Quelle auch von 127.0.0.1 zur Adresse von eth0 geaendert werden; im Gegensatz zu anderen Source-Mappings geschieht das im selben Augenblick. Natuerlich wird beides wieder umgekehrt, wenn Antwortpakete eintreffen.