[gelöst] iptables: Zugriff auf Host im lokalen LAN

Sani120

Neuer User
Mitglied seit
30 Aug 2010
Beiträge
14
Punkte für Reaktionen
0
Punkte
0
Hallo,
ich habe Freetz mit OpenVPN und iptables / iptables-CGI auf meiner 7270 V3. Die Freetz ist durch Portweiterleitung an 0.0.0.0 des OpenVPN Ports 1194 von außen erreichbar. Durch das Eintragen einer statischen Route vom lokalen LAN ins VPN und durch die Angabe des lokalen Netzes in der OpenVPN config kann ich über Rechner von außen per VPN auf das komplette LAN zugreifen.

So weit so gut.

Jetzt möchte ich diesen Zugriff von außen reduzieren. Ein über VPN konnektierter Client soll auf einen Rechner A im LAN (192.168.68.0) Zugriff bekommen, und zwar nur auf Port 80. Die anderen Rechner einschließlich der Fritzbox selber soll nicht erreichbar sein.

Hierzu möchte ich iptables rules anlegen. Leider kenne ich mich nicht sehr gut aus. Wie kann ich das realisieren? Würde ich das über die INPUT chain "abfackeln" können? Oder muss ich hier NAT einsetzen? Wäre nett wenn mir jemand einen "Schups" in die richtige Richtung geben könnte :) Vielen Dank vorab...
 
Zuletzt bearbeitet:
@RalfFriedl: OK meine Frage war wohl zu allgemein. Jetzt habe ich mich besser eingelesen.

Um zunächst allen Verkehr zu sperren, der über OpenVPN reinkommt, habe ich als Test folgende Rule probiert. 192.68.68.23 ist mein OpenVPN Netz:

Code:
-A FORWARD  -s 192.168.23.0 -d 0.0.0.0 -p all  -j DROP

Die Policy für FORWARD ist unverändert auf ACCEPT.

Ich hätte erwartet, dass ich nun das interne LAN nicht mehr erreiche, wenn ich mich von außen über VPN verbunden habe. Dem ist nicht so. Ich kann von außen über VPN immer noch alle Rechner innen mit allen Ports erreichen.

Dann habe ich versucht, zusätzlich alles zu sperren, was über tun0 kommt:

Code:
 iptables -A FORWARD  -s 0.0.0.0 -d 0.0.0.0 -p all   -i tun0  -j DROP

Auch hier weiterhin alles erreichbar. Warum greifen meine Rules nicht? Hat das vielleicht etwas mit der AVM-Firewall zu tun? Dort habe ich ausschließlich den öffentlichen OpenVPN Port 1194 auf 0.0.0.0 geforwarded.

Danke für eure Hilfe.
 
Vielleicht die Netzmaske??
Und nimm doch lieber gleich die "INPUT" chain
Code:
-A INPUT -p tcp -i tun0 -s 192.168.23.0/24 -d 192.168.68.123/32 --dport 80 -j ACCEPT
-A INPUT -i tun0 -d 0.0.0.0/0 -j DROP
 
Trotzdem Google iptables.

Deine Angabe "-d 0.0.0.0" und "-s 0.0.0.0" bedeutet eine Ziel- bzw. Quell-Adresse von 0.0.0.0. An bzw. von dieser Adresse wird aber nie etwas gesendet. Laß diese Angaben einfach weg, dann paßt es vermutlich.

@MaxMuster
Wenn ich das oben richtig verstehe, ist FORWARD richtig.
 
Danke für eure Antworten.

Das hat geholfen. Jetzt wird der Verkehr komplett blockiert durch

Code:
iptables -A FORWARD  -p all   -i tun0  -j DROP
Zunächst hat es nicht geklappt, weil wenn ich die Source/Destination Felder in der Konfigmaske leer lasse folgende Rule geneiert wird:

iptables -A FORWARD -s -d -p all -i tun0 -j DROP

Diese erzeugt einen Fehler, da das "-s -d" noch dringeblieben ist.
 
Da muss man dann "anywhere" eintragen? Steht das irgendwo in der Doku? Sonst sollten wir es vielleicht hinzufügen.

MfG Oliver
 
Ich bin dafür, daß nicht zu dokumentieren, sonder statt dessen bei leeren Felder die Optionen wegzulassen.

Ansonsten sollte es mit "anywhere" oder "0.0.0.0/0" funktionieren. "0.0.0.0" ohne "/0" dagegen bezeichnet eine einzelne Adresse, die in der Praxis niemals angesprochen wird.
 
Der Code im Skript sieht so aus:
Code:
# Source Address
if [ $IPTABLES_SOURCE = "anywhere" ]; then
	IPTABLES_SOURCE=''
else
	IPTABLES_SOURCE='-s '$IPTABLES_SOURCE
fi
Wenn klar ist, dass da anywhere rein muss, dann brauchen wir es nicht dokumentieren. Sollten wir den Test auf "leer" erweitern?

MfG Oliver
 
Anscheinend ist "anywhere" zwar die Ausgabe, wenn keine Adresse angegeben wird, aber es ist kein gültiger Wert, um dies anzugeben.
Die Anführungszeichen sind übrigens wichtiger bei "$IPTABLES_SOURCE" als bei "anywhere"
Code:
# Source Address
if [ "$IPTABLES_SOURCE" = "anywhere" -o -z "$IPTABLES_SOURCE"]; then
	IPTABLES_SOURCE=''
else
	IPTABLES_SOURCE='-s '$IPTABLES_SOURCE
fi
Falls nicht anderweitig sichergestellt wird, daß IPTABLES_SOURCE nur sinnvolle Werte enthält, ist das übrigens ein Sicherheitsrisiko, mit dem sich beliebige Kommandos auf der Box ausführen lassen (wenn man annimmt, daß man die Regeln bearbeiten kann, auch wenn anderweitige Kommandos deaktiviert sind, ansonsten macht es keinen Unterschied, ob man die Kommandos direkt eingibt oder sie hier unterjubelt).
 
Falls nicht anderweitig sichergestellt wird, daß IPTABLES_SOURCE nur sinnvolle Werte enthält, ist das übrigens ein Sicherheitsrisiko, mit dem sich beliebige Kommandos auf der Box ausführen lassen
Kennst du ein einfaches Mittel das zu unterbinden?

MfG Oliver
 
Ich würde das nehmen:
Code:
IPTABLES_SOURCE=$( echo -n "$IPTABLES_SOURCE" | tr -dc '0-9./a-zA-Z_-' )
Damit wird sichergestellt, daß nur ungefährliche Zeichen übrig bleiben.
'0-9./' reicht für numerische IP-Adressen mit Maske, die sowieso empfohlen werden. 'a-zA-Z_-' ist zusätzlich für die Konstante "anywhere" und für Hostnamen, falls man sie doch nutzen will. Das Minus-Zeichen muß als letztes Zeichen bleiben. Wenn also weitere Zeichen notwendig sein sollten, muß man sie vor dem Minus einfügen.

PS:
Das funktioniert mit bash, aber nicht mit der aktuellen Shell auf der Box (das Quete für den Schrägstrich funktioniert nicht):
Code:
IPTABLES_SOURCE=${IPTABLES_SOURCE//[^0-9.\/a-zA-Z_-]/}
 
Zuletzt bearbeitet:
Da es mehrere Variablen in der Art gibt würde ich das gerne in einer Funktion/Schleife erledigen. Leider klappt es nicht so richtig...
Code:
check_entries() {
    for entry in IPTABLES_SOURCE IPTABLES_SPORT IPTABLES_DESTINATION IPTABLES_DPORT IPTABLES_INPUT_INTERFACE IPTABLES_OUTPUT_INTERFACE; do
        local $entry=$(check_entry $entry)
    done
}

check_entry() {
    local save_entry
    save_entry=$( echo -n "$1" | tr -dc '0-9./a-zA-Z_-' )
    echo $save_entry
}

IPTABLES_SOURCE=fritz.box
IPTABLES_SPORT="exec /bin/sh"
IPTABLES_DESTINATION=1.2.3.4
IPTABLES_DPORT="test; /bin/bash"
IPTABLES_INPUT_INTERFACE=test
IPTABLES_OUTPUT_INTERFACE=test.entry

check_entries

for entry in IPTABLES_SOURCE IPTABLES_SPORT IPTABLES_DESTINATION IPTABLES_DPORT IPTABLES_INPUT_INTERFACE IPTABLES_OUTPUT_INTERFACE; do
    echo "$(eval echo \$${entry})"
done
MfG Oliver
 
Hier zwei Varianten.
Man kann entweder den Wert prüfen und einen Fehler melden, oder alle ungültigen Zeichen entfernen und stillschweigend mit dem Rest weiter machen.
Code:
check_entry()
{
    eval local org=\$$1
    eval $1=\$\( echo -n "\$$1" \| tr -dc \'0-9./a-zA-Z_-\' \)
    if eval test \"\$$1\" != \"\$org\"; then
        eval echo "\"invalid characters in \\\$$1: \$org\""
    fi
}

fix_entry()
{
    eval $1=\$\( echo -n "\$$1" \| tr -dc \'0-9./a-zA-Z_-\' \)
}

VAR='a;b|c"d'\''e&f$g h'

echo $VAR
for i in VAR; do
    check_entry $i
    fix_entry $i
done
echo $VAR
 
@Ralf
Kannst du dir bitte mal den angehängten Patch anschauen. Sollte so funktionieren oder? Ich weiß nicht so recht wie ich den ausprobieren soll.

MfG Oliver
 

Anhänge

  • rc.iptables.patch.txt
    3 KB · Aufrufe: 5
Sieht schon mal gut aus. Nur statt
Code:
LIST="$IPTABLES_RULE $IPTABLES_CHAIN $IPTABLES_POSITION $IPTABLES_SOURCE ...
muß es heißen
Code:
LIST="IPTABLES_RULE IPTABLES_CHAIN IPTABLES_POSITION IPTABLES_SOURCE ...
Durch das Doller-Zeichen würden die Variablen durch ihre Werte ersetzt werden, und das brauchen wir hier nicht. Die Shell ist insoweit anders als z.B. PHP oder Perl.

PS:
Wenn ich den Patch richtig lese, werden die Variablen erst nach der Verarbeitung geprüft. Das Ersetzungs-Muster entfernt auch alle Leerzeichen aus den Variablen. Das könnte bei einigen Optionen funktionieren, aber nicht bei den langen.

Ich würde die Variablen, die vom Benutzer kommen, als allererstes auf ungültige Zeichen prüfen.

PPS:
Anscheinend ist es doch nicht so einfach, die Shell mit Sonderzeichen in Variablen durcheinander zu bringen, zumindest nicht auf dem Weg, den ich befürchtet hatte. Von daher braucht man den Teil mit fix_entry vermutlich doch nicht.
 
Zuletzt bearbeitet:
Ja, nimm den Check-Teil wieder heraus.
Tut mir leid mit dem vermutlich falschen Alarm wegen dem Sicherheitsrisiko.

Die langen Optionen (z.B. "--dport") funktionieren nicht ohne nachfolgendes Leerzeichen. Die kurzen Optionen (z.B. "-s") funktionieren auch ohne Leerzeichen.
 

Zurzeit aktive Besucher

Statistik des Forums

Themen
246,300
Beiträge
2,249,713
Mitglieder
373,904
Neuestes Mitglied
Elemir
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.