IPTables und DHCP Fragen?

8

In meinem anderen Thread habe ich über einige interessante Dinge über die Richtlinien und Zustände von iptables gesprochen . Jetzt möchte ich mehr darüber erfahren, wie DHCP funktioniert und wie iptables es versteht.

Die ETH0 ist mit meinem Haupt-Switch verbunden, der die dynamische IP von meinem Router empfängt, um nicht nur Internetzugang, sondern auch Zugang zu meinem äußeren Netzwerk zu erhalten.

ETH1 ist die interne Karte, die mit einem internen Switch verbunden ist, über den X-Clients ihr IPS von diesem Server erhalten

Das ETH1-Netzwerk ist 192.168.1.0/255.255.255.0, wobei die Server-IP 192.168.1.254 lautet.

Soweit ich verstanden habe, ist dhcp ein Bootp-Protokoll. Selbst wenn Sie Ihre Firewall-Richtlinien haben, um alles zu DROPEN, würde Ihr Netzwerk dennoch DHCP erhalten, was in den von mir durchgeführten Tests als wahr erschien.

Von tcpdump:

root@test:~# tcpdump -i eth1 port 67 or 68
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
11:34:03.943928 IP 192.168.1.2.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 00:0c:29:29:52:8b (oui Unknown), length 303
11:34:03.957647 IP 192.168.1.254.bootps > 192.168.1.2.bootpc: BOOTP/DHCP, Reply, length 300
11:34:06.492153 IP 192.168.1.2.bootpc > 192.168.1.254.bootps: BOOTP/DHCP, Request from 00:0c:29:29:52:8b (oui Unknown), length 303
11:34:06.506593 IP 192.168.1.254.bootps > 192.168.1.2.bootpc: BOOTP/DHCP, Reply, length 300

Ich habe eine einfache Protokollregel erstellt, um zu sehen, was iptables tut:

root@test:~# tail -f /var/log/syslog
Oct 15 11:30:58 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9527 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:31:43 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9529 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:33:32 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9531 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:34:03 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9533 PROTO=UDP SPT=68 DPT=67 LEN=311

Hier sind meine Iptables-Regeln im Moment:

# deny all traffic
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP

# Use stateful inspection feature to only allow incoming connections
# related to connections I have already established myself
$IPT -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# allow all traffic on lo interface
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT

Selbst mit der Standardrichtlinie, alles zu löschen, erhalte ich immer noch das DHCP in meinem Netzwerk, während das Erneuern einer IP und dergleichen viel länger dauert.

Wenn ich meiner Firewall die folgende Regel hinzufüge:

$IPT -I OUTPUT -o $INTIF -p udp --dport 67:68 --sport 67:68 -j ACCEPT

Es wird viel weniger Zeit dauern, um einen Client-DHCP zu aktualisieren.

In Anbetracht des oben Gesagten:

  1. Warum dauert es tatsächlich länger, es zu aktualisieren, obwohl es nicht blockiert wird?
  2. Ist es möglich, den DHCP-Server überhaupt zu DROPEN, ohne ihn auszuschalten?
  3. Ist es möglich, den DHCP-Server in iptables mit dem BOOTP zu AKZEPTIEREN? wie geht das

Wenn du gute Links kennst, würde es mir nichts ausmachen, viel zu nehmen :)

Guapo
quelle
Ich bin ein bisschen verwirrt von Ihrer Protokollausgabe von tcpdump und iptables. Überwachen Sie die Netzwerkschnittstelle im Promiscuous-Modus? Verwendet Ihr Firewall-Server tatsächlich DHCP, um seine Netzwerkkarte zu konfigurieren?
Steven Montag,
@Steven der Server mit der oben genannten Firewall hat eth0 und eth1, eth0 empfängt DHCP als Client von außen und eth1 ist mein DHCP-Server für mein internes Netzwerk, von dem ich spreche. Was meinst du damit, dass Are you monitoring the network interface in promiscuous modeich noch lerne ...
Guapo
Oh ok. Sie müssen Ihr Netzwerk und Ihre Server wirklich besser beschreiben, wenn Sie möchten, dass jemand Ihre Frage versteht!
Steven Montag,
Über den Promiscous-Modus: en.wikipedia.org/wiki/Promiscuous_mode
Steven Montag,
@Steven wird das jetzt tun, danke für den Hinweis. Glaubst du, ich muss etwas anderes als das Netzwerklayout angeben?
Guapo

Antworten:

13

Ich werde # 2 antworten: Nein.

Beim Abrufen einer IP-Adresse erstellt der DHCP-Dämon einen Raw-Socket für die Netzwerkschnittstelle und verwaltet das UDP-Protokoll selbst. Daher durchlaufen die UDP-Pakete niemals iptables.

Der Grund, warum der DHCP-Dämon UDP implementieren muss, ist, dass der Kernel UDP (tatsächlich die gesamte TCP / IP-Suite) nur verarbeiten kann, wenn die Schnittstelle eine IP-Adresse hat. Früher gaben DHCP-Dämonen einer Schnittstelle zuerst die IP-Adresse 0.0.0.0, aber das funktioniert nicht mehr.

Mark Wagner
quelle
Paket Buchse. Raw Sockets kann durch iptables gehen. afaict. unix.stackexchange.com/a/447524/29483
sourcejedi
5

Hinzufügen

$IPT -I INPUT -i $INTIF -p udp --dport 67:68 --sport 67:68 -j ACCEPT

soll das DHCPD-Update beschleunigen :) Es soll sowohl auf der Seite von INPUT als auch von OUTPUT funktionieren. Sie können dhcpd mit ebtables DROPEN, nicht mit iptables. DHCPD hört bei 0.0.0.0 zu, nicht innerhalb von IP

Ta Coen
quelle
+1 Ich hatte es auf INPUT und es dauerte genauso lange, als hätte ich es nicht in meinen Regeln. Als ich es OUTPUT gemacht habe, hat es einen RIESIGEN Unterschied gemacht. Ich werde über ebtables lesen, danke.
Guapo
$ IPT -I INPUT -i $ INTIF -s 0/0 -p udp --dport 67:68 --sport 67:68 -j AKZEPTIEREN
Ta Coen
Ich habe gerade das oben Genannte ausprobiert und es dauert immer noch zu lange im Vergleich zur OUTPUT-Regel.
Guapo
Da die Richtlinie DROP lautet, müssen Sie sowohl INPUT als auch OUTPUT verwenden.
Ta Coen
3

Meine jüngste Beobachtung zu OpenWRT Kamikaze 7.09 = 2.4.34 und udhcpc aus Busybox 1.4.2:

Ich habe eine "ACCEPT" -Richtlinie in der OUTPUT-Kette und in der INPUT-Richtung habe ich mich ursprünglich auf diese klassische Sammelregel verlassen:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

um die DHCP-Antworten in (auf meinem udhcpc) ​​auf der WAN-Schnittstelle zuzulassen. Hier weist mir der Upstream-DHCP-Server meines ISP eine IP-Adresse zu.

Beachten Sie den Unterschied zwischen einem anfänglichen DHCP-Austausch (Erkennen, Anbieten, Anfordern, Bestätigen) und einer Erneuerung des DHCP-Lease (Anfordern, Bestätigen).

Nach dem Booten startet udhcpc mit dem vollständigen anfänglichen Austausch. Dieser Austausch würde gelingen. Und ein oder zwei weitere Erneuerungen wären ebenfalls erfolgreich - nur eine Anfrage und Bestätigung. Der DHCP-Server meines ISP fordert normalerweise eine Verlängerungszeit von etwa einer Stunde bis 1,5 Stunden an. Daher fordert mein DHCP-Client alle 30 bis 45 Minuten eine Verlängerung an (dieses Verhalten basiert auf dem RFC).

Aber ungefähr bei der dritten oder vierten Erneuerung würde es interessant werden. TCPdump würde ungefähr drei Erneuerungsversuche anzeigen, gefolgt von einem vollständigen anfänglichen Austausch - innerhalb einer Zeitspanne von nur wenigen Minuten oder sogar Sekunden. Als ob udhcpc nicht gefallen würde, was es zurückbekam :-( und letztendlich mit dem vollständigen Austausch zufrieden sein würde. Danach würde eine weitere Erneuerung in einer halben Stunde erfolgreich sein ... und die Geschichte würde sich erneut wiederholen.

Ich habe herausgefunden, dass vielleicht die Verbindungsverfolgung im Kernel etwas falsch gemacht hat. Als ob der Conntrack-Eintrag nach ungefähr zwei Stunden abläuft und die späteren DHCP-Erneuerungen fehlschlagen, weil die ACK vom Server es nicht tatsächlich zu udhcpc schafft, den Socket abzuhören. Beachten Sie, dass tcpdump (libpcap) die unformatierte Schnittstelle überwacht und alle eingehenden Pakete sehen kann, bevor sie iptables unterliegen. Sobald udhcpc die Erneuerung aufgibt und verzweifelt versucht, mit einem vollständigen Austausch (beginnend mit DISCOVER) von vorne zu beginnen, erstellt der Kernel einen neuen Conntrack-Eintrag und kann verwandte Pakete für einige Zeit verstehen ...

Sicher genug, sobald ich etwas hinzugefügt habe wie:

iptables -A INPUT -i $OUT_IF -p udp --sport 67 --dport 68 -j ACCEPT

Die Erneuerungen scheinen für immer zu funktionieren.

Die folgenden tcpdump-cmdline-Argumente sind möglicherweise hilfreich:

tcpdump -vv -s 1500 -i eth0.1 port 67 or port 68

Hinweis: Der -vvfragt nach der ausführlichen Dissektorausgabe. eth0.1ist mein WAN-Port (auch eine "NAT außerhalb" -Schnittstelle).

Ein interessantes Attribut in den ACK-Paketen ist das LT: Feld = vorgeschlagene / maximal gewährte Lease-Zeit in Sekunden. DHCP-Anforderungen werden von Port 68 an Port 67 gesendet. Die Antworten kommen von Port 67 an Port 68.

frr
quelle
Deine Geschichte macht keinen Sinn. Unabhängig davon, ob initial oder erneuert, wird der DHCP-Austausch immer vom Client gestartet, der von Port 68 an Port 67 sendet, entweder an eine bestimmte IP oder als Broadcast. Und mit ausgehendem ACCEPT wird dies immer funktionieren. Eine Antwort vom ausgehenden Ziel sollte immer durch die ESTABLISHED-Regel eingehen, sodass die Erneuerung für immer nur mit der ESTABLISHED-Regel funktionieren sollte, da bei jeder Erneuerung auch der Conntrack-Status erneuert oder neu erstellt wird.
Mecki
Eine Erneuerung sendet eine Anfrage openwrt:68 -> dhcpserver:67und die ACK wird dhcpserver:67 -> openwrt:68. Dies gilt als GESTELLT und wird bestanden. Wenn der alte Verbindungszustand abgelaufen ist, wird ein neuer erstellt. Wenn es ein Problem gibt, kann es nur mit dem anfänglichen Austausch sein, wie der ENTDECKER ist, 0.0.0.0:68 -> 255.255.255.255:67und das ANGEBOT wird sein dhcpserver:67 -> new-openwrt:68, was nicht als GESTELLT gilt. Dies funktioniert nur, da DHCP unter Linux normalerweise iptables mit einem Paketsocket umgeht. Andernfalls ist eine eingehende Regel erforderlich, die Pakete vom UDP-Port 67 oder vom UDP-Port 68 zulässt.
Mecki
1
Sie sagen auch, dass mehrere Erneuerungen erfolgreich waren, aber jede Erneuerung, die erfolgreich ist, erneuert auch den Conntrack-Status. Wenn Ihr Conntrack-Status nach 2 Stunden abläuft, würde eine Erneuerung ihn erneut um weitere 2 Stunden usw. verlängern und somit niemals ablaufen . Das Standard-Conntrack-Timeout für UDP beträgt jedoch nur 30 Sekunden und nicht 2 Stunden, und ich bezweifle, dass OpenWRT dies auf 2 Stunden geändert hat, da dies verrückt wäre. Ihre Geschichte scheint mir also völlig fehlerhaft zu sein.
Mecki
@Mecki, danke für das wertvolle Feedback :-) Inzwischen ist meine Antwort 4 Jahre alt. Vor ungefähr einem Jahr begann mein ASUS WL500G Deluxe (nach ungefähr 12 Jahren Laufzeit aufgrund des Austauschs von Kondensatoren) endgültig abzuflocken, und ich warf diesen alten Kamikaze zusammen mit der Hardware weg. Im Moment führe ich ein aktuelleres OpenWRT auf einem modernen TP-Link-AP aus, und nach einigem Überlegen habe ich meine alten Firewall-Skripte nicht wiederverwendet. OpenWRT scheint jetzt eine gute Firewall zu haben ... Ich möchte damit sagen, dass ich meine früheren Behauptungen nicht überprüfen kann. Ich weiß nur, dass die Regel für zusätzliche iptables geholfen hat.
vom