Forum: PC-Programmierung Webserver discovery wenn nicht im gleichen Subnet


von Thomas F. (tf1973)


Lesenswert?

Hallo zusammen,

folgendes Szenario: eine Dashboard Anwendung im Browser soll auf 
verschiedene Webserver im LAN zugreifen können. Diese laufen auf 
ESP32-S3. Es soll die Möglichkeit bestehen, dass diese Webserver 
automatisch erkannt und aufgelistet werden. Welche Möglichkeiten 
bestehen um das möglichst effizient zu gestalten? Sicher, im gleichen 
255.255.255.0 Subnet könnte man einfach durchpingen. Bei 255.255.0.0 
wird das definitv nichts gehe ich von aus. Außerdem muss noch der Fall 
abgedeckt werden, das kein DHCP zur Verfügung steht.

Danke schonmal!

von Rüdiger B. (rbruns)


Lesenswert?

Broadcast/Unicast wurde dafür gemacht.
Oder ein Ping auf das Netzwerk, also 192.168.255.255 .

: Bearbeitet durch User
von Tobias S. (tobias_s)


Lesenswert?


von Harald K. (kirnbichler)


Lesenswert?

Rüdiger B. schrieb:
> Oder ein Ping auf das Netzwerk, also 192.168.255.255 .

Das gibt nicht sonderlich viele Antworten, deutlich weniger, als gerade 
im Netzwerk Geräte aktiv sind.

von Mario M. (thelonging)


Lesenswert?

Thomas F. schrieb:
> * Dashboard Anwendung im Browser
> * nicht im gleichen Subnet
> * kein DHCP

Du bist auf dem Holzweg. Die genannten Lösungen funktionieren nur in 
stabiler Netzwerkumgebung und wären auch dann  von OS und Browser 
abhängig. Sonst kann man nur z.B. einen ESP nehmen, der einen AP 
aufmacht, die anderen ESPs per ESP-NOW abfragt und die Daten dann auf 
seiner Webseite darstellt.

von Nemopuk (nemopuk)


Lesenswert?

Wie "toll" automatisches Discovery funktioniert erlebe ich seit 30 
Jahren mit Druckern und der Dateifreigabe von Windows. Nein Danke, egal 
wie es gelöst wird, ich habe kein Interesse mehr.

Auf der Arbeit würde so ein Dashboard übrigens wegen der Scans von der 
Firewall blockiert werden.

: Bearbeitet durch User
von Markus K. (markus-)


Lesenswert?

Thomas F. schrieb:

> folgendes Szenario: eine Dashboard Anwendung im Browser soll auf
> verschiedene Webserver im LAN zugreifen können.

Wie schon geschrieben wurde: Broadcasts kann man aus fremden Subnetzen 
empfangen, allerdings muss das ja UDP sein und das kann man nicht im 
Browser empfangen.

Broadcasts gehen auch eher nicht über einen Router in andere Subnetze. 
Sind alle Subnetze auf einem Switch, dann könnte man Broadcasts 
empfangen, aber wenn die Subnetze nicht alle in den 
Netzwerkeinstellungen eingetragen sind, dann kann man sich nicht 
verbinden. Man kann also durch den Broadcast feststellen, dass die 
anderen Rechner da sind, aber dann nicht auf deren Webserver zugreifen.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Harald K. schrieb:
> Rüdiger B. schrieb:
>> Oder ein Ping auf das Netzwerk, also 192.168.255.255 .
>
> Das gibt nicht sonderlich viele Antworten, deutlich weniger, als gerade
> im Netzwerk Geräte aktiv sind.

Nunja, er will ja bestimmte Geräte finden, über deren Verhalten er 
vermutlich die Kontrolle hat. Dann würde das schon gehen. Er müßte denen 
halt allen beibiegen, dass sie auf Ping an die Broadcastadresse 
antworten.

Naja, es werden gelegentlich noch einige Uralt-Geräte im LAN ebenfalls 
auf den Ping-Broadcast antworten. Die kann er dann ausfiltern, indem er 
wirklich einen Web-Request versucht.

Aber, wenn die Broadcastadresse mangels DHCP-Server garnicht bekannt 
ist, kann man das sinnlose Broadcast-Pingen auch gleich ganz einsparen 
(und damit den Aufwand, das den gesuchten Targets beibringen zu müssen).

Einfach gleich nur ARP benutzen. Das ist die bestmögliche Näherung für 
die Aufgabe, in einer unbekannten Netzumgebung potentielle Server zu 
finden. Zumindest die drei privaten Adressbereiche sind mit einer 
binären Suche und halbwegs intelligenter Auswertung der eintreffenden 
Antworten relativ schnell abgeklappert. Nunja: wenn nicht gerade ein 
intelligenter Switch mit threat-protection den Usurpator als solchen 
erkennt und schlicht mittendrin abwürgt...

Die bessere Strategie bei unbekanntem Netzwerk ohne DHCP deshalb, 
zunächst mal nur passiv die ARP-Broadcasts anderer zu belauschen. Es 
dauert zwar eine Weile, bis man ein halbwegs verläßliches Ergebnis hat, 
aber die aktive Suche kann dann sehr viel gezielter und damit 
entsprechend schneller sein. Und mit etwas Glück ein recht zuverlässiges 
Ergebnis liefern noch bevor irgendeine threat-protection Alarm gibt.

von Frank K. (fchk)


Lesenswert?

Thomas F. schrieb:

> folgendes Szenario: eine Dashboard Anwendung im Browser soll auf
> verschiedene Webserver im LAN zugreifen können. Diese laufen auf
> ESP32-S3. Es soll die Möglichkeit bestehen, dass diese Webserver
> automatisch erkannt und aufgelistet werden.

Eine weitere Möglichkeit wäre so etwas wie dyndns, wo sich alle Server 
nach dem Aktivieren des Interfaces sich mit ihrer IP-Adresse 
registrieren.

IPv6 nutzt vermehrt Multicast. Da weiß ich aber nicht, ob der IP-Stack 
deiner ESP dafür Support hat.

fchk

von Εrnst B. (ernst)


Lesenswert?

Thomas F. schrieb:
> Bei 255.255.0.0 wird das definitv nichts gehe ich von aus.

Wieso?
Die Frage kam letztes Jahr schonmal auf. 64k gleichzeitige TCP-Connects 
(O_NONBLOCK) versuchen und bei Verbindung einen HTTP-GET zu senden geht 
Single-Threaded in ca. 2 Sekunden (Reine CPU-Zeit, x86@2GHz).

Beitrag "Re: IP-Subsysteme im LAN effektiv finden?"

Wär allerdings für einen Server, wenn das autark im Webbrowser per 
Javascript laufen soll, ist das eine andere Geschichte. Aber da kannst 
du auch kein arp, multicast u.ä. verwenden.

von Nick (nick15)


Lesenswert?

Eigentlich ist mDNS heutzutage schon der richtige Weg. Entgegen der 
landläufigen Meinung funktioniert das auch subnetzübergreifend 
problemlos, wenn man einen mDNS Repeater dazwischen hängt. Gute Router 
können das von Haus aus. Ich nutze das z.B. um einen Drucker, der in 
einem anderen VLAN hängt, über AirPrint ansprechen zu können.

Alternativ geht das auch mit einem Computer, der in beiden Subnetzen 
hängt. Siehe dazu hier: 
https://hifish.ch/2022/02/21/netzwerk-segmentierung-und-mdns-bonjour-airprint/ 
oder z.B. als Docker-Container hier: 
https://hub.docker.com/r/yuxzhu/mdns-reflector (letzteren habe ich seit 
ein paar Jahren problemlos für die Docker-interne Weiterleitung im 
Einsatz).

(Voraussetzung dafür, dass die subnetzübergreifende Erkennung dann am 
Ende auch was bringt ist natürlich, dass der Router die Pakete dann auch 
in das jeweils andere Subnetz (und wieder zurück) leitet und etwaige 
Firewall-Regeln entsprechend angepasst sind. Sonst sind die Dienste im 
anderen Subnetz durch den Repeater zwar bekanntgemacht, lassen sich aber 
nicht erreichen.)

Wie du die so erkannten Geräte dann in deine Dashboard-Anwendung 
bringst, ist dann nochmal eine andere Frage. Kommt dann drauf an, was 
für ein Backend die benutzt. Sollte aber für alles gängige entsprechende 
mDNS libraries geben.

: Bearbeitet durch User
von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Man kann doch problemlos ein eigenes broadcast-basiertes Protokoll in 
der Art von ARP entwickeln und nutzen.

Der interessierte Netzwerkteilnehmer (der mit dem Dashboard) sendet 
einen solchen Broadcast (UDP, spezieller Port). Die erreichbaren 
Clients, die etwas damit anfangen können, antworten an die Adresse des 
Fragenden. Die Antwort muss kein Broadcast sein, die Antwortadresse ist 
bekannt, wenn die im Broadcast stand. Und sie kann sogar per TCP 
erfolgen, damit sie nicht verloren geht.

Man muss damit auch nicht alle Netzwerkteilnehmer "durchpingen", den 
Broadcast empfangen sowieso erstmal alle (im gleichen Subnet) und 
antworten nur dann, wenn sie auch zur Zielgruppe gehören.

: Bearbeitet durch User
von Nick (nick15)


Lesenswert?

Frank E. schrieb:
> Man kann doch problemlos ein eigenes broadcast-basiertes Protokoll in
> der Art von ARP entwickeln und nutzen.

Das ist maximal unnötig. Wieso Zeit verlieren mit einer eigenen 
Implementierung, wenn man auch einfach mDNS samt der passenden libraries 
nutzen kann?

Eine Webapp, die z.B. sämtliche per mDNS erkannten Webserver einsammelt 
und als Liste präsentiert baut ChatGPT dir mit einem Prompt …

von Markus K. (markus-)


Lesenswert?

Nick schrieb:
> Eine Webapp, die z.B. sämtliche per mDNS erkannten Webserver einsammelt
> und als Liste präsentiert baut ChatGPT dir mit einem Prompt …

Redet mDNS nicht UDP? Das geht nicht im Browser. Man braucht also ein 
Hilfsprogramm, das außerhalb läuft.

von Frank K. (fchk)


Lesenswert?

Nick schrieb:
> Frank E. schrieb:
>> Man kann doch problemlos ein eigenes broadcast-basiertes Protokoll in
>> der Art von ARP entwickeln und nutzen.
>
> Das ist maximal unnötig. Wieso Zeit verlieren mit einer eigenen
> Implementierung, wenn man auch einfach mDNS samt der passenden libraries
> nutzen kann?

Ich stimme mit @Nick überein, dass es deutlich sinnvoller ist, eine der 
zahlreichen vorhandenen Lösungen zu verwenden als eine weitere 
Sonderlocke zu erzeugen, natürlich nur unter der Vorausetzung, dass alle 
vorhandenen Anforderungen erfüllt werden. Was in dem konkreten Fall das 
Beste ist (mDNS, WS-Discovery, ...) müsste man sehen, aber da gibts auf 
jeden Fall was von ...

fchk

von Nick (nick15)


Lesenswert?

Markus K. schrieb:
> Redet mDNS nicht UDP? Das geht nicht im Browser. Man braucht also ein
> Hilfsprogramm, das außerhalb läuft.

Ja, natürlich. Aber bei einem Dashboard bin ich mal davon ausgegangen, 
dass es ein entsprechendes Backend gibt.

Ganz unabhängig davon würde ich sowieso empfehlen, dass man die ganze 
Discovery nicht den Browser machen lässt, sondern das Backend. Weil dann 
müssen die mDNS-Broadcasts für den Client gar nicht sichtbar sein. Das 
würde nämlich spätestens dann zu Problemen führen, wenn man das 
Dashboard über eine Verbindung aufruft, die mDNS (oder auch sämtliche 
Form von UDP-Broadcasts) nicht wirklich unterstützt, z.B. über ein 
WireGuard-VPN auf iOS (nicht sicher, ob das bei Android geht).

Wenn man den Server dann auch noch ins gleiche Subnetz wie die zu 
entdeckenden Geräte hängt, könnte man sich sogar den mDNS-Repeater 
sparen.

: Bearbeitet durch User
von Mario M. (thelonging)


Lesenswert?

Markus K. schrieb:
> Redet mDNS nicht UDP? Das geht nicht im Browser. Man braucht also ein
> Hilfsprogramm, das außerhalb läuft.

Ja, nennt sich Windows(10/11).

von Markus K. (markus-)


Lesenswert?

Ich habe gerade dass da gefunden
https://github.com/hrzlgnm/mdns-browser

Das hat Clients für verschiedene Betriebssysteme. Mal kurz unter Windows 
ausprobiert, es findet 8 Services auf der Fritzbox, je 1-2 auf den 
Repeatern und einen der Raspberry Pis.

von Markus K. (markus-)


Lesenswert?

Mario M. schrieb:
> Markus K. schrieb:
>> Redet mDNS nicht UDP? Das geht nicht im Browser. Man braucht also ein
>> Hilfsprogramm, das außerhalb läuft.
>
> Ja, nennt sich Windows(10/11).

Das kann man im Browser abrufen?
Oder meinst Du einfach die Windows-Netzwerkumgebung?

von Mario M. (thelonging)


Lesenswert?

Ich meinte die Namensauflösung per mDNS. Also einfach die Geräte passend 
benennen, dann kann man sie im Browser über den Namen aufrufen. 
Inwiefern "service discovery" im Broser möglich ist, weiß ich nicht. 
Vielleicht geht da was mit JavaScript und Sockets.

von Markus K. (markus-)


Lesenswert?

Mario M. schrieb:
> Inwiefern "service discovery" im Broser möglich ist, weiß ich nicht.
> Vielleicht geht da was mit JavaScript und Sockets.

Eher nicht. Javascript im Browser kann kein UDP, was aber nötig wäre.

von Rüdiger B. (rbruns)


Lesenswert?

Ob S. schrieb:
> Einfach gleich nur ARP benutzen.

Und der ARP-Cache füllt sich auch mit dem Ping auf die Broadcast 
Adresse.

von Nick (nick15)


Angehängte Dateien:

Lesenswert?

Ich verstehe immer noch nicht, wieso der Client da irgendwas machen 
soll. Das soll die Webapp im Backend machen und gut ist. Dann hat man es 
komplett Browser- und Netzwerkunabhängig. Das einzige, wozu der Client 
fähig sein muss, ist eine HTTP-Verbindung zu den entdeckten Geräten 
(wobei man selbst das proxien könnte, aber lassen wir das mal).

Proof of concept für ein Dashboard nach zwei Prompts mit ChatGPT; das 
ist der Python-Code:
1
from flask import Flask, render_template
2
from zeroconf import Zeroconf, ServiceBrowser, ServiceListener
3
import threading
4
import socket
5
6
app = Flask(__name__)
7
zeroconf = Zeroconf()
8
discovered_services = {}
9
10
class HTTPServiceListener(ServiceListener):
11
    def add_service(self, zeroconf, type, name):
12
        info = zeroconf.get_service_info(type, name)
13
        if info:
14
            address = socket.inet_ntoa(info.addresses[0])
15
            port = info.port
16
            full_url = f"http://{address}:{port}"
17
            discovered_services[name] = full_url
18
19
    def remove_service(self, zeroconf, type, name):
20
        if name in discovered_services:
21
            del discovered_services[name]
22
23
def start_mdns_browser():
24
    listener = HTTPServiceListener()
25
    ServiceBrowser(zeroconf, "_http._tcp.local.", listener)
26
27
# Start mDNS discovery in a background thread
28
threading.Thread(target=start_mdns_browser, daemon=True).start()
29
30
@app.route("/")
31
def index():
32
    return render_template("index.html", services=discovered_services)
33
34
if __name__ == "__main__":
35
    app.run(debug=True, host="0.0.0.0", port=5000)

Den HTML-Code kann ich nicht posten, weil Spamschutz, deshalb im Anhang.

Zum Ausführen, python-Skript unter $WORKDIR/dashboard.py ablegen und 
index.html unter $WORKDIR/templates/index.html ablegen.

Dann nur noch dependencies installieren und starten:
1
cd $WORKDIR
2
python3 -m venv .venv
3
source .venv/bin/activate
4
pip3 install flask zeroconf
5
python3 ./dashboard.py

Und dann im Browser das Dashboard unter http://localhost:5000 aufrufen.

: Bearbeitet durch User
von Tobias S. (tobias_s)


Lesenswert?

Als Ergänzung zu Nicks Vorschlag könnte man zusätzlich einen eigenen 
Service anlegen – ähnlich wie es beim Arduino-OTA-Flashen gemacht wird.

Beispiel unter Linux:
1
avahi-browse _arduino._tcp
2
+ enp34s0 IPv4 esp32-d4d4xxxxxx    _arduino._tcp        local

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Namensauflösung reicht ja nicht, du musst die aufzulösenden Namen erst 
mal haben. Willst du die raten? Namenskonvention und dann 
durchprobieren? Ist doch Mist.

Um es halbwegs vernünftig zu machen könnte man z.B. noch so etwas wie 
DNS-SD hinzu nehmen um eine entsprechende Service-Discovery zu machen um 
die Namen zu bekommen. Die erhaltenen Hostnames kann man dann mit mDNS 
oder was auch immer auflösen.

Das wiederum bedeutet die PTR, SVR und TXT DNS Records dafür müssen 
aufgesetzt werden. Eigentlich kein Problem - in einem anständig 
administrierten Netzwerk, oder sogar durch die Clients selber die sich 
registrieren (Dynamic DNS). Das entspricht dann einem Bootstrapping der 
Service-Discovery-Konfiguration die auch nicht ohne ein paar 
Basisconfigurationen auf den Clients geht.

Und jetzt sind wir beim eigentlichen Punkt. Das Vorhaben ist mal wieder 
der klassische feuchte Traum alles ohne Infrastrukturunterstützung, ohne 
Netzwerkadministation und ähnliches machen zu wollen. Es soll irgendwie 
einfach magisch funktionieren. Alleine schon wieder die Idee einfach mal 
alles durchzupingen oder mit ARP-Requests vollzumüllen ... Das kannst du 
in einem ranzigen Heimnetz machen (in dem stolz auf DHCP verzichtet 
wurde), aber viel Spaß damit in Kundennetzwerken durchzukommen (wenn der 
Admin nicht gerade ein Volltrottel ist).

Also, Standardprotokolle auswählen die das machen was man will, breit 
sein den Preis dafür zu bezahlen. Nämlich die dafür dafür notwendige 
Infrastruktur im Netz aufsetzen zu müssen. Wie der Rheinländer sagt, von 
nix kütt (kommt) nix.

---

Nebenbei bemerkt, die Behauptung dass ein Host die Broadcastadresse 
seines Subnetzes mangels DHCP-Server nicht kennt ist natürlich auch 
quatsch.

Damit er überhaupt über IP kommunizieren kann (und jetzt komm mir keiner 
mit Ethernet-only, man könnte ja ...), braucht er eine IP-Adresse und 
eine Netmask. Hat er die nicht ist er auf IP-Ebene nicht existent. Auch 
hier wieder von nix kütt nix.

Mit IP-Adresse und Mask ist jedoch auch die Broadcast-Adresse 
festgelegt. Es ist immer die letzte Adresse im Subnet.

Ohne DHCP müssen die IP Adresse und Mask zum Beispiel statisch von Hand 
auf dem Host konfiguriert sein. Das macht bei großen Netzwerken viel 
Spaß ... Oder man spielt Zeroconf-Lotterie und der Host würfelt sich 
nach gewissen Regeln eine IP-Adresse in 169.254.0.0/16 aus. Auch hier 
ist die Broadcast-Adresse die letzte Adresse im Subnet 169.254.255.255. 
Also bekannt.

von Alexander (alxc)


Lesenswert?

Habe demletzt bei einem Kunden aus der Industrie ein Netzwerk vorgeführt 
bekommen wo die Knoten einfach angesteckt werden und los geht’s mit IPv6 
(only) und mDNS. War keinerlei Netzwerkkonfiguration notwendig und 
keinerlei Kenntnis von IP Adressen. Das hat mir sehr gut gefallen. 
Natürlich ging’s da nicht um solche hochkomplexe Geschichten wie 
Internetzugang und Drucker sondern „nur“ um Maschinen die miteinander 
reden sollten.

Dennoch fand ich das so überzeugend dass ich mich frage warum wir noch 
mit IPv4 Konfiguration unsere Zeit verschwenden.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.