Linux: bei Änderung einer / mehrerer Dateien ein Kommando starten

Mittwoch, 16. Oktober, 2019

Ich brauchte da mal was für unsere Systemlandschaft: der Webservice soll neu gestartet werden, wenn sich eine vordefinierte Datei ändert. Wenn es ein Update der Web-Applikation gibt, dann kann jenes Update ein touch [Dateiname] auslösen.

Wenn das Check-Skript mit einem User läuft, der den Webservice starten darf - sei es mit root oder einem User, dem sudo auf systemctl erlaubt ist - dann kann ein Entwickler niedrige Applikationsrechte haben, ihn aber eine spezifische höhere Rechte erforderliche Aktion ausführen lassen, ohne ihm selbst root oder sudo Rechte geben zu müssen.

Mein Skript habe ich onfilechange.sh genannt.
Es benötigt minimal Parameter zum Erfassen der zu überwachenden Trigger-Dateien und das auszuführende Kommando.
Mit einem “-v” schaltet man den Verbose-Modus ein - dann sieht man mehr, was das Skript gerade macht.

Parameter:

-c [command]
    command to execute on a file change
-f [filename(s)]
    filenames to watch; separate multiple files with space and put all in quotes
-h
    show this help
-i
    force inotifywait command
-s
    force stat command
-v
    verbose mode; enable showing debug output
-w [integer]
    for stat mode: wait time in seconds betweeen each test or on missing file; default: 5 sec

Ein erstes einfaches Beispiel:
Es wird der Text Hallo ausgegeben, sobald man (z.B. in einem 2. Terminal) die Datei /tmp/mytestfile toucht oder beschreibt.

onfilechange.sh -f "/tmp/mytestfile" -c 'echo "Hallo" '

Mit einem zusätzlichen Parameter -v kann man etwas genauer reinschauen, wie das Skript onfilechange.sh arbeitet.

Auf der Kommandozeile macht das Skript wenig Sinn. Um es permanent laufen zu lassen, sollte man es als Dienst einrichten. Wie man mit dem Skript einen Systemd Service einrichtet, ist in der Readme enthalten. Folge ganz unten dem Link zum Sourcecode.

Lizenz: Free software; GNU GPL 3.0

Und noch etwas zu den Interna, wie man die Datei-Überwachung bewerkstelligen kann:

(1)
Das gibt es zum einen inotifywait . Das Tool erhält man in vielen Distros mit Installation der “inotify-tools”.

Nachteile:
- Die Datei / alle zu prüfende Dateien müssen immer existieren. Wenn es einen Prozess gibt, der das Löschen der Trigger-Datei zulässt, ist diese Kommando ungünstig
- Installation der “inotify-tools” ist erforderlich

Vorteile:
+ Man kann mehrere Dateien zum Überwachen andocken
+ Man kann spezifisch definieren, welche Events man überwachen möchte
+ Ohne einen Loop zu verwenden, kann man nach Beendigung mit Returncode 0 ein Kommando starten. Die Ausführung erfolgt sofort

(2)
Das Kommando stat liefert etliche Datei-Attribute, wie Namen, letzer Zugriff, letzte Änderung, Rechte, …

Nachteile
- man kann nur 1 Datei prüfen. Bei mehreren muss man sich einen Loop über n Dateien bauen
- es braucht eine while Schleife und ein sleep N, um zyklisch einen Zustand zu überwachen
- der Kommando-Aufruf erfolgt nicht sofort, sondern ist entspr. sleep in dessen Wartezeiten etwas verzögert.

Vorteile:
+ Man kann obige Nachteile weitestgehend umgehen - dann ist die Prüfung mit stat auch die zuverlässigere Variante
+ Es ist in jeder Distribution in der Standard-Installation enthalten

weiterführende Links:

  1. Download/ Readme: git-repo.iml.unibe.ch: onfilechange

Virtualbox: Protocol error beim Mounten der Shared Folders

Mittwoch, 17. April, 2019

In meiner Virtualbox 6.0(.x) Instanz habe ich ein lokales Webentwicklungsverzeichnis mit mehreren Domains von Entwicklungsumgebungen als Shared Folder in eine CentOS VM geteilt. In jener sind die Verzeichnisse als Apache Webroots via /var/www/[Domainname]/public_html/ angesprochen.

Und wie das so bei Computern ist: von einem Tag auf den anderen funktioniert irgendwas nicht mehr. Heute: das Mounten der Verzeichnisse.

Versuch 1:

Ein Reboot der VM … brachte nichts.

Versuch 2:

Shared Folders funktionieren nur, wenn die Gästetools installiert sind. Es hätte ja durch ein OS-Update der VM einen neuen Kernel gegeben haben. Diese habe ich nochmals installiert. Es wurde ein neuer Kernel compiliert… was einen weiteren Reboot brauchte … es geht aber nicht.

Versuch 3:

So kommt man dem Problem dann näher:
Man öffnet die Logs - das geht via dem Icon rechts einer VM (oh, ich hatte beim Umstellung von Virtualbox 5 auf V 6 lange die Sicherungspunkte gesucht :-)) - hier Logs auswählen. Dann erscheinen mehrere Tabs - das erste davon brauchen wir - die VBox.log.

2019-04-17-virtualbox-01-show-logs.png

Darin taucht ein Fehler auf:

00:36:51.618960 ASSERT_GUEST_LOGREL F:\tinderbox\win-rel\src\VBox\HostServices\SharedFolders\mappings.cpp(762) 
... int __cdecl vbsfMapFolder(struct _SHFLCLIENTDATA *,struct _SHFLSTRING *,unsigned short,bool,unsigned int *): 
... pFolderMapping->cMappings == 0 || pFolderMapping->fGuestCaseSensitive == fCaseSensitive
00:36:51.618981 Incompatible case sensitivity setting: C:\data\htdocs: 2 mappings, insenitive, requested senitive!
00:36:51.619183 VMMDev: Guest Log: 06:57:31.461002 automount Error: vbsvcAutomounterMountIt: Failed to mount 
... 'htdocs' on '/media/sf_htdocs': Protocol error (-1,71)

Nach jenem

automount Error: vbsvcAutomounterMountIt: Failed to mount ‘htdocs’ on ‘/media/sf_htdocs’: Protocol error (-1,71)

kann man im Internet micht der Suchmaschine seiner Wahl suchen. Leider wurde ich trotz des Fehlercodes und Wortlaut der Meldung nicht fündig. Das fand ich unlustig. Ich bin also der erste Mensch auf der Welt, der dieses Problem hat :-)

Schauen wir bei den gemeinsamen Ordnern - das hatte ich eingestellt:

2019-04-17-virtualbox-02-shared-folder.png

Was aber klappte:

Ich habe die Shared Folder Defintion gelöscht … rechts das Order Symbol mit dem X … im Log erschien

00:39:53.656135 SharedFolders host service: Removing host mapping 'htdocs'
00:39:53.743943 GUI: UIMediumEnumerator: Medium-enumeration finished!

Dann wurde das zuvor Gelöschte 1:1 wieder eingerichtet.

00:40:26.398568 SharedFolders host service: Adding host mapping
00:40:26.398589     Host path 'C:\data\htdocs', map name 'htdocs', writable, automount=true, automntpnt=, create_symlinks=false, missing=false
00:40:26.452420 GUI: UIMediumEnumerator: Medium-enumeration finished!
00:40:27.403966 VMMDev: Guest Log: 07:01:07.246159 automount vbsvcAutomounterMountIt: Successfully mounted 'htdocs' on '/media/sf_htdocs'

Dies hat er eingerichtet - und sofort war es auch in der VM ohne weiteres Zutun gemountet.
Last but not least habe ich die VM nochmals rebootet, um zu schauen, ob es auch nach einem Neustart noch funktioniert … yep, auch dies ging.

Unterbinden von Load_file() in Mysql und MariaDB

Sonntag, 17. Februar, 2019

Ich benötige zum Betreiben von Applikationen keine Dateizugriffe via Mysql. Wenn es weder Dateien vom Server noch vom Client braucht, fühle ich mich wohler, wenn die Funktion komplett deaktiviert ist, weil das ein offenes Scheunentor sein kann.

Um das Laden von Dateien innerhalb SQL zu vermeiden, gibt es in Mysql die Möglichkeit, in der Konfiguration den Dateizugriff zu unterbinden

[mysqld]
local-infile = 0|1 oder ON|OFF
secure_file_priv = [Wert]

Kurz in der Dokumentation die Werte nachlesen, ins Puppet kippen und auf alle Server verteilen.

Als Test, ob ich erfolgreich bin, dient der Aufruf … dieser muss NULL ausgeben und keinen Dateiinhalt.

#  mysql -e "SELECT  load_file('/etc/passwd');"
+--------------------------+
| load_file('/etc/passwd') |
+--------------------------+
| NULL                     |
+--------------------------+

Das war die Idee. Eigentlich klingt es einfach.
Leider verhalten sich aber die Einstellungen von Mysql und MariaDB unterschiedlich.

Der Wert für local-infile muss bei beiden 0 oder OFF sein. local-infile ist aber eine dynamische Variable - das ist aber lediglich der Startwert, der mit einem SQL Befehl in der laufenden Instanz neu gesetzt werden kann.

Heisst: es braucht zwingend den Wert für secure_file_priv, der sich wiederum NICHT zur Laufzeit verändern lässt.

(1)
Variante für Mysql:

[mysqld]
(...)
local-infile = 0
secure_file_priv = NULL
(...)

Danach einmal den Service neu starten systemctl restart mysql … dann habe ich das Verhalten wie in meinem Testaufruf.
Dieses Setup funktioniert nicht auf MariaDB - es wird mit einem Fehler in der Variable secure_file_priv beendet.

Die Dokumentation sagt: wenn secure_file_priv fehlt, würde der Dateizugriff verhindert werden…

Description: LOAD DATA, SELECT … INTO and LOAD FILE() will only work with files in the specified path. If not set, the default, the statements will work with any files that can be accessed.

Aber das ist nicht korrekt! Wenn ich secure_file_priv nicht setze, und es aus der laufenden Datenbank abfrage, ist der Wert leer

# mysql -e "SHOW VARIABLES LIKE 'secure_file_priv';"
+------------------+------------+
| Variable_name    | Value      |
+------------------+------------+
| secure_file_priv |            |
+------------------+------------+

… und ein SELECT load_file(’/etc/passwd’); zeigt mir den Dateiinhalt an!
Wer Percona oder einen anderen Mysql-Abkömmling verwendet, sollte das Verhalten austesten.

MariaDB erwartet einen existierenden Verzeichnisnamen. Ich habe mich entschieden, /dev/null zu nehmen, weil es sowohl existiert als auch ein User hier keine Datei ablegen kann:

(2)
Variante für MariaDB:

[mysqld]
(...)
local-infile = 0
secure_file_priv = /dev/null
(...)

(3)
Bliebe noch die Software-Verteilung… wenn in Puppet die Mysql-Klasse aufgerufen wird, muss diese von irgendwoher wissen, ob das Produkt am Zielsystem MariaDB oder Mysql ist. Die Lazy Variante wäre, auf das OS zu reagieren, weil Defaults in den Repos beispielsweise von Debian oder CentOS sich unterscheiden. Besser und sicherer ist natürlich ein echtes Flag.

Update zu (3):

Meine Variante für ein vom Mysql Daemon nicht verwendbares, aber stets existierendes Verzeichnis für beide Mysql-Varianten ist … “/root”

[mysqld]
(...)
local-infile = 0
secure_file_priv = /root
(...)

weiterführende Links:

  1. Golem: Lange bekannte MySQL-Lücke führt zu Angriffen (27.1.2019)
  2. secure_file_priv - mysql - Docs (en)
  3. secure_file_priv - mariaDB - Docs (en)

Erstes Tutorial mit OBS: Installation Pimped Apache Status unter Lubuntu

Samstag, 27. Oktober, 2018

Ich hatte, mal irgendwann OBS auf meinem Rechner installiert … seinerzeit für einen recht banalen Zweck (Vollbild-Streaming zu Youtube) … und jenes geriet fast in Vergessenheit, weil nie wieder gebraucht.
Bis - ja bis eines wunderschönen Tages jemand in unserem Institut meinte, “… mit OBS kann ich für eine Demo sehr einfach Bild-Kompositionen auf andere Bildschirme streamen…”. Es sei einfach und verbirgt viele komplexe Einstellungen, zu denen man aber auch kommt.

Dies war der Wink mit dem Zaunpfahl, das Werkzeug gleichen Abends nochmals hervorzukramen: Man kann mehrere Bildschirmszenen ertsellen und dazwischen umschalten? Diese auch speichern? Und statt streamen vielleicht auch ein Video aufzeichnen?

Ich habe mich zu Beginn wohl zu initial wenig auf das Werkzeug eingelassen. Die Einstiegsoberfläche ist halbwegs einfach. Sobald man aber irgendeine Einstellung bearbeitet, wird man mit zahlreichen Optionen regelrecht eingedeckt. Das Speichern der erstellten Szene habe ich gar nicht gefunden, weil ich es als “Pojekt” links oben im ersten Menüpunkt erwartet hätte. Man muss sich wirklich erst etwas genauer umsehen.

Weil ich schon immer mal ein Tutorial mit Aufzeichnung des Bildschirminhaltes machen wollte, habe ich mich nochmals hingesetzt und probiert.
Als Erstlingswerk entstand ein Installationsvideo für mein Monitoring Werkzeug Pimped Apache Status.

2018-10-27-obs.png

Das Haupfenster ist spartanisch … aber hat es in sich

  1. links unten: “Szenen” - eine Liste mit verschiedenen Settings: Start-Bildschirmseite mit Text, dann eine oder mehrere mehrere mit Interaktionen, eine Outro-Szene.
  2. links unten 2: “Quellen” - pro Szene kann man ein Setup von Quellen platzieren. Ein Bild oder Programmfenster, Webcam oder Videoquelle, Text - alle Elemente kann man skalieren und verschieben und so beliebig anordnen. Die Quellen kann man in mehreren Szenen verwenden (verlinken) - damit werden Änderungen eines Textes oder einer Farbe in allen Szenen übernommen.

OBS zeichnet die Szenen-Umschaltung, die ich manuell gesteuert habe (Anm.: man kann dies auch automatisieren) und die in einer Szene eingebetten Bildschirmaktionen als eine Video-Datei auf.
Nach der Aufnahme war das per Webcam aufgezeichnete Audio zu leise - das musste noch normalisiert werden. Und das Video nochmals encodet.
Weil ich noch zusätzlich einige Annotationen einbringen wollte, z.B. weitere Texte und Hervorhebungen in der Ausgabe auf der Konsole, wurde noch ein 2. Video-Bearbeitungswerkzeug herangezogen.

2018-10-27-vsdc-video-editor.png

Und dann die Videodatei ein drittes Mal encodet. Davon wird die Videoqualität nicht besser. Hier habe ich noch Potential für Optimierungen.
Aber dann ging es “sogleich” auf Youtube.

Voila:

weiterführende Links:

  1. obsproject.com OBS Studio (Free and open source software for video recording and live streaming)
  2. videosoftdev.com VSDC Free Video Editor
  3. Axels Webseite - Docs Pimped Apache Status Get started - hier ist das Youtube Video eingebunden

Matomo-Updater

Donnerstag, 18. Oktober, 2018

Ich habe bei meinem Hoster ein shared Hosting. Dort läuft seit (gefühlt) “ewig” eine Piwik-Instanz. Heute Matomo.
Das aktuellste Matomo Zipfile enthält das Unterverzeichnis “matomo”. Aber meine Instanz liegt noch in einem andersnamigen Verzeichnis.

Damit ich auch künftig weiter automatisiert auf die aktuelle Matomo Version aktualisieren kann, habe ich ein Shellskript geschrieben, was das entpackte Achiv ins eigentliche Installverzeichnis schiebt.

Falls dies noch wer gebrauchen kann … bitteschön :-) Anzupassen ist der Bereich Config…

2018-10-19-matomo-update.png

[Weiterlesen…]