Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. ioBroker Allgemein
  4. [Frage] PEM-Zertifikate in ioBroker importieren ohne Admin-GUI

NEWS

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    10
    1
    309

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    24
    1
    1.5k

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    9.4k

[Frage] PEM-Zertifikate in ioBroker importieren ohne Admin-GUI

Geplant Angeheftet Gesperrt Verschoben ioBroker Allgemein
14 Beiträge 6 Kommentatoren 4.1k Aufrufe
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • DutchmanD Online
    DutchmanD Online
    Dutchman
    Developer Most Active Administrators
    schrieb am zuletzt editiert von
    #5

    @daniel_2k:

    Die Idee ist gut und würde mir vollkommen ausreichen.

    Das Object system.certificates gibt es bei mir nicht.

    Wenn ich Systemobjekte in admin mit anzeigen lasse, sehe ich das object nicht.

    Im Screenshot von bluefox ist es zu sehen, aber bei mir ist das nicht vorhanden.

    Wie komme ich an das object ran? `

    sicher ? Ich musste auch 3 mal schaun aber hier steht das object:

    979_certificates.jpg

    1 Antwort Letzte Antwort
    0
    • D Offline
      D Offline
      daniel_2k
      schrieb am zuletzt editiert von
      #6

      Das mit dem Wald und den Bäumen :-) . Naja, man muss schon den Filter richtig setzen. Der Stand auf "state".

      Mit "config" oder "all" kommt man schon weiter.

      Danke für die Anregungen. Ich werde es mal probieren mit der Simple API es zu aktualisieren und den String in system.certificates zurück zuschreiben.

      1 Antwort Letzte Antwort
      0
      • DutchmanD Online
        DutchmanD Online
        Dutchman
        Developer Most Active Administrators
        schrieb am zuletzt editiert von
        #7

        @daniel_2k:

        Das mit dem Wald und den Bäumen :-) . Naja, man muss schon den Filter richtig setzen. Der Stand auf "state".

        Mit "config" oder "all" kommt man schon weiter.

        Danke für die Anregungen. Ich werde es mal probieren mit der Simple API es zu aktualisieren und den String in system.certificates zurück zuschreiben. `

        :lol: bist nicht der erste und ach nicht der letzte, schoen das es geholfen hat. Bin gespannt ob du es hinbekommst klinkt namelich gut deine loesungsrichtung !

        1 Antwort Letzte Antwort
        0
        • D Offline
          D Offline
          daniel_2k
          schrieb am zuletzt editiert von
          #8

          Ich werdes mal umsetzen und berichten.

          Mit getObject("system.certificates").native.certificates.defaultPrivate); kann ich jedenfalls sogar jedes einzelne Zertifikat ansprechen. Das sollte es sogar realtiv einfach machen.

          1 Antwort Letzte Antwort
          0
          • D Offline
            D Offline
            daniel_2k
            schrieb am zuletzt editiert von
            #9

            So, ich habe nun gebastelt. Es waren schon einige Hindernisse zu überwinden, aber ich habe eine funktionierende Lösung.

            Allerdings sind da ein paar Sachen, die mir noch nicht so gefallen.

            Im Detail:

            Ich nutze ioBroker auf einem Windows-Server, daher habe ich ein VBScript gebaut, welches das Zertifikate-Update in ioBroker durchführt (siehe Attachement). Das kann aber sicher auch für den Pi als Ansatz genutzt werden.

            Voraussetzungen:

            • in ioBroker zwei Datenpunkte (Zeichenketten), die die Strings der neuen PEM-Zertifikate aufnehmen. Bei mir „admin.0.certUpdate“ und „admin.0.keyUpdate“

            • laufende simpleAPI

            • JavaScript für das eigentliche Update der Zertifikate (siehe weiter unten)

            Ich habe zwei Varianten umgesetzt:

            1. Update der Datenpunkte über die simpleAPI

            Das Update der Datenpunkte habe ich über einen POST-Request mit "setValueFromBody“ umgesetzt, da ein Senden der Zeichenkette via GET-Parameter in der URL an Sonderzeichen wie "=" scheitert. Ich habe versucht die URL entsprechend zu kodieren und das "=" durch "%3D" zu ersetzen, aber die simpleAPI ignoriert das. Es kommt dann auch tatsächlich "%3D" im Datenpunkt an. Warum das URL-Encoding da nicht so funktioniert, weiß ich nicht. POST ist aber eh eleganter, wie ich finde.

            Also der Aufruf lautet dann:

            http://<server>:<port>/setValueFromBody/admin.0.certUpdate</port></server>
            

            Im Body wird dann der blanke String des Zertifikats geschrieben (ohne irgendwas dazu).

            Wichtig: der String muss die vorhandenen Zeilenumbrüche beibehalten, was aber in einem POST-Request problemlos klappt. Hier hätte man bei der GET-Methode das nächste Problem.

            2. Update der Datenpunkte über die ioBroker-Konsole

            Mit ioBroker state set admin.0.certUpdate "String" kann ich den Datenpunkt auch aktualisieren. Auch das funktioniert.

            Hier gibt's aber zwei Sachen, die ich umschiffen musste. Zunächst kann man als Kommandozeilenparameter keine Zeichenketten mit Zeilenumbruch übergeben. D.h. ich muss in meinen Zertifikats-String erstmal die Zeilenumbrüche (‚\n‘ und/oder ‚\r‘) in druckbare Zeichen umwandeln. In dem Fall habe ich die direkt in „\n“ und „\r“ umgewandelt, was kein Problem darstellt, da im PEM-Encoding kein Backslash vorkommt.

            Das zweite Problem ist, dass der String, den ich schreiben muss mit einem Minus ("-") beginnt. Das mag die Kommandozeile von ioBroker nicht (invalid value). Ich vermute, das hat mit dem Parsen der Argumente zu tun, da Parameter auch mit einem oder doppeltem Minus beginnen. Gelöst habe ich das durch ein Voranstellen eines Space e.g.

            C:\ioBroker\ioBroker state set admin.0.certUpdate " -----BEGIN RSA PRIVATE KEY-----\\nM…"
            

            Hier das Skript in ioBroker, welches dann die aktualisierten Datenpunkte in den „Zertifikate-Speicher“ schreibt:

            const CERTCONFIG = "system.certificates";      // Zertifikate-Konfiguration
            const DELAYTRIGGER = 1000;
            
            var locked = false;
            
            function updatePEMcert (certName, newCertValue)
            {
                // neuen PEM-Stringm erzeugen: Leerzeichen trimmen, druckbare Zeilenumbrüche in echte Umwandeln
                var newPEMString =  newCertValue.trim().replace(/\\r/g, '\r').replace(/\\n/g, '\n');    // neuer PEM-Zertifikat-String
            
                // Zertifikate-Config aus DB laden
                var certsConfig = getObject(CERTCONFIG);
                // Zertifikate aus Config
                var certs = certsConfig.native.certificates;
            
                // Update Key-Cert
                certs[certName] = newPEMString;
            
                // DB zurückschreiben
                setObject(CERTCONFIG, certsConfig, function (err) {
                    if (err) log('Cannot write object: ' + err);
                });
            }
            
            function wait(ms){
               var start = new Date().getTime();
               while(new Date().getTime() < start + ms);
            }
            
            // Trigger bei Update Key
            on({id: "admin.0.keyUpdate"/*keyUpdate*/, change: "ne"}, function (obj) {
                var timeout = 0;
            
                if (!locked) locked = true;
                else timeout = DELAYTRIGGER;
            
                // Verzögert ausführen, wegen zurückschreiben in DB und konkurrierenden Zugriff
                setTimeout(function () {
                    updatePEMcert("test key", obj.state.val);
                    if (timeout > 0 ) locked = false;
                }, timeout);
            });
            
            // Trigger bei Update Cert
            on({id: "admin.0.certUpdate"/*admin.0.certUpdate*/, change: "ne"}, function (obj) {
                var timeout = 0;
            
                if (!locked) locked = true;
                else timeout = DELAYTRIGGER;
            
                // Verzögert ausführen, wegen zurückschreiben in DB und konkurrierenden Zugriff
                setTimeout(function () {
                    updatePEMcert("test cert", obj.state.val);
                    if (timeout > 0 ) locked = false;
                }, timeout);
            });
            

            Das Skript macht im Wesentlichen Folgendes:

            Es stellt zwei Trigger für die beiden Datenpunkte bereit, auf denen ich das neue Zertifikat über die simpleAPI oder per Kommandozeile schreibe, die auf Änderung des Wertes reagieren.

            Anschließend werden Leerzeichen entfernt und die umgewandelten Zeilenumbrüche wieder in "echte" Zeilenumbrüche zurückgewandelt, damit der String auch korrekt im Zertifikate-Objekt geschrieben wird. Denkbar wäre hier noch eine Prüfung, ob die Strings korrekt mit Begin Certificate anfangen und mit End aufhören etc.

            Mit getObject hole ich mir die Zertifikate-Config, ändere dort mein Zertifikat und schreibe das Objekt wieder zurück (wichtig: setObject-Kommando muss im JavaScript-Adapter aktiviert sein!).

            Hier gibt es aber ein großes Problem, was ich zwar gelöst habe, aber nicht sehr elegant ist.

            Mit setObject kann ich das geänderte Objekt wieder in die Datenbank schreiben. Aber nachdem ich diese Funktion aufgerufen habe, ist das aktualisiert Objekt nicht sofort verfügbar.

            D.h. wenn ich nach einem setObject direkt danach wieder ein getObject mache, dann steht dort noch die alte Konfiguration vor dem Update drin. Ich habe nun herausgefunden, dass ein wenig Zeit nach setObject vergehen muss, bis man die zurückgeschriebenen Daten wieder mit getObject lesen kann.

            Das Problem entsteht dann nämlich durch das Updaten von dem zweiten Zertifikat durch den zweiten Trigger. Die Trigger werden sehr kurz hintereinander ausgeführt. Wenn der erste fertig ist, liest der zweite mit getObject die Zertifikate-Config wieder ein und schreibt das zweite Zertifikat zurück. Das erste ist aber da noch nicht enthalten, da wie gesagt einige Zeit vergehen muss. Dementsprechend ist immer nur das letzte Zertifikat aktualisiert worden.

            Gelöst habe ich das mit eine Art Lock-Mechanismus und einer verzögerten Ausführung (timeout), da es in JavaScript ja kein wait oder sleep gibt. Der erste Trigger wird sofort ausgeführt und der zweite verzögert, welcher dann auch das lock zurücksetzt. Nicht schön, geht aber. Ich bin kein JavaScript-Experte, vlt. kann man das auch besser schreiben.

            Frage wäre hier: warum ist nach setObject das geändert Object nicht sofort zugreifbar? Ich vermute, das da im Hintergrund was asynchron läuft, bis die Daten tatsächlich geschrieben sind und wieder gelesen werden können. Wäre natürlich toll, wenn setObject das berücksichtigt.

            Wenn jemand noch andere Ideen hat, das zu berücksichtigen, bin ich offen dafür.

            Mein VBScript startet dann noch den ioBroker neu. Alternative zum gesamten Neustarten des ioBrokers wäre auch das neu-Starten aller betroffenen Adapter.

            Das kann in einer kleinen Schleife, die alle Adapter in einem Array z.B. durchgeht und ein Systemaufruf macht passieren. Z.B.:

            C:\ioBroker\ioBroker restart web.0
            

            Das Neustarten der Adapter könnte aber auch ein Skript in ioBroker machen:

            obj = getObject("system.adapter.web.0"/*web*/);
            obj.common.enabled = true;
            setObject("system.adapter.web.0"/*web*/, obj);
            

            Das Ganze ist jetzt der erste Entwurf und wird sicher noch leben.

            Für weitere Ideen, Anregungen bin ich offen.
            2323_lecertupdate_iobroker.zip

            1 Antwort Letzte Antwort
            0
            • AlCalzoneA Offline
              AlCalzoneA Offline
              AlCalzone
              Developer
              schrieb am zuletzt editiert von
              #10

              Cool, dass du eine Lösung gefunden hast. Kleiner Tipp:
              @daniel_2k:

              obj = getObject("system.adapter.web.0"/*web*/);
              obj.common.enabled = true;
              setObject("system.adapter.web.0"/*web*/, obj);
              ```` `  
              

              geht auch einacher:

              extendObject("system.adapter.web.0", {common: {enabled: true}});
              

              Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

              1 Antwort Letzte Antwort
              0
              • D Offline
                D Offline
                daniel_2k
                schrieb am zuletzt editiert von
                #11

                Ich habe das Update-Script (Windows) mal in Powershell geschrieben.

                Da es ein Powershell ACME-Modul als ACME-Client gibt, macht es Sinn es komplett als PS-Skript zu schreiben.

                Es aktualisiert über die Let's Encrypt CA das Zertifikat (es wird alle 90 Tage ein neues angefordert), aktualisiert die Bindung in IIS und aktualisiert die Zertifikate in ioBroker.

                Das Skript ist noch nicht zu 100% getestet. Der IIS-Teil und ioBroker-Update funktioniert (getestet). Der Let's Encrypt-Part funktioniert prinzipiell auch, allerdings konnte ich bisher noch keinen Test nach Ablauf des Identifiers (30 Tage) machen (muss ich noch warten :) ). Ich weiß derzeit noch nicht genau, welche Schritt nach der ersten Einrichtung des Vaults noch notwendig sind, um ein neues Zertifikat mit gleichen Eigenschaften wie zuvor zu erstellen.
                2323_lecertupdate.ps1.zip

                1 Antwort Letzte Antwort
                0
                • D Offline
                  D Offline
                  daniel_2k
                  schrieb am zuletzt editiert von
                  #12

                  Update für das PowerShell-Skript.

                  Nach dem nun die Gültigkeit meines Identifiers abgelaufen ist, konnte ich das Skript mal als Ganzes testen.

                  Es funktionierte nämlich noch nicht wie gewünscht. Es ist tatsächlich so, das bei Ablauf des Identifiers man die gesamte Prozedur (Identifier erzeugen, Challenge durchlaufen, Zertifikat anfordern) immer neu durchlaufen werden muss.

                  Daher habe ich das Skript angepasst (inkl. diverse Anpassungen und kleine Fixes) und konnte es auch als Ganzes erfolgreich testen.
                  2323_lecertupdate_v1.3.zip

                  1 Antwort Letzte Antwort
                  0
                  • systemofapwneS Offline
                    systemofapwneS Offline
                    systemofapwne
                    schrieb am zuletzt editiert von
                    #13

                    Hat sich etwas an iobroker geändert? Ich finde das entsprechende Objekt nicht und kann selbst mit dem JS-Modul das objekt nicht einlesen:

                    log(JSON.stringify(getObject('system.certificates')));
                    

                    resultiert in einem null-value.

                    1 Antwort Letzte Antwort
                    0
                    • apollon77A Offline
                      apollon77A Offline
                      apollon77
                      schrieb am zuletzt editiert von
                      #14

                      CLI support ist geplant für js.controller 2.0.0 … https://github.com/ioBroker/ioBroker.js ... issues/222 ... dauert aber noch ein bissl

                      Beitrag hat geholfen? Votet rechts unten im Beitrag :-) https://paypal.me/Apollon77 / https://github.com/sponsors/Apollon77

                      • Debug-Log für Instanz einschalten? Admin -> Instanzen -> Expertenmodus -> Instanz aufklappen - Loglevel ändern
                      • Logfiles auf Platte /opt/iobroker/log/… nutzen, Admin schneidet Zeilen ab
                      1 Antwort Letzte Antwort
                      0
                      Antworten
                      • In einem neuen Thema antworten
                      Anmelden zum Antworten
                      • Älteste zuerst
                      • Neuste zuerst
                      • Meiste Stimmen


                      Support us

                      ioBroker
                      Community Adapters
                      Donate
                      FAQ Cloud / IOT
                      HowTo: Node.js-Update
                      HowTo: Backup/Restore
                      Downloads
                      BLOG

                      591

                      Online

                      32.5k

                      Benutzer

                      81.7k

                      Themen

                      1.3m

                      Beiträge
                      Community
                      Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                      ioBroker Community 2014-2025
                      logo
                      • Anmelden

                      • Du hast noch kein Konto? Registrieren

                      • Anmelden oder registrieren, um zu suchen
                      • Erster Beitrag
                        Letzter Beitrag
                      0
                      • Home
                      • Aktuell
                      • Tags
                      • Ungelesen 0
                      • Kategorien
                      • Unreplied
                      • Beliebt
                      • GitHub
                      • Docu
                      • Hilfe