S3 Interception Proxy

Vor ein paar Tagen habe ich mir für meinen Energieüberschuss auf Empfehlung von bis dahin zwei Kollegen eine Zendure 1600 AC+ gekauft. Eigentlich wollte ich mir meinen Speicher selbst bauen, aber man muss ja nicht für alles das Rad neu erfinden. Nun ist es leider so, das man die Kiste nur mit dem in der Firmware hinterlegten MQTT Broker verbinden kann. Meine Meinung zu Home-Automation ist strikt. Das Wort steckt schon im Begriff, nämlich „Home“. In diesem Zusammenhang kann ich mit dem ganzen IoT und Cloud Wahn überhaupt nichts anfangen. Es ist ja schließlich auch noch niemand auf die Idee gekommen, das eigene Stromkabel zu Hubel-Heiner-Butzenbach den ich mal Bernd nenne und der zwei Straßen weiter wohnt zu legen, dort in einen Schaltkasten, und von dort wieder zurück. Um den eigenen Treppenhausautomaten dort unterzubringen, damit Bernd immer schauen kann wann ich in den Keller gehe und das zu protokollieren. Der Clou an Bernd und anderen Anbietern wie Shelly, Bosch, Zendure uvm. ist, das man sich seine live Daten anschauen kann (Ahhh das Licht ist an!) die Historischen Daten aber in Bernds Tresor landen, und mir diese nicht frei zur Verfügung stehen. Wie wenn das Bernds und nicht meine Kellergänge gewesen wären. Und wenn der Bernd glaubt, nicht genug dran zu verdienen, oder keine Lust mehr hat, schaltet er einfach meinen Treppenhausautomaten ab. Bernd argumentiert dann: Trotz aller Bemühungen und des innovativen Konzepts wurde nicht die für einen wirtschaftlichen Weiterbetrieb erforderliche Marktakzeptanz erreicht!

Wo war ich stehen geblieben? Ah ja, wer sagt denn, das ich meinem Server in meinem lokalen Netzwerk nicht den alias mqtt-eu.zen-iot.de geben kann und somit die Zendure 1600 AC+ mit meinem MQTT spricht?! Das eine nennt man Spoofing und das andere Hijacking was garnichtmal so trivial ist.

Da ich das nicht über meinen Linux Server lösen, dort Sicherheitslöcher aufreißen und etliche vorhandene, funktionierende Sachen verbiegen wollte, habe ich mich für einen anderen Weg entschieden. In meiner Bastelbox liegen seit ein paar Tagen zwei brandneue ESP32 S3 DevKit1 R16N8. Mit 16MB Flash und 8MB PSRAM haben die um einiges mehr Ressourcen als meine bisherigen. Sollte also für eine TCP-Bridge reichen.

Also erst mal schauen was alles von Zendure erwartet wird. HTTP Token (TCP), MQTT (TCP), NTP (UDP) oha. Ohne Uhrzeit lässt sich die 1600 AC+ nicht regeln.

Erst mal mit dem Programmieren anfangen. Zunächst einmal einen Accesspoint mit WPA aufspannen. Zum Testen auf 192.168.4.1 (default) und über das Webinterface auf Port 8080 konfigurierbar machen. Dann nach SSIDs scannen und das Zielnetzwerk einstellbar machen. Zudem die Target IP also mein persönlicher Server einstellbar machen. Zum Testen wird die 192.168.1.10 verwendet. Zur Sicherheit habe ich eine Whitelist eingebaut. Nur erlaubte Domains dürfen auf meinen Server. Um das zu prüfen musste noch ein Log ins Interface. Dann noch DNS und TCP einbauen.

Was passiert nun? Der Client meldet sich am ESP32 Accesspoint an, bekommt den Gateway und den DNS 192.168.4.1 sowie eine freie IP in diesem Netzwerksegment. Wenn der Client nun beim DNS nach der IP von Beispielsweise google.com fragt, bekommt er die 192.168.4.1 zurück insofern die Domain in der Whitelist ist. Intern werden die Pakete über die TCP-Bridge welche die WIFI Klasse mitbringt an die Target-IP weitergeleitet, und von da die Antwort zurück.

Funktioniert astrein.

Bei NTP schaut die Sache nun anders aus. Das User Datagram Protocol (UDP) hat zwar einen Header, aber dieser beinhaltet keine Quell und Zieladressen. Die werden eine Schicht darüber im IP-Header geführt. Das ist in meinem Fall ein Problem. Der Client schickt die Anfrage zur .4.1 wo es ausgepackt wird. Hier sieht mein Proxy das es eine NTP Anfrage auf Port 123 ist. Dieses kann ich nehmen, und auf der anderen Seite wieder als UDP an meinen Server, den Router oder einen anderen NTP-Server schicken welcher mit der Uhrzeit antwortet. Da aber der ESP32 vergessen hat von wem die Anfrage gekommen ist, endet der Rückweg hier. Es muss ein simuliertes abgespecktes Network Address Translation (NAT) her. Also habe ich eine Funktion für NAT-light eingebaut. Das hat soweit geklappt, benötigt aber viele Ressourcen und bremst den Proxy aus. Zudem ist das System unzuverlässig sobald zwei Clients UDP anfragen stellen, da der eine den anderen im schlechten Fall überschreibet. Also habe ich rumgekämpft, die NAT-Funktion weiter aufgeblasen um das System noch langsamer zu machen. Hat mir alles nicht gefallen. Beim drüber schlafen habe ich mir die Sache nochmal durch den Kopf gehen lassen. Wenn doch der Client eh nur die .4.1 sieht, dann kann er doch von da auch die Urzeit bekommen. Und so läufts. Der ESP32 holt sich beim Boot und in regelmäßigen Abständen die Uhrzeit bei de.pool.ntp.org und stellt sie selbst als NTP zur Verfügung.

  • Bernd, wenn du dich persönlich angegriffen fühlst, möchte ich mich dafür entschuldigen. Der Name ist Rainer Zufall! Äh nein Rainer, nicht ganz. Welches international agierende Unternehmen mit dem Hang zur Verlagerung beginnt nochmal mit dem gleichen Buchstaben?
  • Warum nicht direkt NAT verwenden. Weil die Klasse gekapselt ist, und Eingriffe wie ich sie benötige nicht hergibt ohne diese umzuschreiben.
  • NTP beinhaltet nicht nur die Uhrzeit. Uhrzeit war aber einfacher zu schreiben.
  • Es ist zu erwähnen das google.com für meine ersten Tests die schlechtmöglichste Wahl war. Aber man lernt nie aus. Moderne Browser sind sogenannte HSTS Browser. Beim Aufruf einer Website kann diese dem Browser mitteilen, das zukünftig oder für eine gewisse Zeit der Verbindungsaufruf auf eine andere Adresse umgeändert wird. Es ist gar nicht so einfach dem Browser zu sagen das er bei google.com nicht https://www.google.com/?hl=de aufrufen soll.

Schreibe einen Kommentar