MQTT2 für Worx Landroid Mähroboter

Begonnen von Otto123, 09 Juni 2020, 13:55:43

Vorheriges Thema - Nächstes Thema

frober

Genau, es wurde von User/Passwort auf Token und Websocket secure umgestellt.

IoBroker funktioniert wieder und ich versuche das gerade hier nachzubauen, damit es wieder funktioniert.
Leider nicht so einfach...
Raspi 3b mit Raspbian Buster und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

Heatseeker


Jasimo

Moin,
gibts noch eine Implementierung die funktioniert? Mein Landroid ist, nach dem Winterschlaf, nicht mehr in FHEM funktional.  :-\

frober

Zitat von: Jasimo am 25 März 2023, 13:21:26Moin,
gibts noch eine Implementierung die funktioniert? Mein Landroid ist, nach dem Winterschlaf, nicht mehr in FHEM funktional.  :-\

https://forum.fhem.de/index.php?msg=1264477

Ich komme im Moment nicht weiter...
Raspi 3b mit Raspbian Buster und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

rudolfkoenig

Zitataber was kommt bei Origin hin, wir haben ja keine eigene Domain?  Das ist doch Domain vom Client?
Diese Allow-* Zeilen sind im HTTP-Header des Servers, und weisen den Browser an, bestimmte Sachen zu erlauben (Zugriff aus Javascript auf die Cookies, oder auf andere Webseiten).
Fuer die HttpUtils Funktionen sind diese Anweisungen irrelevant.
Wenn ich die Zeit finde zum Experimentieren: Gibt es eine Anleitung, was ich machen muss, um die Anmeldung selbst zu versuchen? Oder braucht man dafuer Hardware?

frober

#470
Zitat von: rudolfkoenig am 25 März 2023, 15:37:58
Zitataber was kommt bei Origin hin, wir haben ja keine eigene Domain?  Das ist doch Domain vom Client?
Diese Allow-* Zeilen sind im HTTP-Header des Servers, und weisen den Browser an, bestimmte Sachen zu erlauben (Zugriff aus Javascript auf die Cookies, oder auf andere Webseiten).
Fuer die HttpUtils Funktionen sind diese Anweisungen irrelevant.
Wenn ich die Zeit finde zum Experimentieren: Gibt es eine Anleitung, was ich machen muss, um die Anmeldung selbst zu versuchen? Oder braucht man dafuer Hardware?

Danke für das Angebot, Hardware ist nicht nötig, nur der Zugang und die Benutzerdaten. Kann ich die zur Verfügung stellen.

Soweit ich gelesen habe, kann der Client mit Origin = eigeneDomain oder * beim Server anfragen, ob die Unterstützung vorhanden ist. Evtl. ist noch url
Host nötig. Bisher waren meine Anfragen aber ohne Erfolg.

Aktuell habe ich den Entwickler der DeskApp angeschrieben. Er ist fast soweit, dass es wieder funktioniert und verwendet die SDK auch nicht. Mal sehen ob er bereit ist zu antworten...

Notfalls Frage ich noch bei Positec an, da ich nicht weiß was der Server fordert. Laut AWS gibt es viele Möglichkeiten und aus der SDK wurde ich bisher nicht schlau.

P.S. den axios Code habe ich mir auch angesehen, da wird zusätzlich zum http request XMLHttpRequest verwendet und das hat die Funktion withcredentials.
Raspi 3b mit Raspbian Buster und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

frober

#471
Hallo Rudi,

bezgl. API connect, bin ich mir nicht sicher ob ich das überhaupt benötige. Der Token refresh aktualisiert anscheinend nur die MQTT Verbindung.

Daher habe ich erstmal wieder die Verbindung zum MQTT Server getestet, müsste hier mit wss nicht erst der Wechsel auf Websocket angefragt und dann der Websocketheader zur Authentifizierung gesendet werden?
Mich wundert, dass der response Header immer gleich ist...

Laut Log wird der Websocket-Header mit dem Token bei der Anfrage gesendet, dann auf Websocket gewechselt. Es folgt dann nur ein Loginversuch mit der cliendId:
2023.03.26 12:45:46 5: HttpUtils url=https://iot.eu-west-1.worxlandroid.com:443/ NonBlocking via https
2023.03.26 12:45:47 4: IP: iot.eu-west-1.worxlandroid.com -> 34.252.173.127
2023.03.26 12:45:47 5: HttpUtils request header:
GET / HTTP/1.1
User-Agent: fhem
Accept-Encoding: gzip,deflate
Connection: Upgrade
protocol: wss-custom-auth
baseReconnectTimeMs: 5000
Sec-WebSocket-Key: FQ7pU0NSz4mQ9GaEZQRWjw==
clientId: android-xxx
host: iot.eu-west-1.worxlandroid.com
username: iobroker
Sec-WebSocket-Protocol: mqtt
customAuthHeaders: {
                        "x-amz-customauthorizer-name": "com-worxlandroid-customer",
                        "x-amz-customauthorizer-signature": "xxx",
                        jwt: "xxx.xxx,
                        }
Sec-WebSocket-Version: 13
region: eu-west-1
Upgrade: websocket

2023.03.26 12:45:47 4: https://iot.eu-west-1.worxlandroid.com:443/: HTTP response code 101
2023.03.26 12:45:47 5: HttpUtils https://iot.eu-west-1.worxlandroid.com:443/: Got data, length: 0
2023.03.26 12:45:47 5: HttpUtils response header:
HTTP/1.1 101 Switching Protocols
content-length: 0
upgrade: websocket
connection: upgrade
sec-websocket-accept: 6BR6nnFSkFcop27qN/U2kPmBZic=
sec-websocket-protocol: mqtt
2023.03.26 12:45:47 5: MQTT2_Worx: sending CONNECT (16)9(0)(4)MQTT(4)(2)(3)(232)(0)-android-xxx(10)
2023.03.26 12:45:47 5: DevIo_SimpleWrite MQTT2_Worx: 10390004xxx061360a
2023.03.26 12:45:47 1: wss:iot.eu-west-1.worxlandroid.com:443 reappeared (MQTT2_Worx)
2023.03.26 12:45:47 5: Websocket msg: OP:8 LEN:0 MASK:0 FIN:1
2023.03.26 12:45:47 5: Websocket close, reason:

Wenn ich den ioBroker richtig verstehe wird der WS-Header im Header als Json mit gesendet:

Zitatthis.mqttC = awsIot.device({
                clientId: `${this.clouds[this.config.server].mqttPrefix}/USER/${this.userData.id}/iobroker/${uuid}`,
                username: "iobroker",
                protocol: "wss-custom-auth",
                host: mqttEndpoint,
                region: region,
                customAuthHeaders: headers  //const headers = this.createWebsocketHeader();
                baseReconnectTimeMs: 5000,
            });


createWebsocketHeader() {
        const accessTokenParts = this.session.access_token.replace(/_/g, "/").replace(/-/g, "+").split(".");
        const headers = {
            "x-amz-customauthorizer-name": "com-worxlandroid-customer",
            "x-amz-customauthorizer-signature": accessTokenParts[2],
            jwt: `${accessTokenParts[0]}.${accessTokenParts[1]}`,
        };
        return headers;


Nachtrag:
Gerade mit einer Kopie vom Client ohne gesetzten Header getestet, gleicher response Header und wechsel auf Websocket erfolgt auch:
2023.03.26 13:49:42 5: MQTT2_Worx_Test: discarding DISCONNECT (224)(0)
2023.03.26 13:49:51 5: HttpUtils url=https://iot.eu-west-1.worxlandroid.com:443/ NonBlocking via https
2023.03.26 13:49:51 4: IP: iot.eu-west-1.worxlandroid.com -> 52.18.132.86
2023.03.26 13:49:51 5: HttpUtils request header:
GET / HTTP/1.1
Host: iot.eu-west-1.worxlandroid.com
User-Agent: fhem
Accept-Encoding: gzip,deflate
Sec-WebSocket-Protocol: mqtt
Connection: Upgrade
Sec-WebSocket-Key: Ln2i8Qi6c1xoOsk+68EsHQ==
Sec-WebSocket-Version: 13
Upgrade: websocket

2023.03.26 13:49:51 4: https://iot.eu-west-1.worxlandroid.com:443/: HTTP response code 101
2023.03.26 13:49:51 5: HttpUtils https://iot.eu-west-1.worxlandroid.com:443/: Got data, length: 0
2023.03.26 13:49:51 5: HttpUtils response header:
HTTP/1.1 101 Switching Protocols
content-length: 0
upgrade: websocket
connection: upgrade
sec-websocket-accept: WuceeZXGGJwUHYUbI17e9cvz1xg=
sec-websocket-protocol: mqtt
2023.03.26 13:49:51 5: MQTT2_Worx_Test: sending CONNECT (16)9(0)(4)MQTT(4)(2)(3)(232)(0)-android-xxx(10)
2023.03.26 13:49:51 5: DevIo_SimpleWrite MQTT2_Worx_Test: 1039000xxx5303061360a
2023.03.26 13:49:51 1: wss:iot.eu-west-1.worxlandroid.com:443 reappeared (MQTT2_Worx_Test)
2023.03.26 13:49:51 5: Websocket msg: OP:8 LEN:0 MASK:0 FIN:1
2023.03.26 13:49:51 5: Websocket close, reason:
Raspi 3b mit Raspbian Buster und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

rudolfkoenig

ZitatDanke für das Angebot, Hardware ist nicht nötig, nur der Zugang und die Benutzerdaten. Kann ich die zur Verfügung stellen.
Ja bitte, oder mir beschreiben, wie/wo ich selbst was anlegen kann.


ZitatWenn ich den ioBroker richtig verstehe wird der WS-Header im Header als Json mit gesendet:
Kannst Du mir die Quelle dieses Codestuecks zeigen?

frober

#473
Zitat von: rudolfkoenig am 26 März 2023, 17:38:32
ZitatDanke für das Angebot, Hardware ist nicht nötig, nur der Zugang und die Benutzerdaten. Kann ich die zur Verfügung stellen.
Ja bitte, oder mir beschreiben, wie/wo ich selbst was anlegen kann.

https://id.worx.com/login
Fürs Testen sollte das reichen, um Daten zu empfangen, müsstest du natürlich einen Mäher registrieren.
Für meinen Account müsstest du mir mittteilen, wie ich sie dir senden kann.

Die clietId kannst du dir, wie unter #1 beschrieben generieren:
attr MQTT_Worx autocreate simple {my $uuid=substr(genUUID(),0,36);;fhem("attr MQTT_Worx clientId android-$uuid")}
Zitat
ZitatWenn ich den ioBroker richtig verstehe wird der WS-Header im Header als Json mit gesendet:
Kannst Du mir die Quelle dieses Codestuecks zeigen?

Aus main.js habe ich soweit alles "abgeschrieben".
https://github.com/iobroker-community-adapters/ioBroker.worx/blob/master/main.js

und noch meine aktuelle Sub, Debug habe ich drin gelassen aber aus kommentiert
sub connectWorx
{
    #my $file = 'Landroid.log';
   
    my $hash = 'WorxTest';
    #my $def = shift;
    #my $name = $hash->{NAME};
    my $param = {
                    url        => "https://id.eu.worx.com/oauth/token",
                    timeout    => 5,
                    hash       => $hash,
                    method     => "POST",
                    header     => "User-Agent: TeleHeater/2.2.3\r\nAccept: application/json\r\ncontent-type: application/json\r\naccept-language: de-de",
            data       => '{"client_id": "150da4d2-bb44-433b-9429-3773adc70a2a","username": "xxx@xxx.de","password": "xxx!","scop": "*","grant_type": "password"}',
                    callback   => \&WorxApiRequest
                };
    #debuglog("data: ".$param->{data}, $file);

    HttpUtils_NonblockingGet($param);
}

sub WorxApiRequest($)
{
    my $param = shift;
    my $err = shift;
    my $data = shift;
    my $hash = $param->{hash};
    #my $header = $param->{httpheader};
    my $name = 'Landroid';
   
    #my $file = 'Landroid.log';
   
    #debuglog("WorxApiRequest", $file);
    #debuglog("\nheader: $header\nAuth: $param->{auth}", $file);
   
    #return debuglog("Abbruch Test", $file);

    if($err ne "")                                                                                                       # wenn ein Fehler bei der HTTP Abfrage aufgetreten ist
    {
    #debuglog("error while requesting from token ".$param->{url}." - $err", $file);
        Log3 $name, 3, "error while requesting ".$param->{url}." - $err";                                               # Eintrag fürs Log
        #readingsSingleUpdate($hash, "fullResponse", "ERROR", 0);                                                        # Readings erzeugen
    }

    elsif($data ne "")                                                                                                   # wenn die Abfrage erfolgreich war ($data enth? die Ergebnisdaten des HTTP Aufrufes)
    {
    #debuglog("url ".$param->{url}." returned: $data", $file);
        Log3 $name, 3, "url ".$param->{url}." returned: $data";                                                         # Eintrag fürs Log

        my @array = ();
        push @array, $data =~ /token_type.:.([^"]+).*expires_in.:([^"]+),.*access_token.:.([^"]+).*refresh_token.:.([^"]+)/gis;  # Token etc. aus Json auslesen
       
        #debuglog("\ntokentyp: $array[0] \nAblauf: $array[1] \naccess: $array[2] \nrefresh: $array[3]", $file);
       
        $hash = { hash => $hash, data => $data};
       
        my $param = {
                    url        => "https://api.worxlandroid.com/api/v2/users/me",
                    timeout    => 5,
                    hash       => $hash,
                    method     => "GET",
                    header     => "Host: api.worxlandroid.com\r\nOrigin: '*'\r\naccept: application/json\r\ncontent-type: application/json\r\nuser-agent: TeleHeater/2.2.3\r\naccept-language: de-de\r\nauthorization: $array[0] $array[2]",
            callback   => \&WorxMQTTlogin
                };
    #debuglog("param: $param->{header}", $file);

    HttpUtils_NonblockingGet($param);
    }
   
return;
}


sub WorxMQTTlogin($)
{
    my $param = shift;
    my $err = shift;
    my $data = shift;
    my $hash = $param->{hash};
    my $data2 = $hash->{data};
    $hash = $hash->{hash};
   
    my $header = $param->{httpheader};
   
    my $name = 'Landroid';
   
    #my $file = 'Landroid.log';
   
    #debuglog("WorxMQTTlogin", $file);
    #debuglog("\nheader: $header\nAuth: $param->{auth}", $file);
   
    #return debuglog("Abbruch Test", $file);

    if($err ne "")                                                                                                       # wenn ein Fehler bei der HTTP Abfrage aufgetreten ist
    {
    #debuglog("error while requesting from API".$param->{url}." - $err", $file);
        Log3 $name, 3, "error while requesting ".$param->{url}." - $err";                                               # Eintrag fürs Log
        #readingsSingleUpdate($hash, "fullResponse", "ERROR", 0);                                                        # Readings erzeugen
    }

    elsif($data ne "")                                                                                                   # wenn die Abfrage erfolgreich war ($data enth? die Ergebnisdaten des HTTP Aufrufes)
    {
    #debuglog("url ".$param->{url}." returned: $data", $file);
        Log3 $name, 3, "url ".$param->{url}." returned: $data";                                                         # Eintrag fürs Log

        my @array = ();
       
        push @array, $data =~ /message.:.([^"]+).*code.:.([^"]+)/gis;
        return debuglog("\nmessage: $array[0] \ncode: $array[1]", $file) if($array[0] ne "");
       
        #return debuglog("Abbruch Test", $file);
       
        push @array, $data2 =~ /token_type.:.([^"]+).*expires_in.:([^"]+),.*access_token.:.([^"]+).*refresh_token.:.([^"]+)/gis;  # Token etc. aus Json auslesen
       
        #debuglog("\ntokentyp: $array[0] \nAblauf: $array[1] \naccess: $array[2] \nrefresh: $array[3]", $file);
       
        $array[2] =~ s/[_]/\//g;                    # im Token _ durch / ersetzen
        $array[2] =~ s/[-]/+/g;                        # im Token - durch + ersetzen
        my @token = split(/\./,$array[2]);            # Token beim . splitten
       
        #debuglog("\nTeil 1: $token[0] \nTeil 2: $token[1] \nTeil 3: $token[2]", $file);
       
        #my $header = "x-amz-customauthorizer-name:com-worxlandroid-customer x-amz-customauthorizer-signature:$token[2] jwt:$token[0].".".$token[1]" # websocket header erstellen für MQTT2_CLIENT
        my $wssHeader = qq({
                        "x-amz-customauthorizer-name": "com-worxlandroid-customer",
                        "x-amz-customauthorizer-signature": "$token[2]",
                        jwt: "$token[0].$token[1]"
                        });
                         
        #debuglog("MQTT WSS Header: $wssHeader", $file);
       
        $defs{MQTT2_Worx}{header} =  { "clientId" => "android-xxx", "username" => "iobroker", "protocol" => "wss-custom-auth", "host" => "iot.eu-west-1.worxlandroid.com", "region" => "eu-west-1", "customAuthHeaders" => $wssHeader, "baseReconnectTimeMs" => 5000};
       
        #debuglog("MQTT Header: $defs{MQTT2_Worx}{header}", $file);
        # return fhem ("attr MQTT2_Worx HttpHeader $header; set MQTT2_Worx connect; defmod at_reconnect at $array[1]-100 {refrechToken()}");
       
        return fhem('set MQTT2_Worx connect');

        #readingsSingleUpdate($hash, "fullResponse", $data, 0);                                                          # Readings erzeugen
    }
return;   
}
Raspi 3b mit Raspbian Buster und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

frober

Der Entwickler der Deskapp hat mir geantwortet:
ZitatLetztendlich kann man mit dem Access-Token (3 Teile) eine direkte Mqtt-Verbindung über Port 443 erstellen, wenn der MqttClient TLS1.2 und zusätzlich AWS, jwt und ALPN unterstützt.
Den Umweg über die API benötigen wir also doch nicht.

TLS1.2 -> sollte passen
AWS    -> vermutlich 'Amazon Web Service', bzw. die Spezifikation!?  https://docs.aws.amazon.com/iot/latest/developerguide/mqtt.html Da MQTT vor der Umstellung schon funktioniert hat, sollte das vermutlich auch passen.
jwt       -> Json Web Token https://jwt.io/introduction, das habe ich in der Sub
ALPN   -> ? (Der Zusatz "mqtt" war das Schwierige bei der Deskapp ohne SDK)

@Rudi, gibt es hier noch Handlungsbedarf?
Raspi 3b mit Raspbian Buster und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

rudolfkoenig

AWS:
ich habe die verlinkte Doku durchgeflogen, und sehe keine Probleme

jwt:
keine Ahnung, wo man den Token setzen soll, wenn man "plain" MQTT macht, und auf WebSocket verzichtet.

alpn:
AWS Doku dazu: https://aws.amazon.com/blogs/iot/mqtt-with-tls-client-authentication-on-port-443-why-it-is-useful-and-how-it-works/
Dass man per TLS kann den Protokoll aussuchen kann, war mir neu.
Mir ist noch nicht klar, wozu wir alpn machen sollten: 8883 ist offen, und wir sind nicht hinter einem Corporate Firewall.
Wie auch immer, man sollte die mit Motivation nicht am Forschen hindern :)
Leider will SSL_alpn_protocols ein Array reference (siehe https://metacpan.org/pod/IO::Socket::SSL#SSL_alpn_protocols), deswegen musste ich HttpUtils.pm erweitern.
Um alpn fuer AWS zu nutzen, sollte man sslargs setzen bzw. erweitern:
define m2c MQTT2_CLIENT iot.eu-west-1.worxlandroid.com:443
attr m2c SSL 1
attr m2c sslargs SSL_alpn_protocols:x-amzn-mqtt-ca
Das reicht noch nicht, m2c kriegt kein MQTT CONNACK, Authentifizierung/etc fehlt.
Womoeglich funktioniert alpn auch nicht, ich kann es ja nicht wirklich testen.

frober

#476
Zitat von: rudolfkoenig am 31 März 2023, 18:19:39AWS:
ich habe die verlinkte Doku durchgeflogen, und sehe keine Probleme
Ok, danke.

Zitatjwt:
keine Ahnung, wo man den Token setzen soll, wenn man "plain" MQTT macht, und auf WebSocket verzichtet.
Das mache ich über den Websocket-Header in der Sub.
Zitatmy $wssHeader = qq({
                        "x-amz-customauthorizer-name": "com-worxlandroid-customer",
                        "x-amz-customauthorizer-signature": "$token[2]",
                        jwt: "$token[0].$token[1]"
                        });

Zitatalpn:
AWS Doku dazu: https://aws.amazon.com/blogs/iot/mqtt-with-tls-client-authentication-on-port-443-why-it-is-useful-and-how-it-works/
Dass man per TLS kann den Protokoll aussuchen kann, war mir neu.
Mir ist noch nicht klar, wozu wir alpn machen sollten: 8883 ist offen, und wir sind nicht hinter einem Corporate Firewall.
Wie auch immer, man sollte die mit Motivation nicht am Forschen hindern :)
Leider will SSL_alpn_protocols ein Array reference (siehe https://metacpan.org/pod/IO::Socket::SSL#SSL_alpn_protocols), deswegen musste ich HttpUtils.pm erweitern.
Um alpn fuer AWS zu nutzen, sollte man sslargs setzen bzw. erweitern:
define m2c MQTT2_CLIENT iot.eu-west-1.worxlandroid.com:443
attr m2c SSL 1
attr m2c sslargs SSL_alpn_protocols:x-amzn-mqtt-ca
Das reicht noch nicht, m2c kriegt kein MQTT CONNACK, Authentifizierung/etc fehlt.
Womoeglich funktioniert alpn auch nicht, ich kann es ja nicht wirklich testen.
Es wird MQTT over WSS benutzt auf Port 443.

Nochmals danke, leider funktioniert Websocket nicht mehr bei gesetztem
attr MQTT2_Worx sslargs SSL_version:TLSv12 SSL_alpn_protocols:x-amzn-mqtt-caVorsichtshalber habe ich noch TLS1.2 mit angegeben, wahrscheinlich nicht nötig.
maxNrConnects funktioniert auch nicht mehr, wenn ich das Attr hoch setze wird beim nächsten Versuch wieder angezeigt, dass die max Anzahl erreicht ist und es erfolgt kein connect.

Sorry, wenn ich dir Arbeit mache. Vielleicht bin ich mit meiner geringen Erfahrung auch der Falsche für diese Umstellung, aber ich denke es sind einige User die darauf warten, bis es wieder funktioniert.
Wie schon angeboten, würde ich dir meinen Account zum Testen "leihen", nur wie? Persönliche Nachrichten hast du verständlicher Weise blockiert...

Nachtrag:
Als Protokollname wird 'mqtt' verwendet
SSL_alpn_protocols:mqtt, laut meiner Info vom DeskApp-Entwickler.
Für MQTT over WSS ist bei AWS überhaupt kein Protokollname angegeben, deswegen habe ich ihn nochmals angeschrieben.
https://docs.aws.amazon.com/de_de/iot/latest/developerguide/protocols.html

Raspi 3b mit Raspbian Buster und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

frober

zur Info:

die DeskApp V0.31a ist verfügbar, dafür muss .NET Core 6.0 installiert werden

Raspi 3b mit Raspbian Buster und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

rudolfkoenig

ZitatNochmals danke, leider funktioniert Websocket nicht mehr bei gesetztem [...] SSL_alpn_protocols:x-amzn-mqtt-ca
WSS sollte auch nicht funktionieren, man bestellt ja mit SSL_alpn_protocols explizit "plain" MQTT, und damit nicht die Voreinstellung HTTP, was fuer Websocket die benoetigte "Vorstufe" ist. Insofern danke fuer die Bestaetigung, dass diese Option funktioniert.

alpn ist fuer direktes MQTT (d.h. ohne Websocket) gedacht, fuer den Fall dass man hinter dem Corporate Firewall ist, und die beschraenkte IT-Abteilung nur HTTPS (Port 443) nach aussen zulaesst. Es koennte zwar sein, dass AWS auch auf Port 443 mit alpn besteht, 8883 ist aber offen, und das spricht dagegen.

ZitatDas mache ich über den Websocket-Header in der Sub.
Das geht zwar, ist aber nicht mehr "plain" MQTT sondern MQTT over WebSocket, und man braucht dazu kein alpn.

ZitatWie schon angeboten, würde ich dir meinen Account zum Testen "leihen", nur wie? Persönliche Nachrichten hast du verständlicher Weise blockiert...
Email Adresse ist in dem Impressum hinterlegt.

frober

Zitat von: rudolfkoenig am 01 April 2023, 12:00:57
ZitatNochmals danke, leider funktioniert Websocket nicht mehr bei gesetztem [...] SSL_alpn_protocols:x-amzn-mqtt-ca
WSS sollte auch nicht funktionieren, man bestellt ja mit SSL_alpn_protocols explizit "plain" MQTT, und damit nicht die Voreinstellung HTTP, was fuer Websocket die benoetigte "Vorstufe" ist. Insofern danke fuer die Bestaetigung, dass diese Option funktioniert.

alpn ist fuer direktes MQTT (d.h. ohne Websocket) gedacht, fuer den Fall dass man hinter dem Corporate Firewall ist, und die beschraenkte IT-Abteilung nur HTTPS (Port 443) nach aussen zulaesst. Es koennte zwar sein, dass AWS auch auf Port 443 mit alpn besteht, 8883 ist aber offen, und das spricht dagegen.
Ich warte noch auf die Antwort von DeskApp Entwickler, aber im Forum hat er geschrieben, dass "MQTT over https by Postitec", also benutzerdefiniert verwendet wird.
Durch die ursprünglichen Infos habe ich mich zu sehr auf WSS konzentriert. 

Zitat
ZitatDas mache ich über den Websocket-Header in der Sub.
Das geht zwar, ist aber nicht mehr "plain" MQTT sondern MQTT over WebSocket, und man braucht dazu kein alpn.
Jetzt bin ich mir hier nicht mehr sicher, für MQTT müsste die Auth in die Url, bei Https würde es auch über den Header funktionieren. Bei MQTT over Https...?
Auf jedem Fall wird zuerst der Token und vermutlich auch die Bearbeitung von diesem benötigt.
Möglich, dass die Abfrage der API doch relevant ist, da hier noch eine userId empfangen wird.

Aus der Developerguide https://docs.aws.amazon.com/de_de/iot/latest/developerguide/custom-auth.html:
ZitatMQTT
Geräte, die AWS IoT Core über eine MQTT-Verbindung eine Verbindung herstellen, können Anmeldeinformationen über die password Felder username und von MQTT-Nachrichten weitergeben. Der username Wert kann optional auch eine Abfragezeichenfolge enthalten, die zusätzliche Werte (einschließlich eines Tokens, einer Signatur und eines Autorisierungsnamens) an Ihren Autorisierer übergibt. Sie können diese Abfragezeichenfolge verwenden, wenn Sie ein tokenbasiertes Authentifizierungsschema anstelle von username und password -Werten verwenden möchten.

Anmerkung
Die Daten im Passwortfeld sind base64-kodiert von AWS IoT Core. Ihre Lambda-Funktion muss es dekodieren.

Das folgende Beispiel enthält eine username Zeichenfolge, die zusätzliche Parameter enthält, die ein Token und eine Signatur angeben.
username?x-amz-customauthorizer-name=authorizer-name&x-amz-customauthorizer-signature=token-signature&token-key-name=token-value
Um einen Autorisierer aufzurufen, müssen Geräte, zuAWS IoT Core denen MQTT und benutzerdefinierte Authentifizierung eine Verbindung herstellen, über Port 443 eine Verbindung herstellen. Sie müssen außerdem die TLS-Erweiterung Application Layer Protocol Negotiation (ALPN) mit dem Wert von mqtt und die Erweiterung Server Name Indication (SNI) mit dem Hostnamen ihresAWS IoT Core Datenendpunkts übergeben. Um mögliche Fehler zu vermeiden, x-amz-customauthorizer-signature sollte der Wert für URL-codiert sein. Wir empfehlen außerdem dringend, dass die Werte vonx-amz-customauthorizer-name und token-key-name URL-codiert sind. Weitere Informationen zu diesen Werten finden Sie unter Kommunikationsprotokolle für Geräte. Die V2AWS IoTGeräte-SDKs, Mobil-SDKs und AWS IoT Geräteclient kann diese beiden Erweiterungen konfigurieren.

Zitat
ZitatWie schon angeboten, würde ich dir meinen Account zum Testen "leihen", nur wie? Persönliche Nachrichten hast du verständlicher Weise blockiert...
Email Adresse ist in dem Impressum hinterlegt.
Ok, danke.
Raspi 3b mit Raspbian Buster und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...