iptables Verständnisproblem

Post Reply
Message
Author
Fulter

iptables Verständnisproblem

#1 Post by Fulter »

Ich versuche mich gerade in iptables einzuarbeiten, bleibe aber den Ketten input & output in Beziehung zu forward hängen.

Sehe ich das richtig, das input/output sich immer nur auf eine bestimmte Schnitstelle, nie auf ein Netz beziehen können?

Ein Beispiel:
Ich habe zwei Rechner:
1) 10.2.2.2
2) 10.2.2.1 und 192.168.2.1

Nun u meinem Verständnisproblem:

Wenn ich nun den Verkehr (bei -P DROP default ) zwischen den beiden Netzen 10.2.2.0/24 und 192.168.2.0/24 zulassen möchte, brauche ich zwei Regeln?

Eine forward Regel für das Netz und eine input Regel zusätzlich für das lokale Interface?

Code: Select all

# Das Netz generell
iptables -A FORWARD -s 10.2.2.0/24 -d 192.168.2.0/24 -j ALLOW
# Aber der Router soll auch dürfen
iptables -A INPUT -s 10.2.2.1 -d 192.168.2.0/24 -j ALLOW
Oder habe ich da einen Gedankenfehler?

Fulter

#2 Post by Fulter »

Vergessen. Und:

Code: Select all

iptables -A OUTPUT -s 10.2.2.0/24 -d 192.168.2.1 -j ALLOW 
Der würde dann Anfragen an z.B. den Rechner 192.168.2.2 blocken (bei -P DROP)? Was ja eigentlich auch sinnig ist.

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

Re: iptables Verständnisproblem

#3 Post by Janka »

Fulter wrote:Sehe ich das richtig, das input/output sich immer nur auf eine bestimmte Schnitstelle, nie auf ein Netz beziehen können?
Nein. Du kannst natürlich auch in der INPUT und in der OUTPUT-Chain der "filter"-Tabelle Regeln definieren, die sich auf IP-Adressen beziehen. Diese Regeln gelten aber nur für Pakete, deren Weg auf dem Rechner selbst endet oder beginnt, nicht für durchgeleitete Pakete.
Eine forward Regel für das Netz und eine input Regel zusätzlich für das lokale Interface?
Nein. Du brauchst eine FORWARD-Regel für Pakete, die den Rechner nur im Rahmen des Routings passieren, sowie eine INPUT-Regel für Pakete, die auf dem Rechner selbst enden.

Code: Select all

# Das Netz generell
iptables -A FORWARD -s 10.2.2.0/24 -d 192.168.2.0/24 -j ALLOW
Diese Regel besagt, dass der Router Pakete durchlassen soll, die aus dem Quellnetz 10.2.2.x stammen und nach 192.168.2.y geroutet werden.

(Für den ordentlichen Aufbau von Verbindungen ist natürlich auch noch die spiegelbildliche Regel erforderlich.)

Code: Select all

# Aber der Router soll auch dürfen
iptables -A INPUT -s 10.2.2.1 -d 192.168.2.0/24 -j ALLOW
Diese Regel besagt, dass der Router Pakete entgegennehmen soll, die in ihm selbst enden (INPUT-Chain) und von der Quelladresse 10.2.2.1 stammen und an einen Rechner im 192.168.2.y-Bereich gehen.

Was willst du überhaupt erreichen?

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

Fulter

#4 Post by Fulter »

Du kannst natürlich auch in der INPUT und in der OUTPUT-Chain der "filter"-Tabelle Regeln definieren, die sich auf IP-Adressen beziehen
Aber immer nur einzelne IP Adressen, die auf dem Rechner gebunden sind. Nicht aber ganze Netze, ich brauche also immer zwei Regeln. Eine für das Netz und dann noch einmal extra die IP Adresse des Routers, die ja auch Bestandteil des Netzes ist.
Diese Regel besagt, dass der Router Pakete entgegennehmen soll, die in ihm selbst enden (INPUT-Chain) und von der Quelladresse 10.2.2.1 stammen und an einen Rechner im 192.168.2.y-Bereich gehen.
Ist das nicht ein Widerspruch in sich? Wenn die Pakete im diesem Rechner enden, dann können sie ja nicht an einen Rechner im 192.168.2.y Netz gehen, außer natürlich die 192.168.2.y läge auf dem gleichen Rechner wie die Quelladresse.
Für den ordentlichen Aufbau von Verbindungen ist natürlich auch noch die spiegelbildliche Regel erforderlich
Oder eleganter: -m state --state NEW,ESTABLISHED[,RELATED]
damit müßte man sich die Gegenregel sparen können.
Was willst du überhaupt erreichen?
Verständnis. Ich verstehe die Ketten nicht. Deren Sinn und vor allem deren Funktion nicht, vor allem in multihomed Umgebungen.
Wie dieses Beispiel ja auch belegt, habe ich also ersteinmal OUTPUT und INPUT verwechselt. Gut, das wäre schonmal geklärt

Um also Verkehr von 10.2.2.0 nach 102.168.2.0 komplett durchzulassen, brauche ich dann drei Regeln?:

Code: Select all

#Damit die Clients den Router & seine Dienste erreichen können:
iptables -A INPUT [-m state...] -s 10.2.2.0/24 -d  10.2.2.1 -j ALLOW 

#Damit die Clients in das 192er Netz kommen
iptables -A FORWARD [-m state...] -s 10.2.2.1 -d 192.168.2.0/24 -j ALLOW 

#Damit der Router in das 192er Netz kommt. 
iptables -A OUTPUT [-m state...] -s 10.2.2.1 -d 192.168.2.0/24 -j ALLOW 

Fulter

#5 Post by Fulter »

Da war ein Fehler, das muß natürlich heißen:

Code: Select all

#Damit die Clients in das 192er Netz kommen
iptables -A FORWARD [-m state...] -s 10.2.2.0/24 -d 192.168.2.0/24 -j ALLOW 
Natürlich muß das Quellnetz angegeben werden

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#6 Post by Janka »

Fulter wrote:
Janka wrote: Du kannst natürlich auch in der INPUT und in der OUTPUT-Chain der "filter"-Tabelle Regeln definieren, die sich auf IP-Adressen beziehen
Aber immer nur einzelne IP Adressen, die auf dem Rechner gebunden sind. Nicht aber ganze Netze, ich brauche also immer zwei Regeln. Eine für das Netz und dann noch einmal extra die IP Adresse des Routers, die ja auch Bestandteil des Netzes ist.
Du konstruierst einen Zusammenhang, wie er *allgemein* nicht existiert. Daher rührt vermutlich auch dein Verständnisproblem. Selbstverständlich kannst du in der INPUT-Chain auch Netze als Quelladressen angeben und in der OUTPUT-Chain auch Netze als Zieladressen. Das funktioniert ganz hervorragend, auch wenn sich der Router selbst nicht in diesen Netzen befindet.

Der Router muss nur dann eine Adresse innerhalb des Netzes besitzen, nach dem du filterst, wenn du in der INPUT-Chain nicht nach der Quell-, sondern nach der Zieladresse filterst. Und umgekehrt für die OUTPUT-Chain. Erscheint mir auch vollkommen logisch.
Diese Regel besagt, dass der Router Pakete entgegennehmen soll, die in ihm selbst enden (INPUT-Chain) und von der Quelladresse 10.2.2.1 stammen und an einen Rechner im 192.168.2.y-Bereich gehen.
Ist das nicht ein Widerspruch in sich? Wenn die Pakete im diesem Rechner enden, dann können sie ja nicht an einen Rechner im 192.168.2.y Netz gehen, außer natürlich die 192.168.2.y läge auf dem gleichen Rechner wie die Quelladresse.
Das Beispiel stammt doch von dir! Ob das sinnvoll ist, kann ich nur bewerten, wenn du schreibst, was du überhaupt erreichen willst. Wenn das ein Router ist, sollte der ja *beide* Netzadressen besitzen (also z.B. 10.2.2.100 und 192.168.2.1). Du hast ja nicht verraten, welcher Rechner welche Adressen besitzt.
Für den ordentlichen Aufbau von Verbindungen ist natürlich auch noch die spiegelbildliche Regel erforderlich
Oder eleganter: -m state --state NEW,ESTABLISHED[,RELATED]
damit müßte man sich die Gegenregel sparen können.
Das funktioniert aber nur bei Protokollen, für die der Kernel einen Connection-Tracking-Helper besitzt, also generisches TCP, FTP, IRC und noch ein paar weitere.
Was willst du überhaupt erreichen?
Verständnis. Ich verstehe die Ketten nicht. Deren Sinn und vor allem deren Funktion nicht, vor allem in multihomed Umgebungen.
Wie dieses Beispiel ja auch belegt, habe ich also ersteinmal OUTPUT und INPUT verwechselt. Gut, das wäre schonmal geklärt
Dann solltest du mal ein Beispiel komplett ausformulieren, damit wir alle über dasselbe reden.
Um also Verkehr von 10.2.2.0 nach 102.168.2.0 komplett durchzulassen, brauche ich dann drei Regeln?:

Code: Select all

#Damit die Clients den Router & seine Dienste erreichen können:
iptables -A INPUT [-m state...] -s 10.2.2.0/24 -d  10.2.2.1 -j ALLOW 
Wenn sich die Clients im 10.2.2.x-Netz befinden, ja. Wobei ich die Zieladresse einfach weglassen würde, denn es schadet nichts, wenn der Router auf beiden Adressen erreichbar ist.

Code: Select all

#Damit die Clients in das 192er Netz kommen
iptables -A FORWARD [-m state...] -s 10.2.2.0/24 -d 192.168.2.0/24 -j ALLOW
Ja.

Code: Select all

#Damit der Router in das 192er Netz kommt. 
iptables -A OUTPUT [-m state...] -s 10.2.2.1 -d 192.168.2.0/24 -j ALLOW 
Quelladresse weglassen, weil man oft nicht genau weiß, an welche Quelladresse Programme auf dem Rechner binden. Das kann sehr verwirrende Probleme provozieren.

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

Fulter

#7 Post by Fulter »

Erstmal vielen Dank für Deine Mühe. Ich versuche es noch einmal, besser zu erklären, was ich möchte.

Ich habe einen Router mit zwei Adressen:
10.2.2.1 und 192.168.2.1

An jedem Interface hängt ein Kasse C Netz. Jetzt möchte ich, das jeder Rechner aus dem 10.2.2.0/24 Netz in das 192.168.2.0/24 kann, mit dem minimalsten Aufwand.

Außerdem soll jeder Rechner aus dem 10.2.2.0/24 natürlich auch auf die Router IP 10.2.2.1 zugreifen können und die Router IP 10.2.2.1 auch auf das komplette 192.168.2.0/24 Netz, inklusive der Router IP 192.168.2.1.

Banal ausgedrückt, das komplette 10.2.2.0 Netz, ohne Ausnahme soll auf das komplette 192.168.2.0 Netz zugreifen können. Und die Router IP Adressen sind ja Teil dieser Netze, sollen daher also nicht anders behandelt werden.
Und das mit dem geringsten Aufwand bei den Regeln und einer default Richtlinie von -P DROP für alle Ketten - gerne nur stateful Verbindungen.

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#8 Post by Janka »

Fulter wrote:Erstmal vielen Dank für Deine Mühe. Ich versuche es noch einmal, besser zu erklären, was ich möchte.

Ich habe einen Router mit zwei Adressen:
10.2.2.1 und 192.168.2.1
Ok.
An jedem Interface hängt ein Kasse C Netz.
Diese Einteilung gibt es seit einiger zeit nicht mehr. Einfach aus dem Gedächtnis streichen.
Jetzt möchte ich, das jeder Rechner aus dem 10.2.2.0/24 Netz in das 192.168.2.0/24 kann, mit dem minimalsten Aufwand.

Außerdem soll jeder Rechner aus dem 10.2.2.0/24 natürlich auch auf die Router IP 10.2.2.1 zugreifen können und die Router IP 10.2.2.1 auch auf das komplette 192.168.2.0/24 Netz, inklusive der Router IP 192.168.2.1.

Banal ausgedrückt, das komplette 10.2.2.0 Netz, ohne Ausnahme soll auf das komplette 192.168.2.0 Netz zugreifen können. Und die Router IP Adressen sind ja Teil dieser Netze, sollen daher also nicht anders behandelt werden.
Und das mit dem geringsten Aufwand bei den Regeln und einer default Richtlinie von -P DROP für alle Ketten - gerne nur stateful Verbindungen.
Wenn alle auf alles zugreifen können sollen, brauchst du *gar keine* iptables-Regeln, sondern nur Routing. Stell einfach die Policy aller Chains auf "ACCEPT" und fertig ist.

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

Fulter

#9 Post by Fulter »

Diese Einteilung gibt es seit einiger zeit nicht mehr. Einfach aus dem Gedächtnis streichen
Wieso gibt es keine Klasse C Netze mehr? Praktisch ist auch in Zeiten von CIDR ein 24er immer noch ein Klasse C Netz.
Abgesehen davon, daß es hierfür keine Rolle spielt.
Stell einfach die Policy aller Chains auf "ACCEPT" und fertig ist
Gut, machn wir das komplett und fügen wir ein:
Rechner 10.2.2.20 - 10.2.2.30 sowie 10.2.2.60 - 10.2.2.80 dürfen nicht in das andere Netz.

Außerdem ist die Defaultpolicy "-P DROP" vorgegeben und nicht von mir frei wählbar.

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#10 Post by Janka »

Fulter wrote:
Diese Einteilung gibt es seit einiger zeit nicht mehr. Einfach aus dem Gedächtnis streichen
Wieso gibt es keine Klasse C Netze mehr? Praktisch ist auch in Zeiten von CIDR ein 24er immer noch ein Klasse C Netz.
Abgesehen davon, daß es hierfür keine Rolle spielt.
Nein. Die Netzklasse C bedeutet, dass die ersten Bits der Adresse "110" sein *müssen*. Das heißt, eine IP-Adresse in einem Klasse-C-Netz ist eine Adresse von 192.0.0.x bis 223.255.255.y mit der Netzmaske 255.255.255.0. Diese Netzmaske ergibt sich *automatisch* daraus, dass die Adresse mit den Bits "110" beginnt. Dadurch wird das Routing einfacher, aber unflexibel. Heute wird das nicht mehr so gehandhabt, man gibt überall eine "frei" wählbare Netzmaske mit an.
Stell einfach die Policy aller Chains auf "ACCEPT" und fertig ist
Gut, machn wir das komplett und fügen wir ein:
Rechner 10.2.2.20 - 10.2.2.30 sowie 10.2.2.60 - 10.2.2.80 dürfen nicht in das andere Netz.
Gut. Dann ungefähr so.

Code: Select all

# iptables -P INPUT DROP
# iptables -F INPUT
# iptables -A INPUT -m range --src-range 10.2.2.20-10.2.2.30 -j DROP
# iptables -A INPUT -m range --src-range 10.2.2.60-10.2.2.80 -j DROP
# iptables -A INPUT --src 10.2.2.0/24 -j ACCEPT

# iptables -P FORWARD DROP
# iptables -F FORWARD
# iptables -A FORWARD -m range --src-range 10.2.2.20-10.2.2.30 -j DROP
# iptables -A FORWARD -m range --src-range 10.2.2.60-10.2.2.80 -j DROP
# iptables -A FORWARD  --src 10.2.2.0/24 --dst 192.168.2.0/24 -j ACCEPT

# iptables -P OUTPUT ACCEPT
# iptables -F OUTPUT

# echo 1 >/proc/sys/net/ipv4/ip_forward
Auf einem Router an der Output-Chain rumzubasteln ist normalerweise unnötig, daher dort die Policy "Accept". Auf einem "normalen" Host kann es dagegen sinnvoll sein, um zu verhindern, dass Anwender bestimmte Ports benutzen können.
Außerdem ist die Defaultpolicy "-P DROP" vorgegeben und nicht von mir frei wählbar.
Dagegen hülfe ja

Code: Select all

# iptables -I INPUT 1 -j ACCEPT
# iptables -I OUTPUT 1 -j ACCEPT
# iptables -I FORWARD 1 -j ACCEPT
Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

Fulter

#11 Post by Fulter »

Auf einem Router an der Output-Chain rumzubasteln ist normalerweise unnötig
Und dabei ist genau die output Queue mein großes Problemkind, ich bekomme nämlich die lokalen Schnitstellen nicht raus, und weiß nicht, warum. Bei FORWARD verstehe ich so langsam daß hier physische Schnitstellen und nicht logisch Netzwerke entscheiden sind.

Deshalb würde ich, rein aus Verständnisgründen, darauf gerne noch einmal auf die output Kette bei -P DROP zu sprechen kommen.

Ein ähnliches Setup, diesmal aber mit einer unbekannten IP Adresse, da die Firewall vor der PPP Schnitstelle gestartet wird.
Zu unserem Router mit den beiden bekannten IP Adressen kommt jetzt also noch eine dritte ppp Schnittstelle mit unbekannter IP.
Das durchleiten der Clients klappt wunderbar (den state Kram lassen wir der Übersicht halber mal weg):

Code: Select all

iptables -A FORWARD -i eth0 -s 10.2.2.0 -o ppp0 -j ACCEPT
Was nicht klappt, ist die output Kette:

Code: Select all

iptables -A OUTPUT -s 10.2.2.1 -o ppp0 -j ACCEPT
Damit sollte doch aller Verkehr, der auf dem Router (10.2.2.1) erzeugt wird und über das Interface ppp0 nach drausen will, zugelassen werden? Klappt aber nicht, ich kann keine Verbindung aufbauen, auch ein "-p all" hilft nicht.
Mir ist dabei wichtig, die Regel auf den Verkehr von 10.2.2.1 (alternativ statt der IP auch eth0) über ppp0 nach draussen zu beschränken, der an eth1 (192.168.20.1) wird anderweitig abgefrühstückt und soll hier nicht betroffen sein.
Aber egal, was ich mache, ich komme nicht raus.

Eigentlich suche ich das Gegenstück zu folgenden BSD Regeln, falls die jemand geläufig sein sollte, sind aber auch recht selbsterklärend (pf und ipfw):

Code: Select all

pass out on ppp0 from 10.2.2.1 to any
pass all from 10.2.2.1 to any via ppp0

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#12 Post by Janka »

Fulter wrote:
Auf einem Router an der Output-Chain rumzubasteln ist normalerweise unnötig
Und dabei ist genau die output Queue mein großes Problemkind, ich bekomme nämlich die lokalen Schnitstellen nicht raus, und weiß nicht, warum.
Setze die Policy der Output-Queue auf "ACCEPT". Falls du das aus irgendeinem Grund nicht kannst (wie sollte der bloß lauten?), machst du es so, wie ich oben geschrieben habe.
Wenn du dann noch keine Pakete rausbekommst, liegt das Problem nicht in der "filter"-Tabelle, sondern evtl. bei nat, mangle oder raw. Da gibt es auch noch Chains!
Falls dort auch keine Regeln deinen Netzverkehr blockieren, hast du ein Routing-Problem.
Bei FORWARD verstehe ich so langsam daß hier physische Schnitstellen und nicht logisch Netzwerke entscheiden sind.
Nein, nichtmal das. Guck dir bitte das folgende Bild an:
http://www.64-bit.de/dokumentationen/ne ... html#ss3.5
Oder auch dies:
http://www.64-bit.de/dokumentationen/ne ... versal.png
Das "Paket" links, ist einfach ein Paket, das von außen in den Rechner kommt, egal auf welchem Weg. Pakete, die innerhalb des Rechners beginnen, starten hingegen bei "lokaler Prozess" im rechten Teil. Genau wie Pakete, die innerhalb des Rechners enden bei "lokaler Prozess" enden. Da musst du dir die Schnittstelle zum Userspace reindenken.
Deshalb würde ich, rein aus Verständnisgründen, darauf gerne noch einmal auf die output Kette bei -P DROP zu sprechen kommen.

Ein ähnliches Setup, diesmal aber mit einer unbekannten IP Adresse, da die Firewall vor der PPP Schnitstelle gestartet wird.
Zu unserem Router mit den beiden bekannten IP Adressen kommt jetzt also noch eine dritte ppp Schnittstelle mit unbekannter IP.
Das durchleiten der Clients klappt wunderbar (den state Kram lassen wir der Übersicht halber mal weg):

Code: Select all

iptables -A FORWARD -i eth0 -s 10.2.2.0 -o ppp0 -j ACCEPT
Was nicht klappt, ist die output Kette:

Code: Select all

iptables -A OUTPUT -s 10.2.2.1 -o ppp0 -j ACCEPT
Damit sollte doch aller Verkehr, der auf dem Router (10.2.2.1) erzeugt wird und über das Interface ppp0 nach drausen will, zugelassen werden? Klappt aber nicht, ich kann keine Verbindung aufbauen, auch ein "-p all" hilft nicht.
Diese Regel ist so korrekt. Dein Problem liegt woanders -- in der Reihenfolge der Regeln, in Regeln in andere Tabellen oder im Routing.
Eigentlich suche ich das Gegenstück zu folgenden BSD Regeln, falls die jemand geläufig sein sollte, sind aber auch recht selbsterklärend (pf und ipfw):

Code: Select all

pass out on ppp0 from 10.2.2.1 to any
pass all from 10.2.2.1 to any via ppp0
Du kannst diese Regeln nicht 1:1 übersetzen, da ipfw wenn ich mich recht erinnere Filtern, Routen und NAT in sich vereint. Iptables beeinflusst das Routen jedoch nur mittelbar, und die Filter-Tabelle ist es nicht allein, die Pakete verknautschen kann.

Verschaffe dir erstmal eine Übersicht, wie's bei Linux funktioniert. Siehe oben.

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

Fulter

#13 Post by Fulter »

Nein, nichtmal das. Guck dir bitte das folgende Bild an:
Wobei das Bild meiner Aussage doch Vorschub leistet, daß lokale Schnittstellen für die Wahl der Kette verantwortlich gemacht werden und nicht logische Netze.
Diese Regel ist so korrekt.
Aber sinnlos, wie sich inzwischen herausgestellt hat, weil es nie einen lokalen Prozess geben wird, der den Rechner über ppp0 verläßt und der 10.2.2.1 entspringt - daß war mein Fehler. Ich dachte, die Quelladresse eines Dienstes ist auch immer die, auf die er horcht. Das ist falsch, war mir aber nicht klar. Jeder lokale Prozess wird immer ppp0 (genauer: die Schnittstelle, die dem Ziel am nächsten ist) als Absende IP nehmen - damit träfe die obige Regel nie zu. Das ist das ganze Geheimnis.
Verschaffe dir erstmal eine Übersicht, wie's bei Linux funktioniert.
Das habe ich gemacht und weils mir trotzdem nicht klar war, bin ich hier gelandet. Trotzdem vielen Dank für Deine Mühe, es hat doch geholfen.

Post Reply