Dieser Artikel ist größtenteils für alle Ubuntu-Versionen gültig.
Dieser Artikel erfordert mehr Erfahrung im Umgang mit Linux und ist daher nur für fortgeschrittene Benutzer gedacht.
Dieses Perl-Skript dient dazu, mit einem einzigen Kommandozeilenbefehl einen Ubuntu-Router mit der nötigen Network Address Translation (NAT) Funktionalität auszustatten, ohne dass man sich mit der iptables-Syntax beschäftigen muss.
Einfach das Skript irgendwo hin kopieren, wo es passt, bspw. nach /usr/local/sbin/nathelper. Dann die geeigneten Kommandozeilenargumente (s.u.) zusammenstellen und wenn alles wie gewünscht funktioniert den Befehl in einem Startskript (bspw. in /etc/rc.local) konservieren.
Das Skript wird komplett über seine Argumente gesteuert[1]:
nathelper -i IFACE OPTIONEN IP PORT(S)
Beispiele:
nathelper -i ppp+ -m # nur Masquerading nathelper -i ppp+ -m 192.168.6.5 80 21 192.168.6.6 6881-6889:7001-7009 # Masquerading und verschiedene Port-Weiterleitungen
In diesem Beispiel wird auf dem externen ppp-Device (ppp+
ist ein Joker-Ausdruck, der auf alle ppp-Devices zutrifft) Masquerading eingerichtet, sowie ein paar Ports nach innen weitergeleitet. Die Ports 80 und 21 werden an den Rechner 192.168.6.5 weitergeleitet und die Ports 6881 bis 6889 werden an die Ports 7001 bis 7009 des Rechners 192.168.6.6 weitergeleitet.
-i iface
: Gibt die externe Netzwerkschnittstelle an. Für (DSL-)Modems sollte man einfach ppp+
verwenden, ansonsten bspw. eth0
. Diese Option muss unbedingt angegeben werden.
-m
: Diese Option gibt an, dass Masquerading verwendet werden soll. Dies ist in den allermeisten Fällen der Fall.
-v
: Gibt jeden sysctl- und iptables-Befehl auf der Konsole aus, bevor er ausgeführt wird. So kann man nebenbei die iptables-Syntax lernen oder die Funktionsweise des Skriptes kontrollieren.
-d
: Wie -v
, allerdings werden die Befehle nur ausgegeben, aber nicht tatsächlich ausgeführt.
-q
: Am Ende des Skripts wird normalerweise eine Erfolgsmeldung ausgegeben. Mit Angabe der Option -q
unterbleibt dies.
ip
: Wird ohne benannte Option auf der Kommandozeile angegeben. Bezeichnet die IP-Adresse eines Rechners, an den Port(s) weitergeleitet werden. Alle nachfolgenden port-Argumente bis zur nächsten IP beziehen sich auf diese Adresse.
ports
: Ein Weiterleitungsstatement, dass sich immer auf die letzte vorhergehende IP-Adressenbezeichnung bezieht. Folgende Möglichkeiten gibt es:
1234
-> Der Port 1234 wird 1:1 an denselben Port des Zielrechners weitergeleitet.
1234-1238
-> Ein ganzer Abschnitt von Ports wird weitergeleitet.
1234,1370
-> Mehrere verschiedene Ports werden weitergeleitet.
1234:5678
-> Ein Port wird auf einen anderen Port des Zielrechners weitergeleitet.
u1234
-> Dieses Port-Statement bezieht sich auf das UDP-Protokoll an Stelle des meist verwendeten TCP-Protokolls.
Die verschiedenen Operatoren können auch alle miteinander kombiniert werden, wobei aber auf eine gleiche Anzahl Ports rechts und links vom :
geachtet werden muss. Beispiel:
nathelper -i ppp+ -m 192.168.1.1 21-25,80,3128:10001-10007
Für jeden einzelnen Port wird eine iptables-Regel angelegt, was sich bei einer sehr hohen Anzahl an Regeln durchaus auf die Performance auswirken kann. Es ist deswegen nicht empfehlenswert, aus Bequemlichkeit bspw. mit 1-65535
alle Ports umzuleiten.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | #!/usr/bin/perl -w # # nathelper - Masquerading und Port-Forwarding in einer Kommandozeile # benoetigt natuerlich iptables # # Autor: otzenpunk (UbuntuUsers.de) # Lizenz: Public Domain use strict; use Getopt::Std; our %opts; usage() unless @ARGV; getopts('qvdhmi:', \%opts); usage() if $opts{'h'} or !$opts{'i'}; init(); # ip_forward, iptables -F masq($opts{'i'}) if ($opts{'m'}); # evtl. Masquerading our @forwards; our $fw_indx = 0; while ($_ = shift @ARGV) { # Array of Arrays: je 1xIP und n x Ports ++$fw_indx if /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/ && @forwards; push @{$forwards[$fw_indx]}, $_; } forw($_) for @forwards; # jede IP verarbeiten print "NAT erfolgreich aktiviert.\n" unless $opts{'q'} or $opts{'d'}; exit(0); # masq(iface): Masquerading sub masq { my @iptables = (qw(/sbin/iptables -t nat -A POSTROUTING -o), $opts{'i'}, qw(-j MASQUERADE)); iptables(@iptables); } # forw(IP, Ports, ...): Ports duerfen Aufzaehlungen (zahl,zahl) # Ranges (zahl-zahl) # und Uebersetzungen (zahl:zahl) enthalten. sub forw { my $argptr = shift; # Pointer auf Array my $ip = shift @$argptr; # Erstes Element = IP for (@$argptr) { s/[^0-9u:,-]//ig; # saeubern von verbotenen Zeichen my $proto = s/^u//i ? 'udp' : 'tcp'; # u = UDP my ($von, $nach) = split ':'; # Uebersetzung trennen $nach ||= $von; # wenn kein ':' -> Ports bleiben gleich my @von = expand_range($von); # ',' und '-' expandieren my @nach = expand_range($nach); unless (@von == @nach) { # Falsche Parameter abfangen: print "Ungleiche Anzahl Ports: ", join(', ', @von), ' -> ', join(', ', @nach), "\n\n"; usage(); } my $i = 0; for (@von) { # je eine iptables-Zeile pro Port my @iptables = (qw(/sbin/iptables -t nat -A PREROUTING -i), $opts{'i'}, '-p', $proto, '--dport', $_, qw(-j DNAT --to-destination), "$ip:$nach[$i++]"); iptables(@iptables); } } } # iptables(Liste der Argumente, inkl. iptables-Pfad) sub iptables { # system() gibt >0 bei Fehler print join(' ', @_), "\n" if $opts{'v'} or $opts{'d'}; system(@_) && die("Fehler bei iptables. Root?\n") unless ($opts{'d'}); } # expand_range(Port-String inkl. [,-]) # ',' und '-' expandieren und Liste zurueck sub expand_range { my @werte = split ',', shift; @werte = map { my ($down, $up) = split '-', $_; $down < ($up ||= 0) ? ($down..$up) : $down; } @werte; return @werte; } sub init { print "sysctl -w net/ipv4/ip_forward=1\n" if $opts{'v'} or $opts{'d'}; system(qw(sysctl -w net/ipv4/ip_forward=1)) if not $opts{'d'}; iptables(qw(/sbin/iptables -t nat -F)); } sub usage { print <<EOT; Usage: $0 [-v] [-d] -i iface [-m] [ip ports ...] ... $0 [-h] -h : Hilfe -v : Verbose, iptables-Befehle ausgeben und durchfuehren -d : Debug, nicht wirklich durchfuehren -q : Keine Erfolgsmeldung ausgeben -i : externes Interface -m : Masquerading aktivieren ip ports : Ports, die auf IP umgeleitet werden, mehrere moeglich ports : 1234 -> Port wird 1:1 umgeleitet 1234:5678 -> Port wird auf anderen Port umgeleitet 1234-1238 -> Port-Range wird umgeleitet 1234-1238:5674-5678 -> beides u1234 -> UDP-Port(s) verwenden EOT exit(1); } |
Diese Revision wurde am 14. Januar 2012 16:30 von frustschieber erstellt.