NEWS
Lesen/Schreiben von Datenpunkten via Internet
-
Hallo zusammen,
hat sich jemand schon damit beschäftigt, auf einzelne Datenpunkte in ioBroker aus dem Internet zuzugreifen, ohne dafür eine Portweiterleitung oder VPN zu nutzen? Ich denke da z.B. an einen Webspace beim Provider. Anwendungsfall wäre z.B. das Öffnen des Garagentores (ja, mit Telegram geht das natürlich deutlich eleganter).
Die idealen Lösungen sind wohl die Cloud-Angebote von ioBroker selbst. Ich habe bislang auch keinen Adapter gefunden, der dies ansonsten umsetzen würde. Einzig https://github.com/Mic-M/iobroker-geofency-php geht für das Geofencing einen ähnlichen Weg.
Meine primitive Idee, wenn es nur um einzelne Datenpunkte geht, ist derzeit:
- PHP-Skript auf Webspace legen, das mit zwei Variablen, die in de URL übergeben werden, aufgerufen wird: Datenpunkt und Wert (Skript gesichert z.B. durch htaccess)
- PHP-Skript schreibt den Wert in eine Textdatei auf dem Webserver, z.B. Datenpunktname.txt mit Inhalt "true".
- Ein ioBroker-Skript fragt z.B. alle 5 Sekunden diese Datei ab und aktualisiert einen Datenpunkt.
- Umgekehrt kann natürlich auch die Textdatei auf dem Webserver bei Änderungen seitens ioBroker aktualisiert werden.
Ich habe testweise mal etwas gebastelt, das auch funktioniert. Seht ihr GET-URL-Abfrageintervalle z.B. alle 5 Sekunden (oder gar noch kürzer) problematisch für ioBroker oder dessen Host?
Gerne auch alternative Ideen.
-
-
@iobaer
denkbar wäre auch telegram als befehlskanal zu verwenden -
Danke Euch - aber genau die beiden Möglichkeiten hatte ich doch bereits selbst erwähnt.
-
@iobaer
sorry, überlesen -
@iobaer Also so ganz ohne Portweiterleitung wird schwer, aber ich hab mir mal so etwas ähnliches gebaut.
Mit Python und dem Flask-Modul.
Flask wartet auf eine URL und übergibt die einzelnen Pfade der URL an das Script:#!/usr/bin/python # -*- coding: utf-8 -*- #import sys import os import subprocess from functools import wraps from flask import Flask, request, Response app = Flask(__name__) @app.route('/') def hello(): return "Start Radio By URL! Use /Name_or_Group_of_Echo/stationid" #Schalten nur nach Anmeldung, siehe http://flask.pocoo.org/snippets/8/ def check_auth(username, password): # This function is called to check if a username / # password combination is valid. return username == 'alexa' and password == 'manfred' def authenticate(): # Sends a 401 response that enables basic auth return Response( 'Could not verify your access level for that URL.\n' 'You have to login with proper credentials', 401, {'WWW-Authenticate': 'Basic realm="Login Required"'}) def requires_auth(f): @wraps(f) def decorated(*args, **kwargs): auth = request.authorization if not auth or not check_auth(auth.username, auth.password): return authenticate() return f(*args, **kwargs) return decorated @app.route('/<echodevice>/<stationid>') @requires_auth def EchoPlayRadio(echodevice, stationid): #print("http://192.168.1.246:5001/" + echodevice +"/" + stationid) #print("/alexa_remote/alexa_remote_control.sh -d " + echodevice + " -r " + stationid) # Abfragen ob Radio schon spielt oder nicht if echodevice == "Erdgeschoss": #Nachfolgend mit Prüfung echostatus = subprocess.check_output("/alexa_remote/alexa_remote_control.sh -d " + echodevice + " -q | grep currentState | cut -d'" + '"' + "' -f 4", shell=True) #Eventuelles "neue Zeile" am Ende entfernen (ja, war notwendig) echostatus = echostatus.rstrip() #echostatus = os.system("/alexa_remote/alexa_remote_control.sh -d " + echodevice + " -q | grep currentState | cut -d'" + '"' + "' -f 4") #print("Der Status ist:" + echostatus + ":") if echostatus == "PLAYING": os.system("/alexa_remote/alexa_remote_control.sh -d " + echodevice + " -e pause") else: os.system("/alexa_remote/alexa_remote_control.sh -d " + echodevice + " -r " + stationid) # NDR2 StationID: s56857 # http://192.168.1.246:5001/Keller/s56857 # Lautstärke setzen #os.system("/alexa_remote/alexa_remote_control.sh -d " + echodevice + " -e vol:70") return ('OK'), 200 else: if stationid == "stop": os.system("/alexa_remote/alexa_remote_control.sh -d " + echodevice + " -e pause") return ('OK'), 200 else: os.system("/alexa_remote/alexa_remote_control.sh -d " + echodevice + " -r " + stationid) return ('OK'), 200 return ('OK'), 200 if __name__ == '__main__': #print("Starte RadioByURL") app.run(host='0.0.0.0', port=5001)
Obiges Beispiel horcht auf Port 5001 und erwartet so etwas wie
http://alexa:manfred@192.168.1.8/kueche/1234
kueche und 1234 hast du danach als Werte zur Verfügung. Das Beispiel oben nutzt auch die Basis Authentifizierung
Ich rufe in dem Bespiel ein Script auf (/alexa_remote/alexa_remote_control.sh), aber es ginge auch ein SimpleAPI Aufruf etc.https ginge natürlich auch, man müsste halt ein Zertifikat einbinden und Flask als https starten lassen.
Das Skript lief bei mir als Dienst unter Ubuntu, hier eine Beispiel-Service-Beschreibung:
[Unit] Description=Echo Radio URL Service After=syslog.target [Service] Type=simple WorkingDirectory=/gpio/flask ExecStart=/gpio/flask/RadioByURL.py SyslogIdentifier=echoradiourl StandardOutput=syslog StandardError=syslog Restart=always RestartSec=3 [Install] WantedBy=multi-user.target
Für mein Beispiel müsstest du also eine Portweiterleitung auf Port 5001 auf den Rechner machen auf dem das Skript läuft. Aber es ist mit einer Anmeldung abgesichert
-
@bananajoe sagte in Lesen/Schreiben von Datenpunkten via Internet:
Aber es ist mit einer Anmeldung abgesichert
hehe
Bei solchen aussagen möchte ich dann immer gerne mal auf die aktuell aktiven Sicherheitsmeldungen zur jeweiligen Programmiesprache hinweisen:
https://www.cvedetails.com/vulnerability-list/vendor_id-10210/product_id-18230/Python-Python.html
und im speziellen gerade diesen
https://www.cvedetails.com/cve/CVE-2021-29921/Software, die nach außen hin mit einer Portfreigabe offen ist, ist meiner Meinung nach extrem schwer abzusichern. Deswegen würde ich nur einer Software vertrauen, die extra dafür gedacht ist offen im Internet zu stehen.
Wenn du da einen Fehler machst, dann ist er in deinem Netzwerk drin.
Oder hast du da noch zusätzliche Absicherungen drin, wie bspw das die Applikation in einem separaten Netzwerksegment steht, so das, wenn jemand zugriff auf den Rechner hat zumindest nicht auch auf die anderen Rechner zugriefen kann?
Oder der Software zumindest einen eigenen User auf dem Rechner verpassen oder läuft die Software sogar als root, weil man dann ja keine Probleme mit den blöden Berechtigungen hat.Ihr müsst euch ja mal vorstellen was das eigentlich bedeutet, in einen Rechner einzubrechen: Über die vorhandenen Möglichkeiten lokal Befehle ausführen zu können. Auch python hat Befehle um auf die Betriebssystemebene zu kommen. Wenn man mal da angekommen ist, dann kommen noch die Sicherheitslücken des Betriebssystems um sich höherwertige Rechte zu verschaffen. Damit ist der Rechner kompromittiert und darf komplett neu aufgesetzt werden. und wer ist den in der Lage herauszufinden wie lange der Rechner schon kompromittiert ist und ob nicht auch schon die Backups verseucht sind.
Wenn der Angreifer dann auch noch über das Netz Zugriff auf andere Rechner hat, dann hilft nur noch alles löschen und Neuinstallieren.ja ihr seit meistens Privatleute, da lohnt es sich nicht so anzugreifen. aber Teilnehmer eines Botnetzes zu sein um Spam zu versenden, DDos-Attacken auszuführen oder wieder als Attack-Relay zu dienen um den Ursprung des Angriffes zu verschleiern könnte schon sein.
Stellt keine Software mit einer Portfreigabe offen ins Netz, ausser die Software ist dafür ausdrücklich gemacht (Router, Nextcloud, Webserver)
Ansonsten Zugriff nur über VPN.
Die Methode von @IOBaer ist schon nicht schlecht, da hier die Verbindung von innen nach außen aufgemacht wird. Aber dann steht der Webspace offen im Netz. Um die Basis (OS,Webserver) kümmert sich der Anbieter. Um die Software musst dich auch selbst kümmern. Wenn man da die Möglichkeiten des Zugriffs auf den eigenen Rechner einschränkt, dann ist das Risiko kalkulierbar (das absetzen von Shellbefehlen würde ich auch über diese Möglichkeit nicht umsetzen).Nachtrag weil es so schön ist:
https://vulmon.com/searchpage?q=flask -
@oliverio selbstverständlich hast du recht. Aber man kann an den Wahrscheinlichkeiten arbeiten:
- Host (und Python) auf aktuellen Stand halten
- keine Allerweltsports nehmen. Ports gibt es von 1 bis 65535 und das Scannen kostet viel Zeit
- GeoIP-Blocking verwenden. Entweder auf der Firewall so das diese z.B. auf diesen Port nur Zugriffe aus Deutschland zulässt oder im Python
- Reverse Proxy davor verwenden und auf dem Port nur auf einen bestimmten DNS Namen hören, gerne Subdomain aka "mein44dienst-geheim.mydomain.de"
- https verwenden um das eventuelle abfangen von Passwörtern zu verhinden
Jedes dieser Dinge wird die Wahrscheinlichkeit auf einen Hack um ein vielfaches senken
Alternativ: VPN verwenden. Auch nicht 100% sicher. Aber was ist das schon
Zusätzlich: Monitoring! Um Einbruchsversuche / Einbrüche zu erkennen
-
ja Security ist alle nur die Wahrscheinlichkeit zu minimieren und möglichst viele Hürden aufbauen.
-
Hallo zusammen,
danke für die Antworten. Welchen Vorteil gäbe es denn bei der Methode von @OliverIO im Vergleich zur SimpleAPI?
Wie geschrieben, auf Powerweiterleitungen will ich hier komplett verzichten. Viele unterschätzen glaube ich, welcher Aufwand da eigentlich betrieben werden müsste (echte DMZ etc.) - selbst in vielen Firmen werden Ports oftmals nur weitergeleitet.
Mein PHP-Projekt funktioniert soweit gut, allerdings wäre es gut zu wissen, ob ihr in Abfragen alle 5 Sekunden ein Problem für den ioBroker seht? Ich würde vermuten eher nicht, da ja ioBroker-intern auch laufend irgendwelche Aktualisierungen stattfinden.
-
@iobaer sagte in Lesen/Schreiben von Datenpunkten via Internet:
hat sich jemand schon damit beschäftigt, auf einzelne Datenpunkte in ioBroker aus dem Internet zuzugreifen, ohne dafür eine Portweiterleitung oder VPN zu nutzen? Ich denke da z.B. an einen Webspace beim Provider. Anwendungsfall wäre z.B. das Öffnen des Garagentores (ja, mit Telegram geht das natürlich deutlich eleganter).
Warum kein VPN? Ich öffne genau damit mein Garagentor. Per Handy lässt sich der Aufbau der notwendigen VPN-Verbindung automatisch erledigen. Passendes Widget auf die Oberfläche legen und mit einem Klick ist die Toröffnung erledigt.
-
@samson71 Ist alles bekannt und nutze ich ebenfalls bereits so. Geht mir hier eher um die technischen Möglichkeiten. Die PHP-Lösung funktioniert und die zeitliche Differenz (maximal 5 Sekunden aktuell) ist aus meiner Sicht absolut in Ordnung für einen Schaltvorgang.
Vielleicht kann einer der ioBroker-Programmierer ja noch was zur Systembelastung von so kurzen JS-Abfragen (http-GET) sagen (alle 5 Sekunden oder noch kürzer).
-
@iobaer
Eigentlich ist das für iobroker kein Problem.
Du kannst ja mal die Systemauslastung deines Adapters/Skripts und die des gesamten Systems im Auge behalten.
Dann solltest du noch in die Richtlinien deines Providers schauen, ob den da alle 5 Sekunden eine Anfrage eintreffen darf. Hast du Webspace oder einen virtuellen Server?
Bei den günstigeren Preismodellen kalkulieren die eher damit, das die Teile größtenteils nix machen. Wenn du da alle 5 Sekunden drauf feuerst und das irgendwo in den AGBs ausgeschlossen oder mit Quota belegt ist, dann ist irgendwann dicht.Hier ein Auszug von ionos
2.1.4. Fair Use-Pflichten
https://www.ionos.de/terms-gtc/terms-server/
Sie verpflichten sich, den exzessiven Verbrauch von Ressourcen zu vermeiden. Ausschlaggebend ist ein Leistungsabfall der Plattform, der Verdacht auf betrügerisches Verhalten (Fraud) oder die Beeinträchtigung der Rechte Dritter. Weiterhin verpflichten Sie sich, jede Störung zu vermeiden, die zu einem Leistungsabfall der Plattform, auf dem sich die Ressource befindet, führt und die Erbringung des Dienstes oder die Rechte Dritter, die die Infrastruktur teilen, beeinträchtigen würde. -
@oliverio
Also ich habe einen IONOS V Server M auf dem meine Homepage läuft.
Die hat so mehr als 12.000 Seitenaufrufe pro Monat + wird Regelmäßig von den Suchmaschinen durchgeackert (mindestens einmal am Tag)
Dazu läuft auf dem Ding ein Zabbix-Agent für das Monitoring welches die Werte von 120 Datenpunkten im Minutentakt (aber nicht alle gleichzeitig) an den Hauptserver sendet.
Zusätzlich wird 1x am Tag ein Backup per Veeam-Agent zur mir nach Hause und in die Firma gemacht.Und ich habe bisher keinen Ärger bekommen, und erwarte das auch nicht. Der Netzwerkverkehr ist trotz allen überschaubar, genauso wie CPU und RAM Nutzung.
Wenn ich mein Zabbix betrachte sollte er sich bei alle 5 Sekunden abfragen keine Sorgen machen müssen.
Doof finde ich die Lösung trotzdem. Weil halt alle 5 Sekunden gepollt wird. Eine Lösung über einen offenen Port wäre "Push" und würde nur dann Arbeit und Datenverkehr erzeugen wenn etwas passiert,Alternativ wäre eine Technik wie sie auch bei vielen anderen Diensten verwendet wird:
- Client (also dein ioBroker zuhause) fordert die Textdatei an - mit großen Timeout, z.B. 1h oder 8h
- Server (die Kiste z.B. bei IONOS wo dein PHP läuft) nimmt die Anfrage an ... beantwortet diese aber erst wenn es eine a.) Änderung gibt oder b.) der Timeout sich nähert
- Client bekommt Antwort und stellt gleich wieder eine neuen Anfrage
Da müssen natürlich Mechanismen rein die bei einem Verbindungsabbruch greifen etc.
Aber genau so arbeiten z.B. viele Apps, WhatsApp zum Beispiel. So kommt neues immer sofort/zeitnah rein ohne das ständig gepollt werden muss.Bei IONOS sind das übrigens echte VMware-VMs, ich bin sehr angetan über die Geschwindigkeit mit der die VM läuft
-
@bananajoe
Ich sehe du hast genügend technisches Hintergrundwissen.
ich wollte es nur erwähnen, das umso kleiner das eingekaufte Produkt ist,
es da evtl. Probleme geben könnte. du hast ja schon einen etwas größeren Server.Die Formulierung ist ja auch sehr interpretationswürdig bezüglich exzessiv.
Wenn man aber das kleinste Webspace-Produkt mit Skriptfähigkeiten hat, könnte es sein, das bei über 17000 Zugriffen an einem Tag bei dem dann noch PHP angeworfen wird irgend jemand sagt, das passt da nicht. Hängt aber davon ab, wie eng die ihre internen Grenzen setzen.
Jedes Produkt ist ja irgendeinem physischen Server zugeordnet. Je nach Kalkulation werden dann auf diesen Server dann uU mehrere (100e) zugeordnet. Wenn dann da mehrere auf solche Ideen kommen, dann merken die anderen Kunden auf diesem Server das uU schon.
Aber alles gut -
-
@bananajoe Ich habe mal mit zwei Bekannten Rücksprache gehalten, die bei Providern arbeiten - und mich auf Webhosting bezogen. Kurzform: die Abfragen im z.B. 5-Sekunden-Takt sind kein Problem.
Ich teste das die Tage mal (bewusst nicht auf einem externen VPS oder dedicated Server, sondern einem Webhosting-Paket), ggf. auch mit kürzeren Abfragezeiten und warte ab, ob sich wer meldet
-
@iobaer Auch auf die Gefahr hin, mir den Unmut von Dir und den anderen Postern in diesem Threat zuzuziehen: Warum bitte investiert ihr soviel Zeit in die Entwicklung einer eigenen Lösung, anstatt die paar Euro für iot/SimpleAPI auszugeben und damit auch das ioBroker Projekt zu unterstützen, von dem wir alle ja profitieren???