[Patch] smartVISU über HTTPS und nur einen Port 443

Begonnen von Loredo, 07 August 2016, 21:22:14

Vorheriges Thema - Nächstes Thema

Loredo

Hallo,

ich schlage folgenden Patch von io_fhem.js vor, damit der Zugriff auf smartVISU auch per HTTPS möglich ist:

(siehe auch Github Pull Request)

*** io_fhem.js.orig   2016-08-07 17:02:03.000000000 +0200
--- io_fhem.js   2016-08-07 22:06:25.290150006 +0200
***************
*** 90,95 ****
--- 90,103 ----
        };
      }
 
+     if (address === "") {
+       io.address = window.location.hostname;
+     }
+
+     if (port === "") {
+       io.port = window.location.port;
+     }
+
      if(address === "offline") {
        io.offline = true;
      }
***************
*** 420,426 ****
    // Open the connection and listen what fronthem sends
    // -----------------------------------------------------------------------------
    open: function () {
!     io.socket = new WebSocket('ws://' + io.address + ':' + io.port + '/');
 
      io.socket.onopen = function () {
        io.log(2, "socket.onopen");
--- 428,444 ----
    // Open the connection and listen what fronthem sends
    // -----------------------------------------------------------------------------
    open: function () {
!     var socketproto = "ws:";
!
!     if (window.location.protocol == "https:") {
!         socketproto = 'wss:';
!     }
!
!     if (io.port == "80" || io.port == "443") {
!         io.socket = new WebSocket(socketproto + '//' + io.address + '/ws/');
!     } else {
!         io.socket = new WebSocket(socketproto + '//' + io.address + ':' + io.port + '/ws/');
!     }
 
      io.socket.onopen = function () {
        io.log(2, "socket.onopen");


Dabei wird abhängig der verwendeten Zugriffsart des Clients entweder ws:// oder wss:// verwendet.

Außerdem ist der Suffix von "/" auf "/ws/" geändert.
Somit kann man im Webserver einen Reverse-Proxy konfigurieren, der Websocket Verbindungen entsprechend an fronthem durchtunnelt. Vom Client wird dann nur noch ein einzelner Port für alles verwendet.

Die Nginx Konfiguration aus dem Wiki muss dafür wie folgt angepasst werden:


server {
        listen 80 default_server;
        listen [::]:80 default_server;
        listen 443 ssl;
        root /var/www/html;
        index index.php index.html index.htm index.nginx-debian.html;

        ssl_certificate /etc/ssl/private/ssl-cert-snakeoil.pem;
        ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

        server_name _;

         location /ws/ {
             proxy_pass http://127.0.0.1:2121;
             proxy_http_version 1.1;
             proxy_set_header Upgrade $http_upgrade;
             proxy_set_header Connection "upgrade";
         }

        location / {
                try_files $uri $uri/ =404;
        }
        location ~ \.php$ {
                 try_files $uri =404;
                 fastcgi_split_path_info ^(.+\.php)(/.+)$;
                 fastcgi_pass unix:/run/php/php7.0-fpm.sock;
                 fastcgi_index index.php;
                 include fastcgi.conf;
                 fastcgi_read_timeout 600;
         }
         location ~* \.(js|css|png|jpg|jpeg|gif|ico|eot|otf|ttf|woff)$ {
                 access_log off; log_not_found off; expires 30d;
         }
         location = /robots.txt { access_log off; log_not_found off; }
         location ~ /\. { deny all; access_log off; log_not_found off; }
}


Die Websocket Tunnellung funktioniert nicht unbedingt mit jedem beliebigen Webserver oder jeder Version.
HAproxy oder eben Nginx können es, Apache hat glaube ich noch immer Schwierigkeiten mit dem Protokoll Upgrade.

In der smartVISU Konfigurationsdatei config.ini gibt man dann als Port einfach 80 oder bei konfiguriertem HTTP 443 statt 2121 an.


Gruß
Julian
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

Loredo

Achso: Auf iOS braucht man ein valides Zertifikat. Ansonsten stellt Safari keine Verbindung zum Websocket Server (fronthem) her.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

Loredo

Ich habe den Patch oben nochmals angepasst.

Wenn driver_address und/oder driver_port in config.ini leer gelassen werden, dann wird automatisch die URL aus der Browser Adresszeile verwendet.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

dev0

Zitat von: Loredo am 07 August 2016, 21:22:14
Außerdem ist der Suffix von "/" auf "/ws/" geändert.
Diese Änderung hatte ich vor langer Zeit schon einmal vorgeschlagen, allerdings ohne einen Patch zu liefern.
Ich halte diese Änderung in jedem Fall für sinnvoll.

herrmannj

Hi

gute Idee. Den patch nehme ich gern (Danke!) - bitte vorher unbedingt testen ob es Nebenwirkungen gibt falls ohne reverse proxy gearbeitet wird.

Der patch ergänzt sehr gut ssl /wss. Auf die Idee den ws(wss) auf den gleichen port laufen zu lassen bin ich noch gar nicht gekommen. Wenn man das ohne reverse-proxy macht wird das etwas tricky (würde aber vmtl gehen).

Welche Vorteile seht ihr denn, mal abgesehen davon das man keinen zweiten Port am router öffnen muss ? Wenn fronthem einen port für http(s)/ws(s) ermöglichen würde dann würde das die Komplexität doch erhöhen (kein rocket science, aber auch nicht ganz trivial) was im Regelfall mehr Fehlermöglichkeiten (mehr debugging) nach sich zieht.

Gibt es zwingende Gründe die dafür sprechen ?

Danke und vg
joerg

dev0

Mir ging es damals um den Suffix /ws, damit man den ws traffic auf einem reverse Proxy identifizieren kann.

Loredo

#6
Zitat von: herrmannj am 08 August 2016, 12:35:58
bitte vorher unbedingt testen ob es Nebenwirkungen gibt falls ohne reverse proxy gearbeitet wird.


Ist in allen möglichen Kombinationen probiert und hat keine Auswirkung. Das Verhalten ist gleich, wenn man explizit in der config.ini weiterhin einen Port und eine/n IP/Server angibt.


Zitat von: herrmannj am 08 August 2016, 12:35:58
Auf die Idee den ws(wss) auf den gleichen port laufen zu lassen bin ich noch gar nicht gekommen.


Soweit ich weiß ist das eigentlich Standard in Produktivumgebungen großer Webanbieter. Da würde man ohne Tunnelling nicht an Firmenfirewalls vorbeikommen.


Zitat von: herrmannj am 08 August 2016, 12:35:58
Wenn man das ohne reverse-proxy macht wird das etwas tricky (würde aber vmtl gehen).


Aus welcher Sicht heraus? Ohne Reverseproxy müsste fronthem Portsharing mit dem Webserver machen und Web-Verbindungen an den Webserver weiterleiten. Ich glaube so herum funktioniert es mit dem HTTP Protocol Upgrade Header grundsätzlich auch, macht aber wenig Sinn. Du würdest ja nur die Rollen vertauschen (fronthem wäre dann auch ein Reverseproxy) und wir wollen ja Fhem möglichst weit "hinten" haben und nicht an vorderster Front was Webzugriff angeht.


Zitat von: herrmannj am 08 August 2016, 12:35:58
Welche Vorteile seht ihr denn, mal abgesehen davon das man keinen zweiten Port am router öffnen muss ?


Ganz genau. Ich kann vor allem SSL-Offloading verwenden und kann meine Zertifikate, die Benutzerauthentifizierung etc. zentral pflegen (gemeinsam für smartVISU, FHEM und andere Dienste). Das kann ich entweder im Nginx machen oder nochmals davorgelagert auf meiner pfSense (HAproxy) für den Zugriff von außen.


Durch den dynamischen Hostnamen und Port bin ich nicht an die feste Vorgabe aus der smartVISU config.ini gebunden, sondern der Browser entscheidet welchen Servernamen und welchen Port er anspricht - nämlich einfach das selbe wie für die Website auch.


Ich bin gerade auch dabei eine Userverwaltung zusammenzustellen, die eine zentrale, Webformular-basierte Authentifzierung sowohl für Fhem, smartVISU als auch eben gleichzeitig den fronthem Websocket Dienst bereitstellt. Eine schmale Variante tut auch schon, kann bisher aber nicht mehr als mehreren Usern den generellen Zugriff auf die Backend Systeme zu gewähren oder zu verweigern. Ich möchte da noch nach der URI unterscheiden können. Beispielsweise sollen alle auf /smartvisu (und die /ws Websocket URI) zugreifen dürfen, auf /fhem aber nur ein Admin. Außerdem soll der Zugriff aus dem LAN ohne Authentifizierung funktionieren, aus dem Internet muss sich aber generell immer authentifiziert werden.
Auch SSL Zertifikate kann man dafür dann verwenden. Das ganze ohne den Code von Fhem, smartVISU oder fronthem anzufassen. Wenn sich an den Sicherheitsbedingungen etwas ändert (geknackte Verschlüsselungsalgorythmus, TLS Protokollversion etc), dann kann ich diese Einstellungen ganz zentral an nur einer einzigen Stelle (=SSL Offloading) vornehmen und kann mir sicher sein, dass dies für alle dahinter gelagerten Systeme keine Rolle mehr spielt.


Zitat von: herrmannj am 08 August 2016, 12:35:58
Wenn fronthem einen port für http(s)/ws(s) ermöglichen würde dann würde das die Komplexität doch erhöhen (kein rocket science, aber auch nicht ganz trivial) was im Regelfall mehr Fehlermöglichkeiten (mehr debugging) nach sich zieht.

Gibt es zwingende Gründe die dafür sprechen ?


Ich glaube der Aufwand ist eher höher und die Installation wird dadurch auch nicht einfacher. Man kann auch heute schon mit einem SSLwrapper wie stunnel unter Linux einfach den Port 2121 mit einer TLS Verschlüsselung versehen und z.B. auf Port 2122 hören lassen. Das bringt aber eben kaum etwas, weil es nach wie vor den zweiten Port für die Funktion braucht und keiner der Vorteile von oben greift.


Die abgestuften Zugriffe in fronthem habe ich abgeschaltet, da ich zwischen einzelnen Usern so nicht unterscheiden brauche bei mir.
Ich habe u.a. dafür und auch weiteren Funktionen wie z.B. einer verbesserten GAD Verwaltung bereits einen Patch vorbereitet, von dem ich eine erste Version später mal zum ausprobieren rüberreichen möchte.




Gruß
Julian
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

Loredo

Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

herrmannj

Native geht https und damit wss noch nicht.

Über den Revers Proxy kann das nur gehen wenn der die Ursprungs IP meldet. Sonst abwarten und von benutzen.

vg
joerg

Loredo

Nativ muss es auch gar nicht gehen, das hier ist eine reine Zusatzfunktion on top für den, der es will und dann weiß wie es geht.

Aber da du dir hier keine Mühe gemacht hast dir das vorzustellen und diesen Mini-Patch blockierst:
https://github.com/Martin-Gleiss/smartvisu/pull/102
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

herrmannj

Ne, blockieren will ich nichts. Fronthem war ein Test, es hat Design Schwächen. Ich hab den aus den Augen verloren und nehme dir einen Reminder nicht übel. Übernehme ich gern.

Was ich vermeiden möchte ist das da jemand viel Herzblut reinsteckt.

Sorry!

Vg
Joerg


Loredo

Ok, die Absicht erscheint ehrenwert. Der Eindruck, der hier ankommt ist jedoch: Niemand außer dir kann das deiner Meinung nach (richtig) implementieren. Eine andere Erklärung erschließt sich mir jedenfalls nicht, weshalb du quasi sagst "geduldet euch" wenn du mit Menschen sprichst, die durchaus in der Lage sind etwas beizutragen. Du versuchst das mit Höflichkeit beiseite zu wischen, aber wie beschrieben kommt es (bei mir) anders an.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER