Posts für Suchanfrage ssh werden nach Relevanz sortiert angezeigt. Nach Datum sortieren Alle Posts anzeigen
Posts für Suchanfrage ssh werden nach Relevanz sortiert angezeigt. Nach Datum sortieren Alle Posts anzeigen

Dienstag, 31. Juli 2018

Ersatz für ssh-copy-id

Manchmal kommt es vor, das auf einem System das Tool ssh-copy-id nicht vorhanden ist. Dann gibt es zwar einfache Alternativen, aber wenn man nicht genau weiß worauf es ankommt, wird es schnell kompliziert. Ich mache hier raus mal einen kurzen Artikel, weil ich auch ein paar Besonderheiten der Shell gelernt habe. 
Für die Verwendung unter Windows habe ich ein Powershellscript auf GitHub abgelegt.

Die einzelnen Schritte

Was macht ssh-copy-id bzw. was muss man berücksichtigen?
Alles in allem geht es darum, den Public Key von System 1 (lokal) nach System 2 (remote) zu übertragen um sich zukünftig vom System 1 am System 2 vereinfachten anzumelden und Befehle auszuführen.
  • lokalen Public Key an das Remotesystem senden.
  • im Remotesystem schauen ob der Pfad .ssh schon existiert, 
    • wenn nicht: Pfad anlegen.
  • in diesem Pfad schauen ob schon eine Datei .ssh/id_rsa.pub existiert, 
    • wenn nicht: mit dem Public Key erzeugen.
    • wenn schon vorhanden: prüfen ob der public Key schon enthalten ist,
      • wenn nicht: Den Public Key hinzufügen.
Wer Hemmungen hat den Programmcode zu verwenden, kann die oben genannten Schritte auch manuell mit ls und nano (Public Key einfach mit copy&paste übertragen) abarbeiten.
 Schon die erste Aufgabe ist nicht trivial, hier wird mit der Pipe gearbeitet und in Abhängigkeit der Shell stehen dort unterschiedliche Subsysteme zur Verfügung. Variablen können nicht einfach transportiert werden.
Hinweise:

  • Ich habe die Codestücke zur Erklärung ohne Maskierung geschrieben. So funktionieren sie aus der Windows cmd Konsole bzw. direkt in der Shell. Wie weiter unten erläutert muss $ und " maskiert werden!
  • der letzte Befehl (cat bzw. echo) ist nur zum Test ob es funktioniert hat.
Am Einfachsten geht es in eine Datei.
cat .ssh/id_rsa.pub | ssh user@host "cat >kee.tmp;cat kee.tmp"
In Windows sind für Linux oft schädliche Zeilumbrüche (CR/LF) enthalten, dies Variante filtert die CR aus.
type .ssh\id_rsa.pub | ssh user@host "cat | tr -d '\r' >kee.tmp;cat kee.tmp"
Nach einigen Versuchen glaube ich mittlerweile, dass es mit diesem Konstrukt auch zuverlässig in eine Variable ($pub) kommt:
cat .ssh/id_rsa.pub | ssh user@host "pub=$(cat );echo $pub"
type .ssh\id_rsa.pub | ssh user@host "pub=$(cat | tr -d '\r');echo $pub"
Ob das Verzeichnis existiert ist schnell getestet, das ODER führt den Befehl danach nur bei false aus. Vorher wird mit dem umask Befehl die richtige Berechtigung für den neuen Pfad sichergestellt.
umask 077;test -d .ssh || mkdir .ssh
Auf ähnliche Art wird die Datei getestet und bei false einfach erzeugt:
test -f .ssh/authorized_keys || cat kee.tmp >.ssh/authorized_keys
test -f .ssh/authorized_keys || echo $pub >.ssh/authorized_keys
Danach wird der Inhalt der Datei mit grep auf Vorhandensein des Key geprüft und bei false wird der public Key angehängt. Bei der ersten Variante wird die tmp datei gelöscht.
Da Leerzeichen im Public Key sind, braucht grep den Suchstring in "ein zwei drei"!
grep -q "$(cat kee.tmp)" .ssh/authorized_keys  || cat kee.tmp >>.ssh/authorized_keys;rm kee.tmp
grep -q "$(echo $pub)" .ssh/authorized_keys  || echo $pub >>.ssh/authorized_keys

Die Einzeiler

Da die Dateinamen im Code öfters gebraucht werden, definiere ich sie am Anfang als Variable. Jetzt steht noch zusätzlich die Aufgabe den Einzeiler so zu schreiben, dass alle Sonderzeichen von der Shell richtig behandelt werden. Die folgenden Varianten haben als Ziel ein Linux System! Startet man den Befehl aus der Linux Shell muss mit dem Backslash \ maskiert werden:
cat .ssh/id_rsa.pub | ssh user@host "p='.ssh';akey=\$p'/authorized_keys'; okey='kee.tmp'; cat >\$okey; umask 077; test -d \$p || mkdir \$p; test -f \$akey || cat \$okey >\$akey; grep -q \"\$(cat \$okey)\" \$akey  || cat \$okey >>\$akey;rm \$okey"
cat .ssh/id_rsa.pub | ssh user@host "p='.ssh';akey=\$p'/authorized_keys'; pub=\$(cat ); umask 077; test -d \$p || mkdir \$p; test -f \$akey || echo \$pub >\$akey; grep -q \"\$(echo \$pub)\" \$akey || echo \$pub >>\$akey"
Startet man man den Einzeiler aus der cmd von Windows, müssen lediglich die " verdoppelt werden:
type .ssh\id_rsa.pub | ssh user@host "p='.ssh';akey=$p'/authorized_keys'; pub=$(cat | tr -d '\r'); umask 077; test -d $p || mkdir $p; test -f $akey || echo $pub >$akey; grep -q ""$(echo $pub)"" $akey || echo $pub >>$akey"
Baut man den Befehl in Powershell zusammen muss mit dem Backtick ` maskiert werden.

Der Pfad .ssh gilt für die meistens Standard Systeme mit Benutzeranmeldung. Bei vielen Spezialsystemen (Zielsystem) muss der Pfad angepasst werden!
z.B. /etc/dropbear bei OpenWrt.
cat .ssh/id_rsa.pub | ssh user@host "p='/etc/dropbear';akey=\$p'/authorized_keys'; pub=\$(cat ); umask 077; test -d \$p || mkdir \$p; test -f \$akey || echo \$pub >\$akey; grep -q \"\$(echo \$pub)\" \$akey || echo \$pub >>\$akey"
Die nächste Variante hat als Ziel ein Windows System!
ziel='user@host';pkey=$(cat ~/.ssh/id_rsa.pub);ssh $ziel "findstr /c:\"$pkey\" .ssh\authorized_keys ||mkdir .ssh ||echo $pkey >>.ssh\authorized_keys"

Maskierung von Sonderzeichen
Windows: Nur " muss verdoppelt werden -> ""
Linux: $ und " müssen mit \ maskiert werden -> \$ \"
Powershell: $ und " müssen mit ` maskiert werden -> `$ `"

Dienstag, 7. Mai 2019

Windows von FHEM über ssh steuern

Windows OpenSSH Server installieren

Als ersten Schritt sollte man zunächst unabhängig von der Windows Version prüfen ob ein entsprechender Dienst schon läuft oder existiert:
Get-Service -Name *ssh*

Windows 10 + Server 2019

In den aktuellen Windows Versionen (ab dem Jahr 2019) ist der OpenSSH Server enthalten und kann einfach installiert werden.
Get-WindowsCapability -Online -Name OpenSSH.Server* | Add-WindowsCapability -Online
Get-Service -Name sshd | Set-Service -StartupType Automatic
Get-Service -Name sshd | Start-Service

Windows Server 2016, 2012 R2 und 2012

In früheren Windows Versionen kann der OpenSSH Server nur über ein extra download/Setup installiert werden.
Als Voraussetzung für die Installation muss die Ausführung von Powershellscripten erlaubt sein.
Set-Executionpolicy Remotesigned
Ich habe für die Installation ein komplettes Script auf GitHub  zur Verfügung gestellt.
Man kann es einfach herunterladen und starten.
Ergänzung 2021:  TLS1 kann nicht mehr verwendet werden, es kommt unter Umständen zur Fehlermeldung. Hier habe ich Abhilfe gefunden und eine zusätzliche Zeile eingebaut. Eventuell schafft ein .net Update Abhilfe.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]'Tls11,Tls12'
invoke-webrequest https://raw.githubusercontent.com/heinz-otto/Powershell/master/InstallLatestSshd64.ps1 -OutFile InstallLatestSshd64.ps1
.\InstallLatestSshd64.ps1
Das Script überprüft die Windows Server Version und installiert ein fehlendes
Windows Management Framework 5.1 (dann ist zwischendurch ein Reboot erforderlich). Es wird die aktuellste sshd Version heruntergeladen und die Anmeldung für die Administratoren Gruppe freigeschaltet.
Um bei dieser Installationsart anschließend die Programme wie ssh oder ssh-keygen einfach verwenden zu können, kann der Pfad erweitert werden. Hier die Powershell und die cmd Variante für die aktuelle Sitzung:
$Env:Path += "C:\Program Files\OpenSSH-Win64\;"
set PATH=C:\Program Files\OpenSSH-Win64\;%PATH%
Die Verwendung von Parametern in der Powershell kann fehlerhaft sein. Im Zweifel die CMD verwenden!
Das CMD Fenster unter Windows Server 2012 liefert für ssh nicht das richtige Terminal (conpty), eine interaktive Arbeit ist damit nicht wirklich möglich. Scripte können aber abgearbeitet werden.

Anmeldung am Windows OpenSSH Server

Man kann sich wie gewohnt von jedem System (Windows 10 Version 1803 hat den ssh Client aktiv) mit ssh user@host am SSH Server anmelden!
Der ssh Server akzeptiert nur den "Kurznamen". Windows kürzt den Anmeldenamen ein (z.B. bei einem Onlinekonto).
Man kann den Namen leicht in der Powershell Konsole ermitteln:
whoami

SSH Zugang mit Public Key einrichten

Achtung: Auch in Windows darf die Datei %USERPROFILE%\.ssh\authorized_keys nicht für jedermann zugreifbar sein. Nur DER Benutzer (Eigentümer), Administratoren und System darf Zugriff haben, sonst wird der Public Key abgelehnt!
Bitte den Hinweis am Ende des Artikels für die Gruppe der Administratoren beachten!
Bitte alle Schritte (Befehlszeilen) einzeln kopieren und ausführen!

Problem: Bei Windows als SSH Server versagt leider das Tool ssh-copy-id. Hier drei Szenarien für die Einrichtung des ssh Zuganges mit public key zu einem Windows Server.

Voraussetzung: Benutzer hat schon einen RSA Key. Wenn nicht muss er vorher erzeugt werden!
(ssh-keygen -f ~/.ssh/id_rsa -P "" -t rsa oder ssh-keygen -f %USERPROFILE%\.ssh/id_rsa -P "" -t rsa)

Linux Shell
ziel=user@host
pkey=$(cat ~/.ssh/id_rsa.pub)
ssh $ziel "findstr /c:\"$pkey\" .ssh\authorized_keys ||mkdir .ssh ||echo $pkey >>.ssh\authorized_keys"
Windows CMD
set ziel=user@host
set /p pkey=< %userprofile%\.ssh\id_rsa.pub
ssh %ziel% "findstr /c:""%pkey%"" .ssh\authorized_keys ||mkdir .ssh ||echo %pkey% >>.ssh\authorized_keys"
Windows Powershell
$ziel='user@host'
$pkey = $(type $env:userprofile\.ssh\id_rsa.pub)
ssh $ziel "findstr /c:`"`"$pkey`"`" .ssh\authorized_keys ||mkdir .ssh ||echo $pkey >>.ssh\authorized_keys"

Hinweis: Die Befehle nach ssh werden in der CMD von Windows abgearbeitet! Der Public Key wird direkt durch Variablen "Auflösung" mitgegeben. Der Trenner || ist eine bedingte Abarbeitung der folgenden Befehle. 

Ersteinrichtung
Alle Schritte in Kurzform für den Public Key Zugang für den User fhem zu einem Windows SSH-Remotesystem habe ich hier ausführlich gezeigt.

Nur mit Public Key
Man kann den Zugang sehr sicher machen und nur public key zulassen. Dazu muss man die Passwort Authentisierung abschalten indem in der Datei C:\ProgramData\ssh\sshd_config diese Zeile eingefügt wird:
PasswordAuthentication no
Hinweis: Die Config Datei enthält alle Optionen mit ihren Standardwerten als Kommentarzeilen. Jede Änderung in der Datei muss durch einen restart des sshd Services aktiviert werden.

Powershellscript von FHEM aus starten

Bei der Ausführung von Befehlen vom Linux System aus muss man beachten, dass der Backslash verdoppelt (geschützt) werden muss. Ansonsten kann man wie gewohnt Befehle absetzen und sogar Powershell Scripts mit Argumenten ausführen.
"ssh user\@host 'powershell C:\\Tools\\Scripts\\TestPsFhem.ps1' 'http://host:8083' 'DummyName'"
Oder auch mittels powershell cmdlets direkt starten
"ssh user\@host powershell -command stop-vm vmName"
{qx 'ssh user@host powershell -command get-service' }

Innerhalb von Powershell kann man auch mit einem Powershellscript über HTTP auf FHEM zugreifen.
Powershellbeispiel:
Fragt einen Dienst ab und schreibt Status und Displayname nach FHEM zurück in einen Dummy
<#
.SYNOPSIS
    This Script is for testing the FHEM Client for HTTP
.DESCRIPTION
    Give FHEM Server url and Dummy 
.NOTES
    Will give a State and Displayname of Service back
#>
#region Params
param(
    [Parameter(Mandatory=$true,Position=0,HelpMessage="-first 'Portnumber or URL'")]
    [String]$first,
    [Parameter(ValueFromPipeline=$true,ValueFromRemainingArguments=$true)]
    [String[]]$sec
)
#endregion 
$serv="wuauserv"

if (!(Test-Path .\fhemcl.ps1)) {
    Write-Output "fhemcl.ps1 fehlt"
    invoke-webrequest "https://raw.githubusercontent.com/heinz-otto/fhemcl/master/fhemcl.ps1" -OutFile "fhemcl.ps1"
}

$state=get-service $serv
.\fhemcl.ps1 $first "set $sec $($state.status)"
.\fhemcl.ps1 $first "setreading $sec Displayname $($state.DisplayName)"


Eigenheiten für Administratoren in einigen Windows Versionen?

Symptom:
Ein Mitglied der Gruppe administrators kann offenbar keine Anmeldung mit Public Key machen. Obwohl alles eingerichtet ist, wird das Passwort abgefragt. 
Das trifft zu für Windows Server Version 2012 und Windows 10 ab Version 2004.
Bei Windows Server 2012 R2, 2016 und 2019 war es bisher nicht so.

Neue Erkenntnis: Ist eventuell so gewollt und teilweise fehlerhaft implementiert: Link.

Eine Lösung:
Ich habe mir die Sache näher angeschaut und ich habe bei einigen Installationen Unterschiede in der aktiven sshd Konfigurationsdatei C:\ProgramData\ssh\sshd_config gefunden.
Kommentiert man dort am Ende der Datei den folgenden Eintrag mit einem # aus,
Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
funktioniert auch die Anmeldung für Mitglieder der Administratoren. Der Dienst ssd (OpenSSH SSH Server) muss dafür neu gestartet werden!
Hintergrund:
Es gibt zwei Erklärungen für diese Verhalten
  1. Es werden unterschiedliche Inhalte der Datei ausgeliefert - mit und ohne den beiden oben gezeigten Zeilen am Dateiende. 
  2. Der sshd vergleicht dabei die Klarnamen der Gruppenbezeichnung. Ich installiere gern für den Server EN Systeme und gebe Ihnen eine DE mui.
    • Ein 2012 EN System mit DE mui hat administrators - > match!
    • Alle späteren EN Systeme (2012 R2, 2016) mit DE mui haben Administratoren -> kein match!
Der folgende Code kommentiert die verantwortlichen Zeilen in der config aus. In meinem Setupscript für die älteren Serversysteme ist dieser Code bereits enthalten.
# Patch sshd config to allow administrators Group public Key logon
$Quelle="${Env:ProgramData}\ssh\sshd_config"
write-output "patch the sshd config on $Quelle"
Stop-Service -Name sshd
$Inhalt = Get-Content $Quelle
#search 2 lines contains administrators and insert commment sign
$Inhalt|foreach {if ($_ -match "administrators") {$Inhalt[$_.readcount-1]=$_.Insert(0,"#")}}
set-Content $Quelle $Inhalt
Start-Service -Name sshd
Alternative Lösung:
Die Schlüssel der entsprechenden User wirklich in die Datei c:\ProgramData\ssh\administrators_authorized_keys eintragen. Wie hier beschrieben, müssen dazu noch weitere Änderungen (Rechte an Datei und Inhalt C:\ProgramData\ssh\sshd_config) durchgeführt werden.

Den OpenSSH Server wieder loswerden

Stop-Service -Name sshd 
pushd
cd "${Env:ProgramFiles}\OpenSSH-Win64\" 
.\uninstall-sshd.ps1
popd
rm -recurse "${Env:ProgramFiles}\OpenSSH-Win64"
rm -recurse "${Env:ProgramData}\ssh"
Remove-NetFirewallRule -Name sshd

Zum Nachlesen

Ziel des Artikels war es, kurz und knapp alle Schritte zusammenzufassen.
Ausführlicher kann man in folgenden Artikeln nachlesen:
https://heinz-otto.blogspot.com/2018/06/windows-hat-jetzt-ssh.html
https://heinz-otto.blogspot.com/2017/01/per-ssh-remote-befehle-direkt-ausfuhren.html
https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_server_configuration



Samstag, 30. Juni 2018

Windows hat jetzt ssh

Seit vielen Jahren gibt es eine open-ssh Portierung für Windows im Entwicklungs/Beta/Schatten Dasein. Seit der Windows 10 Version 1803 (in 1709 noch als Beta) ist es jetzt offiziell als Feature enthalten und der Client sogar per Default installiert. Die interessante Frage:

Ersetzt das putty?

Wäre zumindest mein Ziel, dann muss man in Zukunft nichts nachinstallieren. Einfach mal versuchen:
Windows + r Taste zum Ausführen drücken und den Befehl eintippen:
ssh username@hostname-oder-IP-Adresse
Es kommt die Abfrage nach dem Passwort bzw. beim ersten Mal vornweg die typische Frage nach der Authentizität des Hostes. Schon ist die Terminalkonsole offen.

Verbindung mit ssh Key

Die OpenSSH Portierung stellt auch einige Tools wie ssh-keygen zur Verfügung. Wie üblich kann man sich einen Key Pärchen im Homedirectory im Pfad .ssh erzeugen lassen. Der Befehl
ssh-keygen -t rsa
schlägt als Verzeichnis vor: C:\Users\name/.ssh/id_rsa
Was natürlich bezüglich der Pfade irgendwie lustig aussieht: Windows trifft Linux.

Alle ssh Befehle mit Bezug auf die Benutzerumgebung müssen ein einem cmd Fenster in der Benutzerumgebung ausgeführt werden!
Geht ganz einfach mit Windows + r Taste + cmd
Die Verwendung einer Powershellkonsole ist wegen der Zeichenkodierung nicht zu empfehlen (siehe weiter unten).

Man kann, wie üblich, den Public Key auf andere System übertragen und sich dort ohne weitere Passworteingabe einloggen und Befehle ausführen (Blog Link zu verwandtem Thema).
Dazu unbedingt die Anmeldung am Windows entsprechend absichern!

Mit SCP Dateien kopieren

Eigentlich ist dies die Funktion von WinSCP &Co. Aber Windows bringt jetzt zumindest Zugriff über die Kommandozeile mit. Und wenn das mit dem Key ohne Passwort funktioniert - warum dann zweimal anmelden?
Kurz und knapp der Syntax um eine Datei zwischen den HomeDirs zu kopieren.
Wie immer: Quelle -> Ziel
scp Dateiname username@hostname:
scp username@hostname:Dateiname .
Während Remote als Ziel der Pfad entfallen kann (HomeDir) muss bei lokal als Ziel mindestens der "." (HomeDir) stehen.

Eigenheiten

Die Anführungszeichen!

  • Remote Befehle müssen in die "Doppelten" gekapselt werden. Bei Linux gehen dort auch einfach 'Remote Befehl'.

Das Beispiel erzeugt lokal eine Datei mit dem Inhalt der Ausgabe des Remote Befehls:
ssh username@hostname "ls -l" >InhaltUserHomeDir.txt

Tools fehlen oder sind unvollständig!

Ein paar Details und Workarounds findet man weiter hinten in diesem Artikel.

Die Antwort

Ich denke putty kann insgesamt mehr, aber wer genau das braucht, was ich hier beschrieben habe, kommt mit dem neuen ssh Client in Windows 10 (ab Version 1083) gut klar. Und die folgende Menüleiste finde ich komfortabler als putty.

Ein paar Tipps

Menüleiste mit den fertigen Verbindungen

Basis ist ein neuer Ordner mit Verknüpfungen darin.
Tipp: Wer ein MS Konto benutzt hat OneDrive, dann am Besten dort und es ist überall verfügbar!
Beispiel: Ordnername "ssh Hosts"
Rechtsklick auf Laufwerk oder Desktop / Neu / Ordner

in dem Ordner Rechtsklick / Neu /Verknüpfung

Rechtsklick Taskleiste / Neue Symbolleiste / Ordner auswählen





Zwei Angaben bei der Verknüpfung: 1 Fenster Befehl und 2. Fenster "Menüpunktname"
Nach dem Klick auf Neue Symbolleiste navigiert man zu dem gerade angelegten Ordner.
Fertiges ssh Menü
Beispiel für Verknüpfungsziele

  • ssh username@192.168.1.1
  • ssh pi@raspberrypi
  • cmd
Wie man das noch etwas mit Powershell kombinieren kann zeige ich in diesem Artikel.

Putty Keys verwenden

Wenn man schon mit einem Putty Key gearbeitet hat, kann man den weiter verwenden. Wobei es bei eigenen Maschinen auch nicht schlimm und am Ende einfacher ist, einen Neuen zu erzeugen.
Man braucht dazu puttygen. In dem grafischen Tool wird mit Load das existierende ppk File mit dem Key geladen.
Den public Key kann man direkt mit der sichtbaren Schaltfläche exportieren, er muss aber dann noch weiter bearbeitet werden, deshalb hier irgendeinen temporären Namen (c:\users\Name\ppkPub.txt) verwenden und diesen mit Pfadangabe merken!
Den private Key müssen wir exportieren: Conversions / Export OpenSSH Key
Hier gleich den richtigen Ort und Namen angeben %userprofile%\.ssh\id_rsa
Dabei eventuell vorher den Pfad %userprofile%\.ssh erzeugen.
Jetzt unbedingt ein cmd Fenster und nicht Powershell öffnen! Der Public Key hat ein falsches Text Format (mehrzeilig). Das Tool ssh-keygen kann diesen umwandeln und gleich an die richtige Stelle schreiben:
ssh-keygen -i -f c:\users\Name\ppkPub.txt >%userprofile%\.ssh\id_rsa.pub

Wie und wo installieren?

Wer jetzt Stelle sucht wo es aktiviert und installiert wird, wird feststellen: Die Sache wird auch nicht übersichtlicher! Je nach dem wie man die Windows Suche benutzt, findet man jetzt:
  • Apps & Features - dort findet man es unter dem Punkt Optionale Features verwalten.
  • Programme hinzufügen oder entfernen - führt letztlich zu Apps & Features
  • Optionale Features - führt direkt zum Punkt
  • Windows-Features aktivieren oder deaktivieren - ist etwas völlig anderes. Obwohl man hier durchaus Komponenten aus Optionale Features findet.
  • Systemsteuerung / Programm deinstallieren oder Ändern hat zwar Windows-Features als Unterpunkt aber die Programme die hier gelistet werden müssen nicht mit denen übereinstimmen die man unter Apps & Features findet.
Powershell ist immer eine gute Lösung, wenn man die Installation exakt beschreiben will. Auf docs.microsoft.com findet man unter dem Stichwort WindowsCapability ein paar cmdlets die aus der dism Verwaltung kommen. Deswegen ist der Syntax etwas "speziell" und man muss schon die Abfrage als Administrator ausführen!
Hinweis: Damit das Installationsthema nicht so einfach wird:
  • Get-WindowsOptionalFeature liefert Windows-Features, 
  • Get-Package liefert installierte Programme, 
  • Get-AppxPackage liefert "vorinstallierte Programme".
Auf dem Server gibt es ein separates Set an CMD-lets z.B. Get-WindowsFeature, Install-WindowsFeature...

Einschränkungen Windows ssh Client

Leider existiert das Tool ssh-copy-id nicht. Deswegen muss man den Key mit ein paar Linux Befehlen übertragen. Ich habe dazu einen extra Artikel verfasst.

Das Tool ssh-keygen kann die known_hosts Datei nicht verwalten.
Update: Aktuell mit der Windows Version 1809 funktioniert es wie gewohnt.
Bisher wurde ein Versuch spartanisch quittiert:
ssh-keygen -R 192.168.178.82
Updating known_hosts is not supported in Windows yet.
Die Datei .ssh\known_hosts ist UTF-8 und mit CR LF kodiert. Man kann sie mit einem Texteditor einfach editieren und die fragliche Zeile löschen. Oder mit dem cat und grep Pendant von Windows geht es mit diesem Zweizeiler:
type .ssh\known_hosts > .ssh\known_hosts.org
findstr /V "192.168.178.82" .ssh\known_hosts.org > .ssh\known_hosts

Windows OpenSSH Server installieren

Edit: Ich habe hier einen Artikel mit einer ergänzenden Anleitung zur Installation des ssh Servers erstellt.

Das machen wir einfach alles mit Powershell.
Windows 10
Der Add Befehl kann hier nicht mit Wildcards umgehen.
Add-WindowsCapability -Online -Name  OpenSSH.Server~~~~0.0.1.0
Jetzt prüfen ob erfolgreich installiert wurde:
Get-WindowsCapability -Online | where name -match 'ssh'
Man kann auch die installierten Dienste prüfen, sie laufen aber noch nicht!
Get-Service -Name *ssh*
Also Dienste auf Automatic setzen und starten:
Get-Service -Name *ssh* | Set-Service -StartupType Automatic
Get-Service -Name *ssh* | Start-Service
Jetzt kann man sofort loslegen und sich zum ssh Server verbinden, eine separate Firewallregel braucht man nicht, die ist offenbar schon eingerichtet. Ich musste nichts weiter einrichten!
Man wird über ssh zur cmd Konsole verbunden, hier kann man dann auch Powershell starten! 

Hinweis:
Die Konfiguration des Servers liegt in C:\ProgramData\ssh.
Get-ChildItem -Path 'C:\ProgramData\ssh\'
Quelle zur Installation

Windows Server
Auf dem Windows Server ist ssh erst ab der ReleaseID 1709 integriert Windows Server 2016 ist die ID 1607.
Auch auf früheren Versionen kann man die aktuelle Win32 OpenSSH Version installieren.
Achtung: für den folgenden Code (und für eine aktuelle Management Umgebung) muss Windows Management Framework 5.1 installiert sein!

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$url = 'https://github.com/PowerShell/Win32-OpenSSH/releases/latest/'
$request = [System.Net.WebRequest]::Create($url)
$request.AllowAutoRedirect=$false
$response=$request.GetResponse()
$url = $([String]$response.GetResponseHeader("Location")).Replace('tag','download') + '/OpenSSH-Win64.zip'
Invoke-WebRequest $url -OutFile openssh.zip
Expand-Archive .\openssh.zip 'C:\Program Files\'
cd 'C:\Program Files\OpenSSH-Win64\'
.\install-sshd.ps1
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
Start-Service -Name sshd
Set-Service -Name sshd -StartupType automatic

Tipp zur Anmeldung mit ssh an Windows 10

Ich melde mich mit einem Online Konto (Format user@domain) am Windows Desktop an. Windows legt intern zu diesem Online Konto eine Art "Kurznamen" an. Der ssh Server akzeptiert nur diesen kurzen Namen, eventuell kann man generell diesen Kurznamen verwenden, wenn man sich an anderen Diensten über das Netzwerk anmeldet.
Mit einer der folgenden Befehle kann man den Kurznamen ermitteln:
whoami
[Environment]::UserName
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name

Hintergrund zur Powershell Textcodierung

In der Powershell (offenbar der > Befehl) werden Text Dateien nicht in der Codierung UTF-8 sondern mit der Codierung UCS-2 LE BOM angelegt. Abhilfe in Powershell? Schwierig.
Mit Notepad++ kann man die Codierung gut anschauen.

Ein paar Tests:
  • Der Befehl innerhalb PS type .ssh/*.pub >catPub.txt erzeugt lokal eine Datei in UCS-2 LE BOM Codierung
  • innerhalb cmd eine Datei in UTF-8 Codierung
  • Der Befehl in CMD oder PS type .ssh/*.pub |ssh pi@192.168.178.80 "cat >picatpub.txt" erzeugt eine Datei in UTF-8 Codierung mit Windows CR LF
  • Wandelt man jetzt mit nano picatpub.txt durch Speichern mit alt+m in Unix LF um dann macht ein erneuter Befehl in cmd type .ssh/*.pub |ssh pi@192.168.178.80 "cat >>picatpub.txt" eine Datei in UTF-8 Codierung mit Unix LF

Das bedeutet:
  • die Übertragung über ssh / type ->  cat "filtert" die UCS-2 LE BOM Codierung aber nicht Windows CR LF.
  • Der cat Befehl unter linux ändert existierende Unix LF nicht!
  • Der type Befehl in PS mit Umleitung >> in eine existierende Datei mit UTF-8 führt zum Datensalat

Ein paar Ansätze:
Ansi ausgeben
UTF8-BOM erzeugen
Keys wieder löschen.
Winscp

Dienstag, 9. Juli 2019

Neues Linux System - Nacharbeit

Generell ist es relativ einfach eine bestehende FHEM Installation auf ein neues Betriebssystem/System zu setzen:
  1. Backup FHEM
  2. Kopie der aktuellen Backupdatei -> Server | USB Stick | per scp lokal
  3. sudo halt
  4. neue SD Card mit aktuellem Image (ich behalte immer die alte SD erstmal in Reserve)
  5. setupBasic, setupFhem, testen
  6. Backupdatei verfügbar machen -> Server | USB Stick mounten | per scp - lokal -> nach /home/pi
  7. stop fhem
  8. restore des Backups
  9. start fhem

Sicherung / Backup

Bei mir ist beim obigen Plan mindestens die Anbindung an Dateiserver und die ssh Verbindung auf der Strecke geblieben. Schritt 1 und 8 muss man dafür noch etwas ausbauen.

Sicherung ssh Umgebung

Die notwendigen Dateien befinden sich in diesen Verzeichnissen:
  • /etc/ssh für den ssh Host / Server
  • /opt/fhem/.ssh für den User fhem
  • /home/pi/.ssh für den User pi. 
Ich werde zwei zusätzliche Dateien in den Backup Ordner von FHEM erstellen. Dies könnte man auch von FHEM von Zeit zu Zeit machen lassen. Neben der Datei für eine Historie mit Zeitstempel erzeuge ich noch eine ohne Zeitstempel. Damit muss man bei der Wiederherstellung nicht lang suchen.
Man kann dieses als Script auch unter FHEM ausführen, da aber Systemdateien gesichert werden, muss tar als sudo ausgeführt werden. Damit das funktioniert, muss die zuständige Datei um /bin/tar ergänzt werden.
datei=/opt/fhem/backup/ssh$(date +%Y%m%d_%H%M%S).tar.gz
sudo tar -czf $datei /etc/ssh /opt/fhem/.ssh /home/pi/.ssh
sudo cp $datei /opt/fhem/backup/ssh.tar.gz
Falls der User fhem gar kein ssh verwendet kommt ein Fehler, dann muss man die Befehle abwandeln. Da die Dateien nicht voluminös sind, kann man auf zip verzichten. Damit kann das tar Archiv leichter mit der Option -rf ergänzt werden.
sudo tar -cf $datei /etc/ssh /home/pi/.ssh
cp $datei /opt/fhem/backup/ssh.tar
Der folgende Zweizeiler wirft zwar Fehler, sichert aber die ssh Dateien für alle existierenden User.
datei=ssh$(date +%Y%m%d_%H%M%S).tar
sudo tar rf $datei /etc/ssh $(awk -F: '$3>998{print $6"/.ssh"}' /etc/passwd)
Will man einfach in FHEM die ssh Key für user fhem sichern kann man das auch dort machen: 
"datei=./backup/sshFhem$(date +%Y%m%d_%H%M%S).tar;; tar -cf $datei ./.ssh"
Und auch später wiederherstellen:
"datei=./backup/sshFhem*.tar;; tar -xf $datei ./.ssh"

Sicherung Dateiserver Umgebung

datei=/opt/fhem/backup/fsconf$(date +%Y%m%d_%H%M%S).tar.gz
sudo tar -czf $datei /etc/fstab /usr/.*credentials /etc/davfs2/secrets
cp $datei /opt/fhem/backup/fsconf.tar.gz
Hat man Scripte o.ä. zusätzlich in anderen Pfaden, kann man die natürlich einfach in dem tar Befehl ergänzen und gleich mit sichern oder eine weitere Datei nach gleichem Schema erzeugen.

Finale Sicherung des alten Systems

Damit man den finalen Status im FHEM System behält, muss man FHEM beenden und dann ein backup durchführen!
systemctl stop fhem
datei=/opt/fhem/backup/FHEM-$(date +%Y%m%d_%H%M%S).tar.gz
tar -czf $datei -C /opt/fhem --exclude ./backup ./
Wenn das Backup zu Ende ist, startet man beispielsweise das Script /opt/fhem/backupFhem.sh und kopiert alle aktuellen Dateien damit auf den Sicherungsserver.
Am Ende des Artikels habe ich noch den Hinweis auf Alternativen zum Server.

Wiederherstellung

Nachdem das neue System grundlegend installiert und getestet ist (Ergänzung Schritt 5. optional: setupDavfs) wird die Sicherung zurückgespielt.
Die Verbindung zu meinem Windows Server geht relativ simpel. Ohne Angabe des Usernamens wird der momentane User (root) verwendet. Ohne Angabe des Passwortes wird es abgefragt:
sudo su
mount -t cifs //ServerName/Freigabe /mnt
mount -t cifs -o username=UserName //ServerName/Freigabe /mnt
mount -t cifs -o username=UserName,password=Passwort //ServerName/Freigabe /mnt
Ist das Laufwerk verbunden, kann auch ohne lokale Kopie sofort mit der Wiederherstellung begonnen werden.
datei=/mnt/fhem/$(hostname)/backup/FHEM-$(date +%Y%m%d_%H%M%S).tar.gz
tar -xzf $datei -C /opt/fhem
Querverweis: Falls die Module im alten System nicht gut dokumentiert waren, hilft eventuell dieser Beitrag.

Wiederherstellung ssh

Bei meinen Systemen wurde immer nur der ecsda Key verwendet. Ich möchte nicht die neue ssh Server Gesamtkonfiguration zerstören (da ändert sich immer mal was, ich habe nicht untersucht was genau) sondern nur das wiederherstellen was gebraucht wird. Unter der Annahme: es gibt nur eine aktuelle Datei im Verzeichnis, wird damit der ecdsa Key in /etc/ssh wieder hergestellt:
datei=/mnt/fhem/$(hostname)/backup/ssh.tar.gz
tar -xzf $datei -C / --wildcards etc/ssh/ssh_host_ecdsa_*
Um die User .ssh Verzeichnisse wieder herzustellen, sollte dieser Befehl gut sein
tar -xzf $datei -C / home/pi/.ssh/ opt/fhem/.ssh/
Damit steht die ssh Umgebung wieder.

Wiederherstellung Verbindungen zum Dateiserver

Die für die Verbindung verantwortlichen Scripte sollten im /opt/fhem Verzeichnis liegen und sind damit schon Teile der Wiederherstellung. Die Datei /etc/fstab und die jeweiligen Credential Dateien liegen aber unter Umständen "verstreut" im System und sind jetzt entweder nicht vorhanden oder neu gemacht.
Zunächst die credential Datei(en) in /usr/
datei=/mnt/fhem/$(hostname)/backup/fsconf.tar.gz
tar -xzf $datei -C / --wildcards usr/.*credentials
Die davfs2/secrets will ich nur ergänzen, davfs muss schon installiert sein!
tar -xzf $datei etc/davfs2/secrets -O|grep magentacloud >> /etc/davfs2/secrets
Ich möchte gern die fstab nicht überbügeln sondern die neue Datei einfach um meine Einträge ergänzen. Existieren z.B. mehrere Mountpoints in /media/ - kann das in einer Zeile erledigt werden:
tar -xzf $datei etc/fstab -O|grep /media/ >> /etc/fstab
Jetzt müssen noch die Mountpoint erzeugt werden:
mkdir $(tar -xzf $datei etc/fstab -O|grep -o '/media/[a-Z,0-9]*'|tr '\n' ' ')

Jetzt kann man das Sicherungslaufwerk wieder trennen.
umount /mnt
Die Verbindung zu davfs2 erfordert auch noch die Gruppenmitgliedschaft in der Gruppe davfs2
usermod -aG davfs2 fhem
Die Gruppenmitgliedschaft greift erst nach erneutem Login! Also mindestens FHEM neu starten!

Alternativen zum Sicherungsserver

USB Stick
Man könnte einen USB Stick verwenden, der Raspberry Pi 3 verkraftet das Stecken im laufenden Betrieb. Bei allen anderen Typen und "zur Vorsicht" ist aber vom Stecken eines USB Sticks im laufenden Betrieb abzuraten. Zuerst schauen welches Device der Stick geworden ist und dann einfach temporär mounten:
lsblk
mount /dev/sda1 /mnt

SCP - lokale Kopie
Mit scp ist es recht simpel sich eine Kopie der Dateien lokal zum holen und diese später zurück zu spielen. Geht auch unter Windows 10 ab 1809 einfach so!
scp pi@hostname:dateiname .
scp dateiname pi@hostname:
Die Restore Befehle muss man natürlich etwas abwandeln, entweder die Variable $datei wird einfach auf die lokale Datei Homedir von pi gesetzt, oder im tar Befehl die Datei direkt angeben.

Installation nodejs, pm2 und pip

Die Installation von nodejs hatte ich ja hier schon erläutert.
Zusätzlich brauche ich "global" noch den Nodejs Prozessmanager pm2.
sudo su
curl -sL https://deb.nodesource.com/setup_10.x | bash -
apt-get install nodejs
npm install pm2 -g
Trotz der Sicherung des gesamten Ordners installiere ich Landroid neu. Wie so oft gibt es mittlerweile neue Versionen.

Python Pakete werden mit Hilfe von pip installiert. Beispiel: die fhem API
apt-get install python-pip
pip install fhem


ToDo
Andere Applikationen unterhalb von /opt sichern

codebox

Freitag, 29. Januar 2021

Befehle und Scripts per ssh ausführen

Ich möchte über ssh (mit Powershell oder Perl) auf einem Linux Computer Befehle ausführen und dort Aktionen steuern.

Dazu braucht man ein paar Vorbereitungen, muss ein paar Eigenheiten beachten und ich möchte hier meine Erkenntnisse notieren.

Die ssh Einrichtung für Linux (fhem) habe ich hier schon mal beschrieben. Auf die Übertragung des public Key mit der Powershell gehe ich kurz ein. 

Mittwoch, 9. September 2020

ssh mit public key

ich habe dazu schon mehrfach was geschrieben - aber man lernt ja immer wieder dazu. Deshalb noch ein ziemlich komprimierter Artikel: 

Ein HowTo für die Automatisierung von Remote Aufgaben in FHEM über ssh. 

Nachtrag 2023: Es gibt einen neuen Artikel, der die Einrichtung ganz kompakt mit einem Script zeigt.

Mittwoch, 18. Januar 2023

ssh Zugang für fhem über Script einrichten

Ich mache einige Dinge aus dem Docker Container heraus über ssh auf dem Docker Host, anstatt den Container zu sehr zu verbiegen. (Artikel andocken).

Dafür habe ich mal ein Script gebastelt und ein paar Aufruf Varianten ausgearbeitet. Damit sollte mit wenigen Handgriffen die Einrichtung des ssh public key Zuganges innerhalb FHEM auf einen anderen Host gelingen. 

Das Script hat nur wenige Zeilen es werden beliebig Hostnamen oder IP Adressen als Argumente übergeben. 

  1. Die eventuell vorhandenen Einträge in known_host werden gelöscht und neu eintragen.
  2. Es wird überprüft ob bereits ein ssh Key vorhanden ist, falls nicht wird ein Neuer erzeugt.
  3. Der public key wird zur möglichen Weiterverarbeitung (in authorized_keys) ausgegeben.

Ich zeige den Aufruf 

  • als komplettes Here Doc, als lokales Script oder Script vom GitHub, 
  • als anderer User,
  • oder direkt im Docker Container.

Das eigentliche Ziel: der public key von User fhem auf dem HostA wird dem User userB auf HostB gegeben damit User fhem sich als userB ohne Passworteingabe an HostB anmelden / Befehle ausführen kann.

Man beachte in allen Beispielen die unterschiedliche Verwendung der Shell Optionen -c und -s!

Samstag, 11. Dezember 2021

FHEM auf neues System umziehen

Eigentlich ist der Weg einfach:

  1. Neues System installieren (Perl Module dokumentiert?)
  2. Altes System beenden und sichern
  3. Restore der Sicherung, Test und Start neues System
Die Downtime beim finalen Umzug soll möglichst gering sein. Punkt 3 kann, vor allem auch zur Übung, mehrfach durchlaufen werden. 

Hinweis: Es gibt zu diesem Thema auch eine aktualisierte Schritt für Schritt Anleitung.

Am Setup eines Raspberry hat sich seit 2019 bei mir nichts geändert. Aber ich habe ein paar neue Ideen getestet. Es ist gut wenn man ein Testsystem oder die neue Hardware bereits zur Vorbereitung hat! 
Will man es auf gleicher Hardware vorbereiten, sollte man sich meinen Artikel BootStick für den RaspberryPi anschauen. 

Samstag, 7. Juli 2018

Etwas Powershell für ssh

Alle Hostverbindungen sind in lnk Dateien definiert und jetzt wäre es cool wenn man diese Definitionen vielfach weiterverwendet.
In Ergänzung zu meinem letzten Artikel will ich hier ein paar Bausteine aufzeigen und die Gedanken dahinter und den Syntax kurz erklären.

Zunächst mal ein paar grundlegende Variablen und Objekte damit der Code universell bleibt.
# Varianten für Zielpfad
#$HomePath = "$env:HOMEDRIVE$env:HOMEPATH\Desktop"
$HomePath = "$env:onedrive\ssh Hosts"
# Filter
$Filter = "*.lnk"
$FArg = "@"

# Shell Object zum Zugriff auf Eigenschaften von lnk
$shell = New-Object -COM WScript.Shell
Kurz und kompakt ist die Variante mit konsequenter Ausnutzung von Pipes.

  • GCI liefert alle Dateien mit der Endung lnk in einem Pfad.
  • Für jedes Element wird ein Shell Objekt erzeugt und im Element Arguments nochmal gefiltert. Im Beispiel auf das Zeichen @ um wirklich nur die lnk Dateien mit user@host zu behandeln. Im Element Targetpath steht der Befehl komplett mit Pfad.
  • Für alle gefilterten Elemente wird ein neuer Prozess mit cmd gestartet und einfach das Kommando aus der lnk Datei aufgeführt.

Ergo werden alle vorhandenen "ssh" Hostdefinitionen in separaten Fenstern geöffnet.
# Variante mit Pipes
Get-childItem $HomePath -filter $Filter |
  ForEach-Object {$shell.CreateShortcut($_.FullName)}|where Arguments -match $FArg|
    ForEach-Object {
       Start-Process "cmd.exe" "/c $($_.Targetpath) $($_.Arguments)"
    }
Die beiden Elemente Targetpath und Arguments liegen als eine Art Objectreferenz vor. Damit wirklich der Inhalt als String verwendet wird muss dies im Process Aufruf mit $() aufgelöst werden.
Es geht auch ohne Pipes, dann werden alle Übergänge in Variablen gespeichert, der Ablauf ist gleich.
# Variante ohne Pipes
$Files = Get-childItem $HomePath -filter $Filter
ForEach ($File in $Files) {
   $lnkfile = $shell.CreateShortcut($File.FullName) 
   if ($($lnkfile.Arguments) -match $FArg ) {
      Start-Process "cmd.exe" "/c $($lnkfile.Targetpath) $($lnkfile.Arguments)"
   }
}
Für andere Fälle kann man auch einfach ein Array mit Hosts erstellen und lässt eine ForEach Schleife über dieses Array laufen.
$Hosts = @("192.168.178.80","192.168.178.81","192.168.178.82","192.168.178.83")
ForEach ($h in $Hosts) {}
Um den Code leserlich und modular zu halten, kann man zu Beginn alles in Variablen packen. Die Unterbringung von Befehlssquenzen in Variablen ist nicht ganz trivial. Damit man gut testen kann und nicht immer den ganzen Code verändern muss, packe ich  auch das erste cmd Argument in eine String Variable $cs.
#Absoluter Pfad zum Public Key
$Keyfile = "$env:HOMEDRIVE$env:HOMEPATH\.ssh\id_rsa.pub"
$cs = "/C "  # Schließt das cmd Fenster nach Abarbeitung
#$cs = "/K "  # Lässt das cmd Fenster offen - nur für Tests wichtig!
$sshTarget = "pi@$h"
Die eigentliche Codezeile ( Ersatz ssh-copy-id) enthält zwei in sich geschachtelte Argumentelisten. Zunächst der Fenstertyp für cmd.exe in $cs.
Die Kombination aus $cs, $C1 und $sshTarget wäre für sich ausführbar, Ergebnis ist eine Shellkonsole.
Danach kommt die Argumentenliste (Befehle) die in der Shellkonsole ausgeführt werden sollen. Diese muss komplett in " " verpackt werden. Innerhalb dieser Argumentenliste werden wieder Variablen mit dem $ Zeichen im Namen gebildet. Diese Namen haben nichts mit der aufrufenden Powershell zu tun.
Damit Powershell die Zeichen $ und " nicht auflöst, muss man sie mit Backticks (`) schützen. Wenn man die Befehlsfolge an den Stellen aufteilt, wo man sie auch separat testen könnte, bleibt sie lesbar und ist gut zu dokumentieren. Der Code funktioniert, im eigentlichen Artikel gibt es eventuell eine aktuelle Variante.
$C1 = "type $Keyfile | ssh " 
$C2 = " akey='.ssh/authorized_keys'; okey='keee.tmp'; cat | tr -d '\r' >`$okey;" # Variablen erzeugen, Text aus der Pipe ohne CR speichern
$C3 = " umask 077; test -d .ssh || mkdir .ssh;" # Berechtigung setzen, Verzeichnis prüfen sonst anlegen
$C4 = " test -f `$akey || cat `$okey >`$akey;" # Datei prüfen sonst direkt anlegen
$C5 = " grep -q `"`"`$(cat `$okey)`"`" `$akey  || cat `$okey >>`$akey;rm `$okey" # Prüfen ob Key schon vorhanden sonst hinzufügen 
Der grep Befehl bekommt einen String übergeben der in sich durch " geschützt sein muss. Damit die Shell die " nicht auflöst müssen sie in der Shell durch Verdopplung geschützt werden, damit Powershell die " im String nicht auflöst müssen sie durch ` geschützt werden.
Jetzt fügen wir alles zusammen und testen das Ergebnis als Ausgabe. Hier erfolgt jetzt das oben erwähnte Einpacken der Shellbefehle in " . Man kann $C2 bis $C5 flexibel weglassen und einzeln testen.
$Argument = $($cs + $C1 + $sshTarget + " `"" + $C2 + $C3 + $C4 + $C5 + "`"")
Write-Output $Argument
Wenn alles gut aussieht kann man den Befehl testen.
Start-Process "cmd.exe" $Argument
Jetzt kann man alles zusammenpacken und auf Knopfdruck entweder alle Hosts auf einmal in getrennten ssh Fenstern öffnen oder gleich alle Hosts mit einem Vorgang mit den eigenen Public Keys versorgen.
Hier eine komplette Version mit ein paar Optionen, die durch Kommentarzeichen noch aus- oder eingeschaltet werden müssen.
# Varianten für Zielpfad
#$HomePath = "$env:HOMEDRIVE$env:HOMEPATH\Desktop"
$HomePath = "$env:onedrive\ssh Hosts"

# eigener Public Key
$Keyfile = "$env:HOMEDRIVE$env:HOMEPATH\.ssh\id_rsa.pub"
# Filter 
$Filter = "*.lnk"
$FArg = "pi@"
# cmd Fenstertyp bestimmen
$cs = "/C"  # Schließt das cmd Fenster nach Abarbeitung
#$cs = "/K"  # Lässt das cmd Fenster offen - nur für Tests wichtig!

# Kommando für cmd Aufruf in Einzelteilen
$C1 = " type $Keyfile | ssh " 
$C2 = " akey='.ssh/authorized_keys'; okey='keee.tmp'; cat | tr -d '\r' >`$okey;" # Variablen erzeugen, Text aus der Pipe ohne CR speichern
$C3 = " umask 077; test -d .ssh || mkdir .ssh;" # Berechtigung setzen, Verzeichnis prüfen sonst anlegen
$C4 = " test -f `$akey || cat `$okey >`$akey;" # Datei prüfen sonst direkt anlegen
$C5 = " grep -q `"`"`$(cat `$okey)`"`" `$akey  || cat `$okey >>`$akey;rm `$okey" # Prüfen ob Key schon vorhanden sonst hinzufügen 

# Die Alternativen Zeilen für OpenWrt Router
#$FArg = "root@"
#$C2 = " akey='/etc/dropbear/authorized_keys'; okey='keee.tmp'; cat | tr -d '\r' >`$okey;"

# Shell Object zum Zugriff auf Eigenschaften von lnk
$shell = New-Object -COM WScript.Shell
# Variante mit Pipes
Get-childItem $HomePath -filter $Filter |
  ForEach-Object {$shell.CreateShortcut($_.FullName)}|where Arguments -match $FArg|
    ForEach-Object {
       $sshTarget = $_.Arguments
       # Entweder nur die Public Keys übertragen 
       $Argument = $($cs + $C1 + $sshTarget + " `"" + $C2 + $C3 + $C4 + $C5 + "`"")
       # oder nur die Terminalsession öffnen
       #$Argument = "$cs $($_.Targetpath) $($_.Arguments)"
        
       Write-Output $Argument # Zum Test
       #Start-Process "cmd.exe" $Argument # eigentlicher Befehl 
    }

Mittwoch, 6. April 2022

andocken - Dinge die man außerhalb docker braucht

Netzwerke, Laufwerke und seriellen Geräte funktionieren relativ einfach in der Containerumgebung. Mit Sound, Bluetooth, Wake on Lan usw. wird es schon schwieriger. Die sind nicht vorgesehen. Docker soll Softwarepakete/Applikationen isolieren und dicht "packen". Das man seine PC Umgebung dort hineinverlegt war so nicht unbedingt gedacht. Und es gibt natürlich "Übergangsbereiche" - Smarthome zum Beispiel. Ich habe ein paar Anforderungen für die ich eine Lösung brauche. Vielleicht ist es ja gar keine Behelfslösung sondern eine clevere Alternative? Folgende Themen habe ich bisher gefunden:

  1. Sound
  2. Bluetooth
  3. WakeOnLan bzw. ssh nutzen  

Freitag, 19. August 2022

HowTo - FHEM Umzug von System A nach System B

Scenario: Umzug auf neues System

  • System Alt: altes Linux, alte Hardware ...
  • System Neu: neues Linux, neue/andere Hardware Plattform ...

Zwei verschiedenen Hardware Systeme sind etwas einfacher zu handhaben, es geht aber auch auf der gleichen Hardware (z.B. Raspberry Pi mit SD Card Wechsel oder USB-Bootstick). Ich habe alle Schritte mit einem Raspberry Pi(Raspberry OS Lite) und einer Virtuellen Maschine(debian 11 netinst) getestet. Dieses HowTo ist auch eine Ergänzung zu meinem vorjährigen Artikel.

Mit dem Raspberry Pi Imager kann man eine neue SD Card effektiv vorbereiten und das System grundlegen konfigurieren (Zahnradsymbol am rechten unteren Rand nachdem man das OS ausgewählt hat) 

Es gab von mir schon ein paar ähnliche Artikel, dieser hier soll ganz gezielt Schritt für Schritt zeigen was zu tun ist. Windows 10 hat ssh und scp eingebaut, andere Tools braucht man nicht. Wer nicht mit Windows CMD arbeiten will findet die Codezeilen für Schritt 1 am Ende auch für Linux und Powershell.

Man kann alle Schritte beliebig oft wiederholen / durchspielen und dabei lernen.

Achtung (03.2024): Das FHEM Installermodul wird leider nicht mehr gepflegt, es häufen sich die Meldungen, das mein hier gezeigtes Verfahren der Ermittlung der fehlenden Debianpakete nicht mehr funktioniert. Ich habe derzeit keine Problem Behebung!

Dienstag, 17. November 2020

Wake On Lan über "Dritte"

Zum Thema Wake On Lan habe ich ja schon ein paar Artikel geschrieben. Es gibt Situationen, da erreicht das Magic Paket nicht direkt sein Ziel. Falls also auch der "directed Broadcast" nicht funktioniert, ist vielleicht der "Agent" im Zielnetz eine Lösung!?

Auslöser für diese Notiz war dieser Beitrag im Forum.

Ein Magic Paket aus einer MAC Adresse zu bauen ist keine große Wissenschaft, dieses Paket muss man dann einfach per UDP und Port 9 ins Zielnetz schicken. Viel Code ist zur Lösung nicht nötig, das Meiste ist wie immer das User Interface und Fehlerbehandlung. 

Mir fallen drei Lösungsansätze ein, alle benötigen keine erhöhten Rechte!

Voraussetzung: ssh Verbindung mit public Key ist eingerichtet und funktioniert!

Linux Host

Auf der Suche nach einem simplen Script bin ich nur bei einer Perl Lösung fündig geworden, eine Lösung mit netcat werde ich noch bereitstellen. 

Das Setup auf dem "Remote Agenten" kann man dann auch gleich per ssh machen:

ssh user@host 'wget -qO wakeonlan https://raw.githubusercontent.com/jpoliv/wakeonlan/master/wakeonlan;chmod +x wakeonlan'

Das Script wird heruntergeladen und ausführbar gemacht. Dann ist die Verwendung simpel: 

  • mac Adresse übergeben
  • Parameter -q für quiet Modus
  • Parameter -i für eine directed Broadcast Adresse.
ssh user@host ./wakeonlan -q 12:34:56:AB:CD:EF

Windows Host

Ich hatte da mal ein PowerShellScript gemacht. Windows kann auch ssh, also kann man auch per ssh die Einrichtung und Steuerung vornehmen.

Fritzbox und TR064

Falls die Fritzbox als zentraler Router dient und die MAC Adressen dort registriert sind, kann man auch die Fritzbox benutzen um das Gerät per WOL zu starten. Per FHEM geht das simpel. Es gibt auch Powershellscripte dafür.

get <FritzBoxName> tr064Command Hosts:1 hosts X_AVM-DE_WakeOnLANByMACAddress NewMACAddress "12:34:56:78:9A:BC"

Definition in FHEM

Das WOL Modul in FHEM bietet mittlerweile den CMD Modus. Hier kann man separate Befehle zum aufwecken angeben, das Ganze auch über ssh (siehe den Link oben). 

In wolCmd steht ein FHEM Befehl. Der Platzhalter $MAC wird bei der Ausführung durch die mac Adresse in der Definition ersetzt.

Beispiel mit der Fritzbox:

Das Gerät muss in der Fritzbox registriert sein! Die Fritzbox kann Broadcast nur im eigenen Netzwerk! 

attr WolDevice wolCmd get Fritzbox tr064Command Hosts:1 hosts X_AVM-DE_WakeOnLANByMACAddress NewMACAddress $MAC

Beispiel mit Remote Host und ssh

Wir brauchen 3 Dinge - ausgeführt so als Block in der Raw Definition:

  1. Das Programm/Script auf dem Agenten,
  2. den Shell Befehl der auf dem Agenten ausgeführt werden soll,
  3. den sshHost in üblicher Form.

"ssh user@host 'wget -qO wakeonlan https://raw.githubusercontent.com/jpoliv/wakeonlan/master/wakeonlan;;chmod +x wakeonlan'"
attr WolDevice wolCmd "./wakeonlan -q $MAC"
attr WolDevice sshHost user@host


CodeSpace


Freitag, 14. Juni 2019

Rockrobo - root und gut?

Es ist einige Zeit vergangen und ich habe im Mai 2021 den Artikel leicht überarbeitet.

Der Staubsauger ist in der Cloud und mein Typ Xiaomi Mi Robot Vacuum (rockrobo.vacuum.v1) wird auch noch von höchster Instanz (CCC) genau analysiert!
Was bedeutet es einen Staubsauger mit Root Zugriff zu haben?!
Markus hat gesagt: Es ist nur der ssh Zugriff - und irgendwann geht es vielleicht nicht mehr.
WLAN Zugang ändern und danach den Token neu auslesen - ist mit dem normalen Gerät ein Graus, aber mit ssh Zugang ganz einfach!?
Tobias hat mir mit seinem Beitrag die Hemmschwelle genommen - also los und Test!
Wie so oft: Meine Beschreibung wird auch irgendwann nicht mehr aktuell sein. 
Die Grundlage steht hier https://github.com/dgiese/dustcloud

Stand Mai 2021 - gibt es einige weitere Entwicklungen und als aktuelle Quelle kann dieser Link dienen:
Das mirobo Tool gibt es auch für Windows, ich habe ursprünglich die Linux Version verwendet.
Ich habe auch Valetudo getestet und in diesem Artikel beschrieben.

Dienstag, 19. März 2019

Precence und OpenWrt - der 3. Versuch

Am Wochenende habe ich meinen OpenWrt Router WRT1900ACS mit neuer Firmware versorgt und dabei fiel dann relativ schnell auf, da war doch noch was...
Die beiden Varianten um festzustellen, ob bestimmte Geräte im Wlan angemeldet sind, die ich im Juni bzw. August 2018 schon mal getestet habe, haben einen ganz entscheidenden Nachteil: Sie überleben das Firmware Update nicht!
Ich hatte die Variante aus August zwar als Provisorium ohne Probleme laufen, aber so richtig zufrieden war ich damit sowieso nicht.
Der ssh Zugang zum OpenWrt Router überlebt das Firmware Update!
Deswegen eine neue Version. Ich beschreibe der Vollständigkeit halber an dieser Stelle auch noch einmal in Kurzfassung die Einrichtung des passwortlosen ssh Zuganges von fhem zum OpenWrt Router. Die Langfassung gab es ja schon in 2017.

Vorbemerkung

Das Tool ssh-copy-id kann nicht mit den speziellen Pfaden von dropbear (ssh OpenWrt) umgehen, deshalb kommt mein "Einzeiler" aus dem Artikel zum Einsatz.
Ich weiß, dass man prinzipiell die ssh Keys auch vom aktiven User auf den User fhem kopieren kann. Bei sicherheitsrelevanten Themen bin ich lieber für "ordentliches" und vielleicht etwas aufwendigeres Vorgehen.

ssh Zugang mit Public Key einrichten

Bitte diesen Artikel zur Einrichtung verwenden und dort in der Codebox den Abschnitt Ziel openwrt verwenden!

FHEM

Die Einrichtung in FHEM besteht aus einem Script und einem Presence Device.

Script

Meine Script liegen jetzt alle auch auf GitHub, wer das aktuelle Script einfach laden will kann das wie hier gezeigt tun, fhem braucht selbst nur Lese Rechte. Im Script muss normal nichts konfiguriert werden.
Dieser Befehl in der FHEM Kommandozeile lädt das Script ohne Umwege ins FHEM Verzeichnis:
"wget -O GetMacPresence.sh https://raw.githubusercontent.com/heinz-otto/scripts/master/Bash/GetMacPresence.sh"
Ich habe keinen anderen Benutzer in OpenWrt angelegt, sollte man aber vielleicht tun.
Das Script liefert lediglich, wie vom Modul gefordert, 0 oder 1 zurück, MAC Adresse und Routername werden als Parameter übergeben.
MAC=$1
host=$2
user="root"
ssh $user@$host '
    if (
      for m in $(
                 for w in $(iwinfo |grep -oE "wlan\d-\d|wlan\d")
                 do
                   iwinfo $w assoclist | grep -o -E "([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}"
                 done
                )
      do
        [ "$m" = '"$MAC"' ] && exit 0
      done
      exit 1
    )
  then
    echo 1
  else
    echo 0
  fi
'

Presence Device

Das Beispiel zeigt die einfachste Verwendung, neben der zu suchenden MAC Adresse wird noch der Name des OpenWrt Routers angegeben.
define WL_Dev1 PRESENCE shellscript "bash GetMacPresence.sh 11:22:33:AA:BB:CC wrt1900"

Erfahrung

Ein Problem tritt relativ schnell zu Tage: Man kann offenbar dieses Script nicht mehrfach starten, dann führt irgendeine Komponente zum Abbruch.

Freitag, 15. November 2024

Dateiserver unter Proxmox

Auf meinem bisherigen KVM/Libvirt Host habe ich ein paar SMB und NFS Shares sowie ISCSI Platten. Ich hielt das bisher für einfacher, als extra eine NAS als virtuellen Server aufzusetzen. Aber: ein GUI macht die Bedienung und Wartung etwas einfacher und bringt auch immer wieder einen Lerneffekt, vor allem wenn man sich nicht tagtäglich mit der Thematik beschäftigt. Durch die Proxmox VE Helper-Scripts bin ich auf etwas mir bis dahin unbekanntes gestoßen: Turnkey Appliances eine Seite mit gut gewarteten VMs und LXC Templates für diverse Anwendungsfälle. 

Die erste Idee war, einfach das Helper-Script zu nehmen, der eine Turnkey Appliance als LXC installiert (bzw. Storage/local/CT Templates/Templates). Der zweite Blick offenbarte den entscheidenden Unterschied: zu VMs kann man die Festplatte direkt durchreichen (nur qm set ...) zu LXC geht das leider nicht. Ich wollte gerne meine existierenden HDDs einfach umhängen.

Nachtrag 2026

Im praktischen Umgang hat sich das direkte Durchreichen von Festplatten als extrem unübersichtlich herausgestellt, ich würde das nicht mehr empfehlen. Auch die Appliance von Turnkey finde ich mittlerweile problematisch. Empfehlung: entweder ein LXC Container und nur als SMB Server verwenden, oder eine Debian VM wenn auch iSCSI und/oder NFS notwendig sind. Ob man Webmin als Admin Interface benötigt muss man selbst entscheiden. Ein paar SMB Freigaben für ein paar User sind nur wenige Zeilen Konfigurationscode.   

Dienstag, 4. Januar 2022

Saugroboter der Neue

Zum Jahreswechsel sucht man sich was zum spielen. Der Saugroboter hat Schwierigkeiten mit dem Weihnachstbaum, Magnetstreifen auslegen habe ich keine Lust, außerdem hat Valetudo eine neue MQTT Api bekommen... Ein Artikel bei Heise hat mich über ValetudoRE nachdenken lassen.

Den Dreame L10 pro haben die Kumpels von DPD mal wieder kräftig mit CO² aufgeblasen, die Sache mit den Lieferdienstes macht mir immer mehr ein schlechtes Gewissen.

Ein erster Test: einfach auf die Taste drücken und fährt - der Weihnachtsbaum bleibt stehen. Aber jetzt erstmal rooten, bevor jemand eine neue Firmware aufspielt. Mit aktuellster Firmware soll es mit dem rooten wieder Probleme geben...

Montag, 31. Januar 2022

OpenWrt upgrade WRT1900ACS (WRT3200ACM) auf DSA network config

 ... das Ende vom Lied: ich habe das Meiste erstmal interaktiv und wenig mit Scripten gemacht - man kann nicht alles theoretisch vordenken. Und ich wollte die Standard Konfiguration erkunden, erweitern und nicht kaputt machen. Nach dem eigentlichen Upgrade habe ich doch ein paar Scripte gemacht die vielleicht nützlich sind.

Das eigentliche Ziel: Update der OpenWrt Firmware mit Reset der Einstellungen, wie es bei manchem Router beim Wechsel von 19.07 auf 21.02 gemacht werden muss. Dabei sollen die Netzwerkkomponenten nicht durcheinander geraten und nach kurzer Zeit alles wieder funktionsfähig sein.

Fast zeitgleich wurde mein DSL Anschluss erneuert - ich habe jetzt vollwertig IPv4 und IPv6. In der default Konfiguration funktioniert ein OpenWrt Router auch nach einer Fritzbox für IPv6. Die Fritzbox muss für einen weiteren Router konfiguriert werden: Dokument von AVM.

Wichtig zur Vorbereitung: Backup und extra ein export der network und wireless Konfiguration sowie der DHCP static leases.

Mittwoch, 13. Mai 2020

systemd unit file

Ich habe mich etwas mit systemd, speziell dem unit file von fhem und dem Start von für FHEM notwendigen Komponenten beschäftigt.
Für detailliertere Information wird diese Seite als Start empfohlen.  Eine Befehlsübersicht zu systemctl habe ich hier gefunden.

Mittwoch, 17. Februar 2021

BootStick für den RaspberryPi

Über USB Boot bei SD Card basierten SBCs hab ich schon mal was geschrieben, ab Version Pi2B v1.2 (Link) kann der Pi ohne SD Card direkt vom USB booten. Dazu muss man u.U. eine einmalige Programmierung vornehmen. Die Hardware und der Pi schon bereit ist, kann man leicht ermitteln:

# Die Hardwareversion ermitteln
cat /sys/firmware/devicetree/base/model
# ermitteln ob das Bit schon gesetzt ist
vcgencmd otp_dump | grep 17:
17:3020000a
#bei ausgabe 17:1020000a programmieren:
sudo cp /boot/config.txt /boot/config.bak
echo program_usb_boot_mode=1 | sudo tee -a /boot/config.txt
# einmal booten wenn erfolgreicher Test config wieder zurück
sudo mv /boot/config.bak /boot/config.txt

Ich hatte die Idee ob man den Pi temporär mit einem Stick booten kann um die SD Card zu sichern oder mit einem neuen Image zu versorgen. Ist vielleicht nur eine Machbarkeitsstudie - ich habe es ausprobiert und auf alle Fälle mal aufgeschrieben. Meine Beschreibung bezieht sich auf ein laufendes System mit RaspiOs lite.