FHEM Forum

FHEM => Automatisierung => Thema gestartet von: dev0 am 04 Juni 2017, 09:16:11

Titel: TcpServerUtils.pm: optionaler Parameter noIPcheck für TcpServer_Accept()
Beitrag von: dev0 am 04 Juni 2017, 09:16:11
Das ESPEasy Modul verwendet TcpServerUtils. Allerdings prüft das Modul bereits selbst anhand von allow/deny Attributen, ob eine Verbindung akzeptiert wird oder nicht. Ich weiß nicht, ob es das Attribut allowfrom damals noch nicht gab oder ich es übersehen habe. Wie dem auch sei, das Modul akzeptiert ebenfalls nur noch private IP Adressen, wenn nichts weiter konfiguriert ist.
Um Code-Duplizierung zu vermeiden, würde ich mir einen 3. optionalen Parameter für TcpServer_Accept($$;$) wünschen, um den neu eingeführten lokalen/privaten IP-Check abschalten zu können.
Titel: Antw:TcpServerUtils.pm: optionaler Parameter noIPcheck für TcpServer_Accept()
Beitrag von: rudolfkoenig am 04 Juni 2017, 10:30:58
Ich verstehe noch nicht, warum fuer manche Module eine Aussnahme sinnvoll waere. Eine Verbindung aus dem "wilden" Internet sollte immer geprueft werden. Modulentwickler sollten dazu im Interesse der Benutzer die angebotenen Mechanismen (allowfrom Attribut, oder ein Modul, was AuthenticateFn/AuthorizeFn implementiert, wie allowed) verwenden, anstatt eigene Mechanismen zu erfinden. Ich kann mich irren, in diesem Fall freue ich mich ueber eine Aufklaerung.

P.S.: allowfrom gab es "schon immer".
Titel: Antw:TcpServerUtils.pm: optionaler Parameter noIPcheck für TcpServer_Accept()
Beitrag von: dev0 am 04 Juni 2017, 12:03:29
Öffentliche IP Adressen bedeuten nicht zwangsläufig wildes Internet: meine beiden DMZten haben zB. auch öffentliche IPv4 (/27) und IPv6 (/64) Adressen, Firmennetze verwenden intern auch häufig öffentliche IP Bereiche. Ebenso benutzt wohl kaum jemand IPv6 link-local Adressen um einen Server zu adressieren.

Die gewünschte Ausnahme hat damit zu tun, dass das ESPEasy Modul einen eigenen Mechanismus verwendet um Verbindungen zu akzeptieren oder auch nicht. Dieser Mechanismus ist langsamer und aufwendiger als allowfrom, bietet aber die Möglichkeit IP Bereiche (bitmask oder dotted decimal) zu erlauben und/oder zu verbieten. Ich hätte auch das allowfrom Attribut der Bridge hart auf .* setzen können, statt Code zu duplizieren, aber Attribute gehören ja dem Benutzer ;)

Die Möglichkeit das Modul allow zu nutzen habe ich für diesen Fall bisher nicht erkannt, da es mWn keine IPs "freischalten" kann. AuthenticateFn/AuthorizeFn sind im Wiki leider noch nicht beschrieben, vielleicht könnte man auch damit "die Freischaltung" von IPs erreichen. Es wäre aber über die vorgeschagene Änderung einfacher.

Wenn Du der Meinung bist, dass die ACL im ESPEasy Modul blöd, unsinnig oder unsicherer ist, dann baue ich das um. Ich würde die Routinen aber gerne weiter verwenden, da sonst auch die Anwender Änderungen vornehmen müssen, damit ihre Installationen weiterhin so funktioniert, wie es bisher der Fall ist.
Titel: Antw:TcpServerUtils.pm: optionaler Parameter noIPcheck für TcpServer_Accept()
Beitrag von: rudolfkoenig am 05 Juni 2017, 12:25:27
Zitat...Firmennetze verwenden intern auch häufig öffentliche IP Bereiche.
Das funktioniert nur bei solchen Firmen, die frueh bei der IP Verteilung dabei waren, sonst kollidieren die internen mit externen Adressen. Diese Diskussion ist aber sinnlos, da du mit deiner Methode das gleiche Problem loest.

Ich faende es sinnvoller, Sicherheitspruefungen im Framework zu hinterlegen, damit es allen zur Verfuegung steht, anstatt den Alleingang einzelnen Modulen zu erleichtern.

ZitatAuthenticateFn/AuthorizeFn sind im Wiki leider noch nicht beschrieben
Stimmt, aber es gibt den Sourcecode. Ich versuche hier als Text zu formulieren:

AuthenticateFn und AuthorizeFn sind zwei unabhaengige Frameworks.

AuthenticateFn dient zum Pruefen, ob jemandem (Benutzer/Client Programm) ein Zugang zu einem FHEM Dienst gewaehrt werden kann. Dazu ruft der betroffenen FHEM-Dienst (wie FHEMWEB oder telnet) Authenticate() auf, mit dem betroffenen device-hash und einem Dienst spezifischen zweiten Parameter auf (FHEMWEB: Http-Header, telnet:Passwort). Auf der anderen Seite ruft fhem.pl alle Module auf, die ein AuthenticateFn anbieten. Diese liefern 0 (nicht zustaendig), 1 (Zugang erlaubt) oder 2 (Zugang abgelehnt) zurueck. Dabei hat "erlaubt" Vorrang vor "abgelehnt".

Es gibt bisher eine einzige Implementierung von AuthenticateFn in allowed, die Folgendes anbietet:
- fuer FHEMWEB: basicAuth und basicAuth+Cookie (dadurch wird basicAuth erst nach Ablauf des Cookies wieder geprueft)
- fuer telnet: password und globalpassword
telnet und FHEMWEB ist in allowed noch hart verdrahtet, das kann ich aber gerne aendern, bisher gab es keine Anfragen dafuer.


AuthorizeFn dient zum pruefen, welche Funktionen ein Benutzer ausfuehren darf. Dazu ruft der betroffene Dienst Authorized() mit dem betroffnen device-hash, die Klasse, und das konkrete Argument auf. Z.Bsp. Aithorized($FW_chash, "cmd", "perl") fragt, ob die aktuelle FHEMWEB-Verbindung berechtigt ist, perl befehle auszufuehren. Dazu ruft Authorized() in fhem.pl alle Module auf, die Authorized anbieten. Die antworten mit 0 (nicht zustaendig), 1 (erlaubt) oder 2 (verboten). Hier "gewinnt" das erste Modul, der erlaubt oder verboten meldet.
Die Implementierung in allowed hat dafuer 2 Moeglichkeiten
- Mit dem allowedDevices Attribut kann man manipulierbare Geraete spezifizieren, falls die abgefragte Klasse "devicename" ist. Das wird in devspec2array benutzt.
- allowedCommands erlaubt bestimmte Befehle, falls die abgefragte Klasse "cmd" ist. Das wird in den Analyze*Command Funktionen aufgerufen.


Die allowedfrom Abfrage koennte auch in AthenticateFn realisiert werden, "leider" ist dafuer eine allowed Instanz notwendig.
Titel: Antw:TcpServerUtils.pm: optionaler Parameter noIPcheck für TcpServer_Accept()
Beitrag von: dev0 am 06 Juni 2017, 08:03:12
Zitat
Das funktioniert nur bei solchen Firmen, die frueh bei der IP Verteilung dabei waren, sonst kollidieren die internen mit externen Adressen.
Für IPv4 trifft das zu, bei IPv6 sieht das schon wieder ganz anders aus. Nach meinen Beobachtungen benutzen/bekommen Firmen eher geroutete "Global IPv6 Unicast Adressen" als nicht geroutete "Local IPv6 Unicast Adressen".
Dabei fällt mir gerade auch auf, dass die "Local IPv6 Unicast Adressen" in TcpServer_Accept() noch fehlen: fc00::/7 (RFC4193, ULA)

Zitat
anstatt den Alleingang einzelnen Modulen zu erleichtern.
Sehe ich ein und ziehe meinen Wunsch zurück ;)

Zitat
Stimmt, aber es gibt den Sourcecode. Ich versuche hier als Text zu formulieren:
Zusammen mit Deinen Erklärungen werde ich mir das noch einmal anschauen. Vielen Dank dafür.