Kodi Remote SSH Filesharing

Ich habe einen Raspberry Pi mit Kodi vor Ort und ein entferntes NAS, von dem ich Multimedia Daten auf den Kodi streamen wollte. Jetzt wollte ich keine Löcher in die Firewall des entfernten NAS schießen und auch keinen Wireguard VPN Server darauf installieren. Ich habe aus Sicherheitsgründen lediglich die SSH bzw. SFTP Möglichkeit zur Verfügung, um mit dem NAS zu kommunizieren. Aus Sicherheitsgründen ist aber die Verbindung mit Passwort auf dem NAS nicht erlaubt (stattdessen nur SSH Keys) und damit kann ich mit Kodi nicht über die “Remote Shares” der Kodi GUI auf das NAS zugreifen. Die gehen nämlich nur mit Passwort.

Ich habe versucht über einen Local SSH Tunnel auf das NAS zu kommen, um darüber eine Datenverbindung aufzubauen. Da mein Versuch am Ende erfolgreich war, möchte ich die Lösung hier teilen:

Erst mal muss man sich für die Konfiguration mit root@<hostname> auf dem Kodi im lokalen Netzwerk anmelden. Dann findet man unter /storage/.config/autostart.sh eine Datei, in der man Befehle eintragen kann, die Kodi beim Start ausführt. Also der perfekte Ort um eine SSH Verbindung zum NAS beim Start des Kodi aufzubauen. Das mache ich mit dem Befehl ssh <user>@<adresse> -i <IdentityFile> (anlegen, wenn nicht vorhanden) -p <port> -f (background) -T (kein Terminalemulator) -L 5005:localhost:5005 sleep 14d

sleep 14d hält die Remote Verbindung für 14 Tage offen. Ohne dieses Kommando würde sich die SSH Verbindung sofort wieder schließen.

Mit diesem Befehl baue ich eine Verbindung zum WebDAV Dienst auf dem NAS auf, ohne SSL Verschlüsselung, weil alles lokal.

Um schließlich auf die Daten auf dem NAS mit Kodi zugreifen zu können, muss ich in Kodi noch ein neues Network-Share hinzufügen. Als Dienst gebe ich natürlich WebDAV an und nutze meine normalen Zugangsdaten. Allerdings mit der Adresse localhost bzw. 127.0.0.1 und Port 5005.

Die Daten fließen nun durch den verschlüsselten Tunnel zum Kodi.

ImageMagick Format Konvertierungen

Umwandlung aller Bilder eines Types aus verschiedenen Unterordnern in ein spezielles Verzeichnis

Wenn du mehrere Unterverzeichnisse hast, über die vertreut Bilddateien liegen, die du platzsparend kleinrechnen und in ein eigenes Verzeichnis abspeichern willst, dann probiere diesen Code aus:


find . -name *.TIF -print0 | \
xargs -n1 -0 -I% sh -c \
'convert -format jpg -quality 80 \
"%" klein/$(basename "%" .TIF).jpg'

# find: Dateien suchen
# Pipe zu xargs
# führt ein Shell Kommando mit convert aus
# schreibt alle Dateien in ein! Unterverzeichnis

Ich hatte viele große TIF Dateien vom Fotografen aus mehreren WeTransfer ZIP Dateien extrahiert, die nun in verschiedenen Ordnern verstreut lagen. Eine Datei wog über 100 MB. Die vielen überflüssigen GB Speicherplatz wollte ich wieder auflösen.

Ein find . -name *.TIF sucht rekursiv nach allen TIF Dateien.
-print0 sorgt dafür dass ein null character als Trennzeichen gesetzt wird, weil sonst Leerzeichen in den Ordnernamen für Falschinterpretationen nach der Pipe entstehen können.

xargs -n1 führt maximal ein Argument im nachfolgenden Befehl aus
-0 löst die null character als Trennzeichen auf
-I% ist der Platzhalter für den Pfad/Dateinamen der gefundenen Datei
sh -c führt ein Shell Kommando von einem String aus, das in einfachen Anführungszeichen folgt:
convert -format jpg -quality 80 stellt die Konvertierung auf JPG und Qualität 80% ein.
"%" Damit die Leerzeichen richtig interpretiert werden muss der Platzhalter in Anführungszeichen stehen.
$(basename "%" .TIF).jpg sorgt dafür, dass nur der Dateiname vom Platzhalter verwendet wird und das .TIF ausgelassen wird, so dass ich lediglich die Endung jpg am Ende habe.

Mac Laptop akkuschonend schlafen legen

Solange der Laptop Zuhause steht, habe ich ihn am Strom angeschlossen. So spare ich an Ladezyklen, die den Akku altern lassen würden. Natürlich ist ein voller Akku auch nicht der Optimalzusand für Li-Ion Akkus, aber besser so, als ständig zwischen 30% und 80% zu pendeln. Ich nehme hier die Degenration durch den permanenten Vollzustand in Kauf, in der Annahme, dass es das geringere Übel für den Akku ist.

Der Akku entlädt sich aber über einen längeren Zeitraum von alleine. Fällt seine Kapazität auf unter 95%, wird er über das Netzteil auf 100% nachgeladen. Wer also den eingebauten Akku schonen will, weil der Laptop meistens auf dem Schreibtisch steht, versucht meiner Meinung nach den Ladezustand über 95% so lange wie möglich zu halten.

Wenn man aber den Laptop transportiert, um ihn an anderer Stelle wieder mit dem Stromnetz zu verbinden, z.B. bei einem Arbeit- oder Auftraggeber oder bei Freunden, dann kann es sein, dass er am Zielort bereits 1% oder mehr an Kapazität verloren hat, weil er im zugeklappten Zustand auch Strom verbraucht.

Der Verlust an Kapzität tritt auf, wenn man ihn in den Ruhemodus versetzt, z.B. in dem man ihn zuklappt und anschließend vom Stromnetz trennt. Im Ruhezustand behält er den aktuellen Systemzustand im RAM. Das sorgt dafür, dass er nach dem Aufklappen fast instantan den Zustand aufrufen kann, an dem den Laptop schlafen legte. Denn aus dem RAM lässt sich bekanntlich am schnellsten lesen.

Nun verbraucht das Speichern der Daten im RAM aber Strom, den er sich aus dem Akku holen muss. Darum verliert der Laptop während des Transportes Strom.

Lösung

Man kann unter OSX (macOS) einstellen, wie der Hibernation-Zustand, der Ruhemodus, ausgeführt wird. Es gibt mehrere Varianten:

Speichern des System-Zustandes

  • (0) Systemzustand nur im RAM gespeichert (geht der Akku auf 0%: Totalverlust)
  • (25) nur auf der Festplatte gespeichert (langsames speichern und laden des Zustands)
  • (3) im RAM und auf Festplatte gespeichert (safe sleep – Standard)

Eine Änderung an den Systemeinstellungen kann man über das Terminal, die Kommandozeile vornehmen. Man kann mit pmset -g erfahren, welche Power Management Settings gesetzt sind. Hinter dem Stichwort hibernationmode steht eine Zahl, die für den Modus steht (s.o.). Will man den Modus auf akkuschonenenden Festplattenmodus stellen, muss man sudo pmset -a hibernationmode 25 eingeben und anschließend neu starten. Anschließend kann man das sleepimage aus dem Pfad /private/var/vm mit sudo rm -f /private/var/vm/sleepimage löschen und einiges an Platz auf der Festplatte frei machen.

Im Modus 25 wird der Zwischenstand allein auf die Festplatte geschrieben, was bei einer SSD kaum Zeit benötigt. Dann wird der Rechner komplett ausgeschaltet und kann durch Drücken auf den Powerknopf wieder geweckt werden. Man verliert (fast) keinen Strom unterwegs.
Es gibt aber einige Fallen die unterwegs doch für Akkuverlust sorgen könnten. Der Rechner startet (bei mir) alle 2 Stunden, um sich dem Netzwerk zu zeigen. Das sollte man unterbinden mit sudo pmset -a ttyskeepawake 0. Dass er nicht gleich beim Öffnen des Deckels angeht, sollte man sudo pmset lidwake 0 setzen.

PiHole, DHCP, und lokale Namensauflösung

Ich habe auf meiner Synology DiskStation den Pi Hole im Docker Container eingerichtet. Die DHCP Funktion habe ich aber abgestellt, weil ich nicht erkannt habe, dass ich damit meine VLAN DHCP Zuweisung aus dem Edge Router abbilden kann. Darum bin ich darauf angewiesen die DHCP Funktion des Routers weiter zu nutzen.

Wie geht also die Einrichtung, wenn PiHole nur als DNS Server arbeiten soll, danach aber noch, quasi als Fallback, der Router kommt, der die lokale DNS Auflösung übernimmt?

In der Frage steckt schon ein Teil der Antwort. Mein DHCP Server vergibt als DNS Server 1 die lokale Adresse vom PiHole. Er selber löst DNS Adressen nicht über den PiHole auf. Er ist das Gateway und löst die DNS über den externen DNS Dienst auf, den ich normalerweise im PiHole angeben würde. Statt dass ich den externen DNS Server jetzt im PiHole angebe, gebe ich als externen DNS Server den Router an. Der nimmt jetzt alle Anfragen entgegen: die für die lokalen Adressen und die gefilterten externen Adressen. Damit werden die lokalen Adressen richtig aufglöst und die externen werden nach aussen geleitet. Zwar ohne DNSSEC und DoT, etc. aber das ist vielleicht nicht so problematisch, wenn es nur um den Filter geht.

Edge Router Nameserver einstellen
Hier stellt man den Nameserver im Edge ein
PiHole Settings für lokale DNS Server
Hier stellt man den Router als DNS Server ein

Also noch mal: der DHCP Server im Router teilt den Clients mit, dass ihr DNS Server der PiHole ist. Der PiHole ist jetzt der erste DNS Server im Netzwerk. Im PiHole stellt man für die externe DNS Auflösung nicht Quad9, OpenDNS, Cloudflare oder was auch immer ein, sondern gibt die IP des Routers ein (Settings > DNS). Und dem Router sagt man, dass der DNS Anfragen dann über den externen DNS Server seiner Wahl übernimmt. Im Fall des Edge Routers ist das in der Leiste am untersten Bildrand (System > Nameserver

DisplayPort: Helligkeit und Lautstärke beim Mac steuern

Bildschirmfoto 2020-01-27 um 10.39.02

Mein Monitor wird über DisplayPort angesprochen, von meinem 2015 Mac. Leider kann ich über die Systemeinstellungen weder die eingebauten Lautsprecher lauter oder leiser machen, noch die Helligkeit regeln. Doch dafür habe ich ein kleines Programm gefunden (MonitorControl, OpenSource), das mir die gewünschen Schieberegler zur Verfügung stellt. Entweder als DMG herunter zu laden oder als Homebrew Cask: brew cask install monitorcontrol.

OpenElec SSH „PasswordAuthentication no“

OpenElec SSH

Ich wollte für einen Bekannten ein OpenElec (Kodi) auf einem RaspberryPi via SSH nach außen zugänglich machen. Das eigentliche Problem ist, dass man die Zugangsdaten (Username root oder Passwort openelec) in der Kommandozeile nicht ändern kann, aufgrund von deaktiviertem sudo. So entsteht, wenn man eine Portweiterleitung im Router auf den Raspberry einstellt, eine unangenehme Sicherheitslücke. Wenn man das Passwort nicht ändern kann, bleibt noch die Möglichkeit den Zugang zu SSH über Passwörter zu deaktivieren. Schlau gedacht und damit /etc/ssh/sshd_config angepasst: PasswordAuthentication no. Schade, das Filesystem ist read-only, speichern nicht möglich. Einen Remount mit rw ging nicht.

Aber man kann dem SSHDaemon trotzdem Startparameter unterschieben.
Der SSHD Start wird in folgender Datei definiert:
/usr/lib/systemd/system/sshd.service.
Und die sucht Konfigurationen wiederum hier:
/storage/.cache/services/sshd.conf.
In Zeile 2 kann man nun folgendes eintragen:
SSH_ARGS="-o 'PasswordAuthentication no'".
Beim nächsten Neustart ist die Passwortabfrage deaktiviert.
Darum vorsicht, den Public Key vorher in
/storage/.ssh/authorized_keys kopieren.

Blockiertes Gast-Netzwerk umgehen

Ports blockiert, wie umgehen

Ich war neulich auf Reisen und bekam eine LTE Verbindung mit Volumenbegrenzung von 10GB spendiert. Problem war, dass ich von einer Flatrate ausgegangen war. Nun hatte ich darauf verzichtet vorher alle für die Arbeit benötigten Daten auf lokale Speichermedien zu kopieren, da ich dachte, dass ich ja auch später noch alles was fehlt nachträglich über das Netz laden kann. Doch wenn man sich seine 10GB doch einteilen muss, sucht man nach anderen Internet-Quellen. Die nächste Flatratequelle war in diesem Fall ein kostenloses Gastnetzwerk in der Nähe. Auf diesem Gastnetzwerk waren nicht viele Ports offen: 80, 443, 25, 143, 993, 995, 8080, um den Großteil zu nennen. Alle Ports die ich für eine Downloadverbindung zum Server brauchte, waren verschlossen und da meine OpenVPN Verbindung auf UDP 1194 eingestellt war, kam ich damit auch nicht weiter.

SSH Port Weiterleitung am Router

Welche Ports blockiert werden, kann man ganz einfach mit curl portquiz.net:993 herausfinden. Wobei 993 der Port ist, den man testen will. Die Seite portquiz.net bietet auch noch andere Testvarianten.

Zum Hauptproblem fand ich mehrere Lösungswege. Der erste schien mir am schnellsten. Wollte ich doch zu erst meine SSH Verbindung wieder nutzen, ohne den Port vom SSH Client zu ändern. Ich hatte zwar schon eine Portweiterleitung eingerichtet, aber die benutzte einen Port, der ebenfalls blockiert wurde.
Die Portweiterleitung ändere ich eigentlich am einfachsten mit dem Webinterface meines entfernten Routers, der die Zugänge zu meinem Server hinter dem Router regelt. Dort leite ich einfach einen im Gastnetzwerk freien Port (bspw. 993) auf meinen SSH Client um.
Das funktionierte leider nicht sofort und ich habe erst später gemerkt, woran es lag. Ich hatte in meiner Portweiterleitung mehrere Weiterleitungen angelegt, die alle auf den gleichen Port zeigten. Doch es fand weiterhin nur eine Weiterleitung über meinen alten Port statt, nie über die neu angelegten. Und der alte war nach wie vor im Gastnetzwerk gesperrt. Nach langem Rumprobieren kam ich drauf, dass ich die Portweiterleitungen, die ich für den Zielport 22 angelegt hatte, ein mal alle komplett abschalten musste, abspeichern und dann auf dem neuen Port wieder aktivieren musste. Dann übernimmt er die neue Weiterleitung. Doch darauf war ich erst ganz am Schluss gekommen. Denn vorher habe ich meine OpenVPN Verbindung auf TCP 443 eingestellt.

Open VPN auf https-Standardport 443 einstellen

Mit dem Umstellen von UDP Port 1194 auf TCP 443 habe ich eine sichere Fallback Lösung für alle Fälle, denn 443 müsste immer und überall offen sein und mit der VPN Lösung sollte ich immer alles über das Netzwerk bekommen, was ich brauche. Was ist eigentlich besser: OpenVPN via UDP oder TCP? (engl)

SSH Tunnel mit lokaler Portweiterleitung

Die dritte und und interessanteste Lösung war der SSH Tunnel, den ich ausprobieren musste, um ihn wirklich zu verstehen.
Angenommen ich erreiche meinen SSH Client neuerdings über Port 25, gebe ich im Terminal folgendes ein
sudo ssh -p 25 user@sshclient.de -L 8080:meinserver.de:5006 -N
macOS wollte sudo, weil Privileged ports can only be forwarded by root.
Ich verbinde mich also zuerst mit -p Port 25 auf meinen SSH Client.
Warum noch mal 25? Ist beispielhaft für einen Port im Gastnetzwerk, der nicht gesperrt ist, so dass nun der angerufene Router den Verkehr von 25 auf 22 weiterleiten kann.
Jetzt steht schon mal eine SSH Verbindung im blockierten Gastnetzwerk.
Wenn ich jetzt mit dem Browser auf das unerreichbare Webinterface meines Servers kommen möchte brauche ich noch -L offenerPort:angerufenerServer:geblockterPort.
Mit -L leite ich alle „local“ Anfragen, auf den im Gastnetzwerk freien Port 8080, über die etablierte SSH Verbindung. Mein verbundener SSH Client erzeugt einen Tunnel auf dem offenen Port 8080 und holt darüber die Pakete von dem im Gastnetzwerk unerreichbaren Port 5006 aus meinem Server.
Das -N weist SSH an, keine Befehle zu erwarten, das heißt, SSH stellt keine Eingabeaufforderung her, sondern ist im Horch-Modus.

Um die Adresse, die ich normalerweise mit https://meinserver.de:5006 aufrufen würde, zu erreichen, gebe ich jetzt im Browser https://localhost:8080 ein. Dann kann ich über den Port 8080 in den Tunnel meiner SSH Verbindung steigen und komme am anderen Ende auf meinem Server mit dem Port 5006 raus.

Mit diesen drei Lösungsmöglichkeiten ist man wirklich gut ausgestattet, um seine Daten in blockierten Umgebungen zu erreichen.

Firefox Fehlermeldung

Ein Problem gibt es aber noch, nämlich wenn man im Browser über einen Nicht-Standard-Port in den Tunnel möchte. Wenn man, wie ich, über Port 993 seine getunnelte Seite ansurfen will, gibt es bei allen Browsern eine Fehlermeldung, bspw. Firefox Fehler: Port aus Sicherheitsgründen blockiert.

Um den Fehler zu beheben gibt man in die Firefox Adresszeile about:config ein und sucht oder erstellt den Eintrag network.security.ports.banned.override. Als Wert wird der Port eingetragen bspw. 993.