Ein UDP-Unicast-Paket in einen Broadcast verwandeln?

8

Wir müssen einige Computer in unserem internen LAN aus dem Internet aktivieren.
Wir haben einen etwas geschlossenen Router mit sehr wenigen Möglichkeiten, ihn zu konfigurieren.
Ich würde gerne netfilter (iptables) verwenden, um dies zu tun, da es keinen Daemon oder ähnliches beinhaltet, aber andere Lösungen sind in Ordnung.

Was ich vorhabe:

  • Der externe Computer gibt ein WOL-Paket (Wake-On-LAN) an die öffentliche IP-Adresse aus (mit dem richtigen MAC im Inneren).
  • Auf dem Router ist der richtige Port geöffnet (z. B. 1234), und die Daten werden auf eine Linux-Box umgeleitet
  • Die Linux-Box wandelt das UDP-Unicast-Paket in ein Broadcast-Paket um (genau der gleiche Inhalt, nur die Zieladresse wird in 255.255.255.255 oder 192.168.0.255 geändert).
  • Das Multicast-Paket kommt zu jeder Netzwerkkarte, und der gewünschte Computer ist jetzt wach

Dafür lautet eine sehr einfache Netzfilterregel:
iptables --table nat --append PREROUTING --in-interface eth+ --protocol udp --destination-port 1234 --jump DNAT --to-destination 192.168.0.255

Leider scheint Netfilter die Umwandlung in Broadcast zu ignorieren. 192.168.0.255 und 255.255.255.255 geben nichts. Auch mit 192.168.0.0 und 0.0.0.0 getestet
Ich habe tcpdump verwendet, um zu sehen, was passiert:
tcpdump -n dst port 1234
13:54:28.583556 IP www.xxx.yyy.zzz.43852 > 192.168.0.100.1234: UDP, length 102
und sonst nichts. Ich sollte eine zweite Zeile haben wie:
13:54:28.xxxxxx IP www.xxx.yyy.zzz.43852 > 192.168.0.255.1234: UDP, length 102

Wenn ich zu einer Nicht-Multicast-Adresse umleitung, ist alles in Ordnung. Ich habe die 2 erwarteten Zeilen. Aber offensichtlich funktioniert das bei WOL nicht.

Gibt es eine Möglichkeit, netfilter anzuweisen, Broadcast-Pakete auszugeben?

Andere Methoden, über die ich nachdenke:

  • Verwenden Sie iptables, um die gewünschten Pakete abzugleichen, sie zu protokollieren, und verwenden Sie einen Daemon, um die Protokolldatei zu überwachen und das Broadcast-Paket auszulösen
  • Verwenden Sie iptables, um die gewünschten Pakete an einen lokalen Daemon umzuleiten, der das Broadcast-Paket auslöst (einfacher).
  • benutze socat (wie?)
Gregory MOUSSAT
quelle
Ein Broadcast-Paket ist nicht nur ein Paket, das an eine Broadcast-Adresse gesendet wird. Es gibt ein Flag für Sockets mit dem Namen SO_BROADCAST. Ich versuche herauszufinden, wie iptables es ändern kann.
Lgeorget
@lgeorget: iptables ist nicht mit so Sockets verwandt.
Bertrand SCHITS
Tatsächlich. Ich suche nicht den richtigen Ort. Es muss irgendwo eine Option für iptables geben, damit Broadcast-Pakete gesendet werden können.
Lgeorget
1
Haben Sie versucht, iptables --table nat --append PREROUTING --in-interface eth + --protocol udp --destination-port 1234 --jump DNAT --to-destination 192.168.0.0?
Lgeorget
@lgeorget: danke für die idee. Aber das gleiche Ergebnis. Ich aktualisiere die Frage
Gregory MOUSSAT

Antworten:

12

socatist ein Killer-Dienstprogramm. Fügen Sie irgendwo in Ihre Init-Skripte ein:

socat -u -T1 UDP-LISTEN:1234,fork UDP-DATAGRAM:255.255.255.255:5678,broadcast

Einige Benutzer haben Probleme mit UDP-LISTEN, daher scheint die Verwendung von UDP-RECV besser zu sein (Warnung: könnte die Broadcast-Pakete in einer Endlosschleife senden):

socat -u UDP-RECV:1234 UDP-DATAGRAM:255.255.255.255:5678,broadcast

forkErlaube Socat, auf die nächsten Pakete zu warten.
T1Begrenzen Sie die Lebensdauer gegabelter Teilprozesse auf 1 Sekunde.
255.255.255.255ist allgemeiner als 192.168.0.255. So können Sie einfach kopieren und einfügen, ohne über Ihre aktuelle Netzwerkstruktur nachzudenken. Vorsichtsmaßnahme: Dies sendet wahrscheinlich die gesendeten Pakete an alle Schnittstellen.

Als Sie bemerkten ich, dass WOL mit jedem Port funktioniert. Ich frage mich, ob das zuverlässig ist. In vielen Dokumenten wird nur über die Ports 0, 7 und 9 gesprochen. Auf
diese Weise kann ein nicht privilegierter Port verwendet werden, sodass Sie socatmit dem Benutzer ausgeführt werden können nobody.

Vielen Dank lgeorget Hauke Lagingund Gregory MOUSSATan dieser Antwort teilgenommen zu haben.
Fiel frei, um Details hinzuzufügen.

Bertrand SCHITS
quelle
Ich habe das versucht, aber das Problem ist, dass UDP-LISTEN den Socket schließt, nachdem das erste Paket angekommen ist, unabhängig von der Abzweigung. Verwenden Sie stattdessen UDP-RECV.
Lgeorget
Kein Problem hier. Sie haben die Option "Gabel" verwendet? Ich sehe in dem Mann UDP-RECV Zusammenführungspakete. Ich habe keine Ahnung, was es bedeutet. UDP-RECVFROM zeigt dieses Verhalten nicht, aber es kann ein Fehler im Mann sein.
Bertrand SCHITS
Ja, ich habe die 'Gabel' benutzt. Ich habe versucht, mit einem Socat und zwei Netcat-Prozessen (einer zum Senden von Paketen an Socat, der andere zum Empfangen der Broadcast-Pakete). Mit UPD-LISTEN simuliert socat eine Verbindung und schließt den Socket am Ende. Bei UDP-RECV wird das standardmäßige verbindungslose Verhalten von UDP verwendet. Von socat man: "Normalerweise werden Socket-Verbindungen mit dem Herunterfahren (2) beendet, wodurch der Socket beendet wird, selbst wenn er von mehreren Prozessen gemeinsam genutzt wird."
Lgeorget
2
Wird socat dann auf allen Schnittstellen senden?
Hauke ​​Laging
1
@lgeorget: "echo 'dummy' | nc -u -q 0 127.0.0.1 1234" funktioniert perfekt mit -UDP-LISTEN. Ich kann es mehrmals ausführen. Ich habe jedoch Probleme mit -UDP-RECV und -UDP-RECVFROM: Die Pakete werden mit maximaler Verbindungsrate gesendet, bis socat beendet wird. Sehen Sie das gleiche Problem mit tcpdump?
Bertrand SCHITS
3

Broadcast-Verkehr ist per Definition für den lokalen Computer bestimmt. Dies bedeutet, dass das Paket auf 192.168.0.255 DNAT'ed wird und der Kernel dann das Paket sieht und entscheidet, dass es für den Router selbst bestimmt ist, sodass Sie dieses Paket in der INPUT-Kette sehen. Der Router (und jedes andere Gerät) glaubt, dass 192.168.0.255-Pakete für sich selbst bestimmt sind, und leitet sie nicht weiter. Broadcast-Pakete werden nicht vom Design weitergeleitet.

Mit dem erwähnten ARP-Trick gibt es eine großartige Problemumgehung. Sie "verlieren" eine IP-Adresse. 192.168.0.254In diesem Beispiel verwende ich Dummy. Denken Sie daran, niemals 192.168.0.254Geräte in Ihrem Netzwerk zuzuweisen :

  1. Erstellen Sie einen statischen ARP-Eintrag auf der LAN-Schnittstelle für die IP-Adresse, die Sie niemals für einen Computer verwenden werden:

    arp -i ethLAN --set 192.168.0.254 FF:FF:FF:FF:FF:FF
    
  2. DNAT Ihr Wake-On-Lan UDP-Taffic auf der WAN-Schnittstelle zu dieser Dummy-IP-Adresse:

    iptables --table nat --append PREROUTING  --in-interface ethWAN --protocol udp --destination-port 1234 --jump DNAT --to-destination 192.168.0.254
    

Dies funktioniert perfekt für WOL-Pakete. Diese Problemumgehung funktioniert auch bei Produkten, die auf dem Linux-Kernel basieren, wie Mikrotik-Geräten und openwrt-Geräten. Ich verwende diesen Trick auf Mikrotik-Geräten, um meine Maschine mit meinem Handy aus der Ferne zu aktivieren.

plagiat0r
quelle
Die aus dem Internet empfangenen Pakete werden nicht gesendet. Aus diesem Grund lautet die Frage "Transform UNICAST to BROADCAST"
Gregory MOUSSAT
2

Ich habe diese Frage bei Serverfault gefunden .

Ich habe es jedoch nicht geschafft, solchen Broadcast-Verkehr über meinen Router zu erhalten. Die DNATted-Pakete kamen nicht einmal in meiner FORWARD-Kette an. Vielleicht gibt es eine seltsame Kernel-Option, die das nicht zulässt.

Aber die ARP-Idee ist interessant. Ich denke, das sollte von einer Regel in OUTPUT begleitet sein, die Pakete an diese Adresse verbietet, damit sie nur mit weitergeleitetem Verkehr erreicht werden können.

Hauke ​​Laging
quelle
1

Socat OpenWRT

Socat wurde bereits als Antwort angegeben, die angegebene Antwort funktionierte jedoch auf meiner Plattform OpenWRT mit einer dynamischen WAN-Adresse nicht.

Mein Ziel ist es, Unicast-UDP-Wake-on-Lan-Pakete vom UDP-Port 9 der WAN-Schnittstelle an ein Subnetz weiterzuleiten, das am 192.168.20.255 gesendet wird.

Die kaputten (iptables)

Ich habe es auch mit iptables versucht, aber jedes Mal, wenn ich eine Regel hinzufüge, die mit 255 endet, wird die Regel in Mush mit der Zieladresse 0.0.0.0 umgewandelt, wenn ich drucke mit:

iptables -t nat -L

Ich glaube, iptables ist nicht in der Lage, Datenverkehr zu multiplexen, wie dies bei einer Konvertierung von Unicast zu Broadcast erforderlich ist.

Die schlechten (gefälschten Arp-Einträge)

Das Fälschen von Arp-Einträgen ist nicht so schlimm, da die Pakete an alle im Ethernet-Segment gelangen, hat aber die folgenden Nachteile

  • Sie "verbrauchen" eine IP-Adresse
  • Die Ziel-IP im WoL-Paket ist falsch, obwohl Sie sie erhalten, weil die MAC-Adresse nur FFFF ist ...
  • Eine IP-Fehlfunktion kann auftreten, wenn jemand im Netzwerk diese IP-Adresse verwendet.
  • Es ist eine Ethernet-Übertragung und keine IP-Übertragung.

Hinweis: Dies kann mit dem arpBefehl oder ip neighBefehl erfolgen.

Der gute

socat ist, wie in der vorherigen Antwort angegeben, schlecht. Bei der vorherigen Socat-Antwort bin ich jedoch auf einige Probleme gestoßen.

  1. Mein Socat hat keinen Datenverkehr weitergeleitet, als das UDP-Broadcast-Ziel 255.255.255.255 war. Ich habe dies vermieden, indem ich das Broadcast-Subnetz auf das von mir verwendete beschränkt habe, was wahrscheinlich sicherer ist.
  2. Als ich die Bindeadresse auf 0.0.0.0 setzte, geriet ich in einen Broadcast-Sturm, weil der Datenverkehr von meinem LAN zurück in den Socat zurückprallte. Ich habe dies zuerst durch Binden an meine öffentlichen DDNS gelöst. Dies ist jedoch nicht ideal, da DDNS möglicherweise nicht verfügbar sind und meine dynamisch zugewiesene IP-Adresse meine Änderung ist.

Ich konnte mich an 0.0.0.0 (alle Adressen) binden und den Broadcast-Sturm vermeiden, indem ich eine iptables-Regel hinzufügte, um zu verhindern, dass eingehende Broadcasts von der LAN-Seite zurück in socat zurückspringen. Diese Regel enthält zusätzlich zu einer iptables-Regel zum Akzeptieren von Datenverkehr auf UDP-Port 9 und einer iptables-Regel zum Protokollieren die folgenden drei Regeln zusätzlich zum Befehl socat.

iptables -I input_wan_rule -p udp --dport 9 -j ACCEPT -m comment --comment "firewall entry to allow udp port 9 to socat"
iptables -I input_wan_rule -p udp --dport 9 -j LOG --log-prefix 'Received MAGIC PACKET on udp/9'
iptables -I input_lan_rule -p udp --dport 9 -d 192.168.20.0/24 -j DROP -m comment --comment "block broadcast from bouncing back to socat to avoid storm"

killall socat 2>/dev/null
socat -u -T1 UDP-LISTEN:9,bind=0.0.0.0,fork UDP-DATAGRAM:192.168.20.255:9,broadcast &

Für die OpenWRTer ist es ausreichend , dies einzufügen /etc/firewall.userund auszugeben /etc/init.d/firewall restart.

Herzlichen Glückwunsch, Sie sollten jetzt WoL von überall im Web für Ihr Netzwerk arbeiten lassen.

vittorio88
quelle
0

Tatsächlich kann netfilter keine Übertragung durchführen, der Routing-Mechanismus tut dies.

Standardmäßig werden jedoch weitergeleitete Sendungen gelöscht.

Es ist möglich geworden, gerichtete UDP-Sendungen im aktuellen Linux-Kernel (ca. Version 5.0) weiterzuleiten.

Sie müssen die bc_forwardingParameter für die Broadcast-Netzwerkschnittstelle ändern :

sudo sysctl -w net.ipv4.conf.eth1.bc_forwarding=1

(Hinweis: Es scheint, dass die Option net.ipv4.conf. All .bc_forwarding nicht funktioniert.)

Nun sollte ein Kernel mit mehr als 5.0 + iptables für Sie ausreichen

Yury Pavlov
quelle