Aufbau eines internen Meshnets für meine RPi's

  • Moin,

    ich bräuchte mal eure Hilfe um auf ein paar Ideen zu kommen ;)
    Aktuell habe ich zwei RPi's im Betrieb. Einer steuert mein Licht und meine Rollladen und der
    Andere ist eigentlich nur für Hyperion zuständig. Bald soll allerdings noch ein weiterer Folgen, welcher sich um die Steuerung weiterer Lampen und Rollladen kümmern soll.
    Jeder RPi soll unabhängig von den anderen laufen sich aber dennoch mit diesen Synchronisieren.

    -Die Datenbank-
    Hier stehen die Rolllos und Lichter drin und auch, ob diese gerade an/aus bzw. oben/unten sind. Im Erstfall wird also ständig (immer wenn jemand auf den Lichtschalter drückt) etwas in die DB geschrieben.

    -Die Synchronisation-
    Synchronisiert werden muss eigentlich nur eine besagte SQLite Datenbank (aktuell 12K groß).
    Ich dachte mir, die Synchronisation über Bittorrent Sync zu verwirklichen, wobei fraglich ist, ob das Performance-Technisch klar geht.

    -Die Verbindung-
    Die RPis sollen sich Remote via TCP ansteuern lassen. Die Verbindung als solche soll natürlich gesichert sein, also via SSL/TLS verschlüsselt. Reicht das für einen sicheren Datenverkehr schon aus, oder wäre es sinnvoller die Pakete als solche noch via AES zu verschlüsseln?
    Dann bleibt noch die Frage, was passiert, wenn jemand die Pakete abfängt und erneuert an meinen RPi sendet. Darauf sollte er wenn möglich ja dann nicht reagieren. Wie verwirkliche sowas in der Theorie?
    Zudem soll jeder RPi, wenn er ein Paket bekommt, dass für einen anderen RPi gedacht ist an den entsprechenden weiterleiten. Hierzu könnte man die SQLite Datenbank benutzen, um Hostname, IP und Port fest zu halten.


    So, das war jetzt eine kleiner Vorgeschmack meiner Idee eins internen Meshnets. Meine Python Kenntnisse sollten hierfür ausreichen. Wenn Ihr Anregungen oder Bemerkungen habt, immer her damit ;)

  • Findest du das nicht etwas "oversized", für die Positionsverwaltung von ein paar Rollos und Lichtschaltern eine DB zu verwenden?

    Ich würde die Daten in ein (strukturiertes) Textfile schreiben, meinetwegen noch im JSON oder HTML Format, wobei eine einfache Tag/Value-Liste ausreichen sollte.
    Diese wird dann per rsync periodisch oder bei Zustandsänderung an alle anderen RPis kopiert (script). rsync kann verschlüsseln und hat noch viele andere Optionen, die das Backup z.B. am Timestamp des Files festmachen (also ob überschrieben wird oder nicht).

    Das Ganze ist natürlich daran gebunden, dass die Zeit auf allen RPis übereinstimmt, ntpd also zwingend nötig...

    also so würde ich das lösen...

    Mfg, Zen


  • Findest du das nicht etwas "oversized", für die Positionsverwaltung von ein paar Rollos und Lichtschaltern eine DB zu verwenden?

    Nachdem wir Datenbanken in der Schule hatten war ich einfach total begeistert davon :D
    Aber klar, Textfiles sind evtl. die bessere Wahl, vermutlich auch, was die Performance angeht.

    Zwischenzeitlich kam mir die Idee, dass nicht jeder immer die aktuelle DB bzw. DB-Files haben
    muss, sondern es würde ja reichen, einen 'Master' zu haben, welcher sich anhand der höchsten MAC identifiziert. Dieser hat dann immer die aktuellen Daten. Via rsync (danke für den Vorschlag :thumbs1:) kann man dann die Daten jede Minute zu den anderen RPi's kopieren. Falls der Master ausfallen sollte, wird der mit der nächst hören Mac Master. Wenn der alte Master wieder online ist, wird dieser wieder Master usw...

    Macht das Sinn? Oder eher nicht?


  • Nachdem wir Datenbanken in der Schule hatten war ich einfach total begeistert davon :D

    :lol: Klar: "Wer nur einen Hammer hat, sieht überall Nägel" :lol: :lol:


    Zwischenzeitlich kam mir die Idee, dass nicht jeder immer die aktuelle DB bzw. DB-Files haben muss, sondern es würde ja reichen, einen 'Master' zu haben, welcher sich anhand der höchsten MAC identifiziert. Dieser hat dann immer die aktuellen Daten. Via rsync (danke für den Vorschlag :thumbs1:) kann man dann die Daten jede Minute zu den anderen RPi's kopieren. Falls der Master ausfallen sollte, wird der mit der nächst hören Mac Master. Wenn der alte Master wieder online ist, wird dieser wieder Master usw...

    Macht das Sinn? Oder eher nicht?

    Gute Idee!
    Bedenke aber auch das Rückfallszenario für die Daten: Der RPi mit der "höchsten" MAC "kommt wieder". Jetzt muss also der "neue" Alte erstmal rumfragen, wer aktuell der Chef ist und sich aufsyncronisieren... Es sollte also immer noch ein Token geben (ein File - wir brauchen den Timestamp), wo der aktuelle Chef drin steht... - mit einem Mechanismus, der das entsprechend setzt und in Fall eines Neustarts löscht...

    Aber das ist dann schon die "höhere' Kunst... mach es erstmal mit dem File und dem rsync :bravo2:

    Mfg, Zen

    Edit:
    Ach ja: http://sourceforge.net/projects/cryptcat/ wäre auch was, weil du ja von Verschlüsselung schriebst... (Warum eigentlich, ssl sollte doch im internen Netz reichen, wenn überhaupt... )

  • So, also aktuell sehen meine Überlegungen so aus:

    Ich habe 9 DB-Files:

    lights (alle ansteuerbaren Lampen stehen hier drin)

    Code
    #id;homecode;lightcode;zuständigerServer
    1;01100;2;tria

    lights_state (hier wird der aktuelle Status einer Lampe hinterlegt)

    Code
    #id;state
    1;on

    rolllos (alle ansteuerbaren Rolllos stehen hier drin und die Zeiten, wie lange diese
    zum hochfahren bzw. herunterfahren benötigen)

    Code
    #id;uptime;downtime;zuständigerServer
    1;20;24;prometheus

    server (alle vernetzten Server)

    Code
    #name;ip;port;mac;
    prometheus;10.1.1.5;10111;de-ad-be-ef-08-50
    tria;10.1.1.6;10111;de-ad-be-ef-08-51
    daedalus;10.1.1.7;10111;de-ad-be-ef-08-52

    syscommands (alle Befehle, die das System betreffen)

    Code
    #name;cmd
    reboot;sudo reboot
    shutdown;sudo poweroff

    services (alle 'Dienste', die unterstützt werden und ggf. ein Alternativserver)

    Code
    #name;alternativserver
    lights;daedalus
    rolllos;

    automatic (hier wird festgelegt, was wann passieren soll, ähnlich crontabs)

    Code
    #wochentag(e);zeit;cmd
    mo-fr;20:00;.lights.1.on


    master (hier steht der aktuelle Master drin)

    Code
    #name
    tria

    Funktioniert aktuell zwar, aber wird erst später dazu kommen.
    accdata (Accoutdaten für Kalender)

    Code
    #type;user;pass;url
    caldav;admin;Baumhausplantage;http://doofescaldavmodulfuerpython.com/default

    zu den Befehlen:
    Diese werden via SSL/TLS und TCP an den jeweiligen Server übertragen.
    (Ohne weitere Verschlüsselung.)
    Aufbau: server.dienst.arg1.arg2
    Lässt man den Server weg, so soll der in der DB eingetragene Server genutzt werden
    (siehe Ablaufdiagramm).
    Beispiele:
    tria.lights.1.on
    prometheus.rolllos.1.up
    daedalus.sys.reboot

    Der Master is der Einzige, der die DB-Files bearbeiten darf.

    --------------------
    In diesem Zuge erst einmal danke an Zentris für die Hilfe ;)
    Soweit alles nachvollziehbar/sinnvoll/logisch?

    Ablaufdiagramm aus der Sicht eines Servers.

    Edit:
    - Gut wäre bei der Installation der Software einen Token ab zu fragen, damit nur diejenigen mit dem Token sich vernetzten. So hält man unbefugte Systeme raus. Der Token wird als sha512 in eine Tokendatei gespeichert,
    welche dann auch mit synchronisiert wird.
    - Evtl. wäre es auch sinnvoller den ersten Master manuell zu setzten und die Reinfolge der alternativen Masters festzulegen, oder derjenige, der am schnellsten antwortet oder am wenigsten Auslastung hat wird zum nächsten Master.

    Was wäre da wohl am Besten?

    Einmal editiert, zuletzt von Bananadini (29. Januar 2015 um 11:58)

  • Hm, 9 DB Files....
    Ich persönlich hätte das in EINE strukturierte Datei geschrieben in der Art (hier nur ein paar Daten von deinen mal reingegeben) :

    Das ist JSON, ich hoffe, alle Klammern richtig gesetzt zu haben... :D
    Dafür gibt es in Python Methoden, die das einlesen, verarbeiten und wieder rausschreiben. Ich hab das mal vor 6 Monaten auf Arbeit verwendet...

    Du kannst natürlich auch HTML oder was anderes nehmen, PYTHON hat auch ein "eigenes" Format, was so mit strukturierten Tag=Value Pairs und Sektionen arbeitet...

    Vorteil "von's Janze":
    Es wird nur eine Datei durch die Gegend transportiert (De-Synchronisierungsgefahr steigt mit der Anzahl der Files, die konsistent gehalten werden müssen).
    Diese Datei ist eigendlich auch schon eine Datenbank.

    Dein Zustandsdiagramm habe ich nur überflogen, auf den 1. Blick sehe ich keine Probleme.

    Auf ein extra Tokenfile (ja, ich hatte das vorgeschlagen) könnte man evtl. wieder verzichten, wenn man in die Datenbankdatei eine gesonderte Section einfügt, die einen Timestamp und den Chefservernamen enthält und folgendes Signalspiel implementiert:

    • Server 1 : legt die Datei an (oder bekommt das File händisch)
    • Server 1 : Austausch (Abfrage der anderen Server, ob Datei vorhanden und welcher Timestamp (TS), Vergleich der TS
    • Server 1 : Hat den höchsten (da die anderen Server keine Files haben) ==> ist Chef, Verteilung der Datei
    • Server 1 : nimmt Änderungen vor (nur er!), danach Aktualisieren des TS und erneute Verteilung
    • alle Server: alle 1 min "pingen" die Server 2 und 3 den Server 1 lt. ihrer Liste an, um Ausfälle zu erkennen.
    • Server 1 : ---down---
    • Server 2 : errechnet eine Zufallszahl und schickt sie an alle Server in der Liste
    • Server 3 : errechnet eine Zufallszahl und schickt sie an alle Server in der Liste
    • Server 2 und 3 vergleichen ihre Zahl mit der der anderen Server, der mit der niedrigsten (!) "gewinnt" und wird Chef (dann weiter ab dem 2. Punkt oben)
    • Server 1 : --- kommt wieder ---
    • Server 1 : er "sieht" sich (noch) als Chef, darf aber nix machen, muss einen "Broadcast" absenden an seine Serverliste, ob er noch Chef ist...
    • Server 1 : bekommt eine neue Datei, Erkennung, dass er nicht mehr Chef ist.... Unterordnung

    Hm, ob das trägt... Dein System sieht ja auch gut aus... also gilt (wie immer) "Versuch macht klug"...

    Mfg, Zen

  • JSON sieht sehr einfach aus und is es vermutlich auch...gekauft ;)
    Alles nochmal :angel:

    Wie ich den neuen Master ermittele ist erstmal nicht ganz so wichtig.
    Werde da glaub erst einmal mit einer statischen Liste arbeiten.
    Der Token fällt dann weg. Schade eig ;(

    Mein dem TS meinst du (sofern richtig verstanden) einfach eine Zahl, die bei jeder Änderung hochgezählt wird. Also nicht wirklich einen ZEIT-Stempel oder?

  • Also die Raspis sind zwar oversized für diese Aufgaben, aber andere Bastelgeräte, die eine solche Aufgabe erledigen können, z.B. Arduino Yun kosten inzwischen das dreifache eines Raspberry Pi A+. Ich finde das Projekt gut und werde hier aufmerksam mitlesen, weil bei mir inzwischen 3 Raspis rumliegen, die ich durch Geräte wie Arduino Yun, Banana Pi und Banana Pi Pro ersetzt habe. Da kann ich meine oversized Raspis für ein solches Projekt "opfern".

    Meine Boards: Raspberry Pi A, Raspberry Pi B, Raspberry Pi B+, Raspberry Pi 2 B, Banana Pi M1, Banana Pro, 3x Arduino Uno, Arduino Yun, Teensy 3.1 und bald den Raspberry Pi Zero

  • Also die Raspis sind zwar oversized für diese Aufgaben, aber andere Bastelgeräte, die eine solche Aufgabe erledigen können, z.B. Arduino Yun kosten inzwischen das dreifache eines Raspberry Pi A+. Ich finde das Projekt gut und werde hier aufmerksam mitlesen, weil bei mir inzwischen 3 Raspis rumliegen, die ich durch Geräte wie Arduino Yun, Banana Pi und Banana Pi Pro ersetzt habe. Da kann ich meine oversized Raspis für ein solches Projekt "opfern".

    Das "oversized" bezog sich auf den Einsatz einer DB zur Verwaltung von einer Handvoll Daten, nicht in Bezug auf die Verwendung eines (oder mehrerer) RPis...

    Die RPis sind m.E. ggü. in diesem Fall Arduinos kostenmäßig zumindest gleichwertig, sowie man ein Netzwerk benötigt und ausreichend Strom zur Verfügung steht... Die Datenerfassung machen die Teile nebenbei, weitere Aufgaben können da drauf gesetzt werden... - selbst die "alten" RPis
    :)

    BTW: man muss allerdings Arduinos nicht zwingend in der "Apotheke" oder anderen europäischen "Umschlagplätzen" kaufen, beim "Hersteller" in China kosten gleichwertige "Nachbauten" wesentlich weniger... wenn man die Lieferzeit aushält :)

    * die "*" bitte entsprechend interpretieren...
    * Nix gegen die A. aus C. ! Laufen bei mir wie geöhlt!

    Grüße ;) , Zen

  • Moin,

    ich muss zwischendurch noch für die Prüfung lernen, weshalb hier keine all zu schnellen Ergebnisse erwartet werden sollten. Anbei hab ich mal den Großteil der aktuellen Klassen gepackt (komplett in Python 3).

    Ich hab mich dazu entschieden die JSON-"Datenbank" nicht via rsync zu übertragen, sondern ebenfalls über TCP.
    Dann ist mir noch aufgefallen, dass JSON keinerlei Kommentare erlaubt. Evtl muss ich da dann noch auf Hjson umsteigen. Aber das hat Zeit.

    Wer Spaß dran hat kann mir mal bei der Datenbank-Übertragung helfen. Dort kommt es immer zu einem Timeout, nachdem die Datenbank übertragen wurde. Der Rest funktioniert soweit Fehlerfrei. Die Datei tcp_test_server.py ausführen um den Server zu starten und tcp_communication.py für den Client. SSL werd ich später implementieren.

    Wäre nice, wenn mir da jemand bei helfen kann ;)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!