Persistieren einer Gruppe

Für welche Projekte verwendet Ihr OpenHAB? Was habt Ihr automatisiert? Stellt eure Projekte hier vor.

Moderatoren: Cyrelian, seppy

Benutzeravatar
udo1toni
Beiträge: 13864
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: Persistieren einer Gruppe

Beitrag von udo1toni »

Nicht erschrecken, das ist etwas länger geworden, sollte dafür aber vollständig sein :)

openHABian ist eine Scriptsammlung. Du kannst allenfalls den Raspberry Pi herunterfahren.

Der grundsätzliche Weg führt über eine Remote Shell, bzw. ssh. ssh ist seit Windows10 ~2019H2??? direkt mit dabei, ohne dass man irgendwas dazu installieren muss.
Das Problem: ssh erlaubt es nicht, das Passwort beim Programmaufruf zu übergeben. Das ist soweit auch korrekt, denn es gibt eine Möglichkeit, sich sicher aber komplett ohne Passwort anzumelden. Dazu musst Du lediglich ein public/private Key Paar erzeugen.
Da die entsprechenden Werkzeuge meines Wissens unter Windows nicht dabei sind, ist es das einfachste, das Schlüsselpaar unter Linux zu generieren.

Vorher müssen wir uns aber über das Thema Sicherheit Gedanken machen. Nicht ohne Grund benötigt ein User root-Rechte, um das System herunterzufahren. Aber ein root-User ohne Passwort? :o eher so NEIN...
Die Lösung ist ein extra angelegter User, der nur diesen einen Befehl (bzw. eine streng ausgewählte Liste von Befehlen) ausführen darf.

Also in der Linux-Konsole:

Code: Alles auswählen

sudo adduser --disabled-password remote
Die nachgefragten Felder kannst Du einfach leer lassen (mit Enter)

Dieser User kann sich nicht auf normalem Weg einloggen, weil er kein Passwort hat. Deswegen etwas umständlich:

Code: Alles auswählen

sudo su - remote
Der root User kann sich ohne Passwortangabe einloggen :) das - bedeutet, dass man ins home-Verzeichnis des Users wechselt, Schwupps, sind wir als User remote angemeldet, obwohl der User das gar nicht kann ;)
Nun müssen wir das Verzeichnis für die Schlüssel anlegen:

Code: Alles auswählen

mkdir .ssh
und die Berechtigungen etwas einschränken.

Code: Alles auswählen

chmod 700 .ssh
Nun brauchen wir endlich ein Schlüsselpaar:

Code: Alles auswählen

ssh-keygen -t ed25519 -C "openHAB-Pi System Account" -f openhab-key
Es wird ein Passwort für den Key erfragt, da wir aber den Key für passwortlosen Login anlegen, lassen wir hier das Passwort leer (also einfach zweimal Enter drücken)
Anschließend befindet sich im aktuellen Verzeichnis ein Dateipaar namens openhab-key und openhab-key.pub
Die Datei openhab-key kopierst Du auf Deinen Windows PC und löschst sie anschließend auf dem Raspberry.
Den Inhalt der Datei openhab-key.pub fügst Du in die Datei .ssh/authorized_keys ein, am einfachsten so:

Code: Alles auswählen

cat openhab-key.pub >> ~/.ssh/authorized_keys
Allerdings kann der User remote nun alle möglichen Befehle remote ausführen (zumindest alle, die keine root-Rechte benötigen).
Deshalb sorgen wir nun dafür, dass a) jeder Befehl geloggt wird, und b) nur ein bestimmter Befehl ausgeführt werden kann (bzw. natürlich auch mehrere, die aber alle explizit angegeben werden müssen)
Dazu legen wir ein Script an und tragen dies als auszuführendes Script in der Datei authorized_keys ein:

Code: Alles auswählen

touch /home/remote/logssh.sh
chmod 755 /home/remote/logssh.sh
Dann öffnen wir die Datei /home/remote/.ssh/authorized_keys und ergänzen zu Beginn der Zeile

Code: Alles auswählen

command="/home/remote/logssh.sh" 
Danach kommt dann ssh-ed25519 AAA... ... openHAB-Pi System Account

Fehlt noch der eigentliche Inhalt des Scripts /home/remote/logssh.sh:

Code: Alles auswählen

#!/bin/bash
if [ -n "$SSH_ORIGINAL_COMMAND" ]; then
  echo "`/bin/date`: $SSH_ORIGINAL_COMMAND" >> $HOME/ssh-command-log
  if [ "$SSH_ORIGINAL_COMMAND" = "shutdown" ]; then
      exec sudo /sbin/shutdown -h now
  fi
fi
Das Schöne an diesem Konstrukt: Du hast ein Log, in dem mit Uhrzeit und Datum festgehalten ist, welche Befehle aufgerufen wurden. Außerdem besteht kein zwingender Zusammenhang zwischen aufgerufenem Befehl und ausgeführtem Befehl (shutdown führt zu sudo shutdown -h now)
mit elif kann man beliebig viele weitere Einträge in der Datei anlegen (also die zwei Zeilen für den shutdown kopieren, vor dem fi einfügen und das if durch ein el zu elif ergänzen - anschließend das Schlüsselwort shutdown durch ein anderes ersetzen und den gewünschten Befehl in der Zeile darunter angeben, analog zum vorhandenen)

Natürlich funktioniert der Aufruf noch nicht, denn der User remote darf überhaupt kein sudo ausführen...

Der nächste Schritt ist also, diesen einen Befehl zu erlauben. Dazu müssen wir wieder zurück zu unserem ursprünglichen Account mit sudo-Rechten, also
und anschließend

Code: Alles auswählen

sudo visudo
In dieser Datei gibt einzelne Bereiche, für uns ist der Bereich User privilege specification interessant. Dort legen wir eine Zeile an:

Code: Alles auswählen

remote  ALL=(ALL:ALL) NOPASSWD: /sbin/shutdown
Der User remote darf von allen Rechnern aus in der Rolle jedes Users und in der Rolle jeder Gruppe ohne ein Passwort eingeben zu müssen den Befehl /sbin/shutdown ausführen.
Wichtig zu wissen: Der Befehl muss mit dem absoluten Pfad angegeben werden.
Angehängte Parameter werden in der sudoers Datei nicht hinterlegt. Man kann auch mehrere erlaubte Befehle auflisten, durch Komma getrennt.

Nun solltest Du aus der Windows Eingabeaufforderung heraus passwortlos den Pi herunterfahren können:

Code: Alles auswählen

ssh -i openhab-key remote@ip.des.rasp.berry -t "shutdown"
Die Datei openhab-key kann an einem beliebigen Ort liegen, Du musst dann halt den Pfad dorthin mit angeben (in Microsoft-Manier, also "C:\Users\...\openhab-key")
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Antworten