Restic client auf 64 Bit Linux installieren
Restic [1] ist ein in Go geschriebenes Backup-Tool für die Kommandozeile … oder zum Skripten. Es besteht aus einem einzigen Binary und hat keinerlei Abhängigkeiten zu Libs, Paketen oder irgendwas. Es erzeugt dedulizierte Backups: initial wird ein Vollbackup gemacht und dann nie wieder - es braucht dann nur noch inkrementelle Backups. Restic gibt es für Windows/ Mac/ Linux und diverse Plattformen (BSD, Solaris, Mips, … - siehe Releases (dort etwas scrollen :-) [2]).
Das hat was.
Daheim werfe ich gerade einen Http-Server als Backup-Endpoint auf die Synology [3].
Auf Systeme am Institut habe ich grob 150 Linux-Systeme - mit altem und neuen Linux Varianten verschiedener Distributionen. Ich habe ein Bash Skript geschrieben, das mit wget das Binary des Restic Client holt, entpackt und ins /usr/bin legt. Wer es für ein anderes OS oder Architektur braucht, müsste den Suffix “_linux_amd64” ersetzen … oder aber auch dynamisch machen (mit
uname -a
könnte man hinkommen).
#!/usr/bin/env bash # ------------------------------------------------------ # CONFIG # ------------------------------------------------------ resticversion=0.12.0 doLink=0 installdir=/usr/bin resticfile=restic_${resticversion}_linux_amd64 downloadfile=${resticfile}.bz2 downloadurl=https://github.com/restic/restic/releases/download/v${resticversion}/${downloadfile} # ------------------------------------------------------ # MAIN # ------------------------------------------------------ echo echo "##### INSTALL RESTIC CLIENT into $installdir #####" echo echo ----- DOWNLOAD if [ ! -f "${downloadfile}" ]; then wget -O "${downloadfile}.running" -S "${downloadurl}" && mv "${downloadfile}.running" "${downloadfile}" else echo SKIP download fi echo echo ----- UNCOMPRESS bzip2 -d "${downloadfile}" echo echo ----- INSTALL mv "${resticfile}" "${installdir}" chmod 755 "${installdir}/${resticfile}" rm -f "${installdir}/restic" 2>/dev/null test $doLink -eq 0 || ln -s "${installdir}/${resticfile}" "${installdir}/restic" test $doLink -eq 0 && mv "${installdir}/${resticfile}" "${installdir}/restic" echo echo ----- SELF-UPDATE restic self-update echo echo ----- RESULT: test $doLink -eq 0 || ls -l "${installdir}/${resticfile}" ls -l "${installdir}/restic" echo echo ----- CURRENT VERSION: restic version echo echo ----- DONE
weiterführende Links:
AhCrawler läuft mit PHP8
Der AhCrawler ist ein PHP Open Source Projekt, das für den Einbau einer Suche auf der eigenen Webseite enststand. Im Backend kann man den Suchindex wie auch die von Besuchern eingegebenen Suchbegriffe analysieren. Hinzu kommen Werkzeuge, wie Linkchecker, Http-Header-Analyse, SSL-Check und Annehmlichkeiten, wie der integrierte webbasierte Updater oder die Verwaltungsmöglichkeit mehrerer Webseiten.
Nachdem PHP in Version 8 erschien, kam Anfang Dezember 2020 eine Version heraus, die offensichtliche Fehler in der WebGUI unter PHP8 bereinigte. Der Crawler zeigte hingegen bei Http Head Requests mit Curl “irgendwann” ein komisches Verhalten und brach mit einem “Segmentation Fault” ab.
Mit dem heutigen Release des AhCrawler ist aber auch das Geschichte. Ich bezeichne die Software nunmehr als PHP8 kompatibel! Tusch :-)
weiterführende Links:
- AhCrawler (de)
- DOCs: AhCrawler (en)
Flatpress - sichere Passwortfunktion statt MD5 Hash
Ich hatte es es ja genauso in mein meinen Webtools mit Login gern gemacht: neben dem Admin User wurde das Passwort als MD5 Hash in einer Config-Datei hinterlegt.
Die Hashfunktion MD5 ist nach IT Masstäben nicht mehr wirklich sicher - heisst: man kann mit einem zeitlich vertretbaren Aufwand aus dem Hash das (oder ein) Passwort ermitteln, dass auf den Hash matcht. Verzichtet man gar auf Salts, ist der Angreifer mit Rainbow Tables gar in Sekundenbruchteilen am Ziel. Das ist gar nicht gut. Auf MD5 sollte man heutzutage beim Hashing von Passwörtern - egal ob in einer Konfigurationsdatei oder Datenbank-Feld - komplett verzichten.
Ich will es keineswegs verdammen: als reine Hash Funktion zum Bilden von Prüfsummen von nicht-sensiblen Daten, wie Prüfsummen von Download-Dateien, ist es bedenkenlos einsetzbar.
Aber zurück zum Speichern von Passwörtern. PHP bietet seit einiger Zeit von Haus sichere Funktionen an, sichere Passwort-Hashes zu generieren [2] wie auch eine Check-Funktion [3]. Auf dieses Paar habe ich meine Tools umgestellt und kannte das Prozedere der Umstellung bereits.
Da ich hier als “mein” Blogtool Flatpress seit gefühlten Äonen selbst verwende, hab ich mich gern auch an jenem Tool drangesetzt, und dessen md5 Passwort-Hash durch eine sicherere Variante ersetzt - und eine Lösung für den Issue #59 [4] als Pull Request eingereicht.
Das gilt nicht nur für die neu angelegten Passwörter - auch die Migration ist berücksichtigt: bestehende mit md5 Hash gespeicherte Passwörter werden on the fly beim nächsten Login umgeschrieben.
Arvid, danke und merci für den Merge und Erwähnung auf Twitter [1] für die kommende Version 1.2!
I love OpenSource :-)
weiterführende Links:
Matomo-Javascript Tracking Code auslagern
Matomo empfiehlt zum Tracken einer Webseite den Einbau des Codeschnipsels innerhalb des HTML Dokuments … im Head Bereich. [1]
Aber: das Hineinschreiben von Javascript Code in das HTML Dokument ist nicht so recht günstig, wenn man im CSP Security Header das Attribut script-src sicher und ohne unsafe-inline konfigurieren will. [3]
Die Abhilfe besteht darin, dass man [2]
- das Snippet in eine Javascript Datei auslagert.
- den Aufruf des Trackens im Onload Event einfügt - der ebenfalls in der Javascript-Datei ist und nicht im HTML-Code einer Webseite.
Hier einmal ist die Funktion embedTrackingCode benannt:
function embedTrackingCode() { var _paq = window._paq = window._paq || []; _paq.push(["trackPageView"]); _paq.push(["enableLinkTracking"]); var u="/matomo/"; _paq.push(['setTrackerUrl', u+'matomo.php']); _paq.push(['setSiteId', 1]); var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0]; g.type="text/javascript"; g.defer=true; g.async=true; g.src=u+"matomo.js"; s.parentNode.insertBefore(g,s); }
… welche bei Abschluss des Ladevorgangs initialisiert wird:
window.onload = (event) => { embedTrackingCode(); };
Hinweis:
Wenn der Tracking Code in einer Javascript-Datei ist, muss man das Http-Caching der JS Datei bei einem expires= im Http Response Header beachten. Man ist u.U. nicht mehr so flexibel, wenn man den Code anpassen wollte, weil Browser das Javascript aus dem Cache nehmen, statt frisch vom Server die angepasste Version zu holen. Man kann per ETag cachen lassen … oder kann die JS-Datei mit Versionsnummer benennen.
weiterführende Links:
Sourcen für Icinga Checks und Graphen mit Graphite
An “meinem” Institut geht ohne Open Source eigentlich nichts. Damit wir nicht nur nehmen, geben wir an und wann auch etwas als Open Source zurück. Für dieses Thema wird auf unserer Instituts-Webseite kein Platz eingeräumt, daher publiziere ich es hier in meinem privaten Blog.
Ich habe seit Anfang des Jahres eine Icinga Instanz bei uns aufgebaut. Als Icinga-Client auf unseren Servern verwenden wir ein Bash-Skript, das die REST API des Icinga-Servers als auch des Directors anspricht.
Es gibt es diverse mit Bash geschriebene Checks, die die Standard-Nagios Checks ergänzen (und nur teilw. ersetzen). Zur Abstraktion diverser Funktionen, wie z.B.
- Prüfung auf notwendige Binaries im Check
- Schreiben von Performance-Daten
- Handhabe von Exitcodes
… gibt es eine Include Datei, die gemeinsame Funktionen beherbergt. Oder anders: wer einen der Checks verwenden möchte, muss neben dem Check auch einmal die Include-Datei übernehmen.
Die Sourcecodes der Checks sind nun publiziert in [1].
Viele Plugins schreiben Performance-Daten, die wir mit dem Icinga-Graphite-Modul visualisieren. Die unsrigen Ini-Dateien der Graph-Templates liegen in einem separaten Repository [2]. Beim Schreiben der Ini-Dateien der Graph-Templates kam ich immer wieder ans Limit und es gibt (noch?) nicht so wirklich viele dokumentierte Vorlagen. Und so manche in Graphite dokumentierte Funktionen greifen (scheinbar?) nicht in den Inis für Icinga Graphite.
Ich hoffe, dass trotz ausbaufähiger Dokumentation der ein oder andere doch entwas mitnehmen kann.
Ich kann mir gut vorstellen, den ein oder anderen Check noch einmal im Detail hier im Blog vorzustellen.
weiterführende Links: (en)
Bash Rest API Client
Ich bin an unserem Institut am Neuaufbau des Monitorings mit ICINGA dran. Weil es so empfohlen wird, kommt das Director Modul zum Einsatz. Ach so, bereut habe ich dies nicht.
Das Monitoring funktioniert über passive Checks: jeder Server meldet sich selbst an und sendet seine Monitoring Daten zu Icinga ein.
Jeder unserer Server soll ein Host Objekt anlegen, die bemötigten Service-Objekte und und die Services mit dem Host-Objekt verknüpfen. Dazu “spricht” jeder Server per REST API mit dem Director. Der muss die Konfiguration zum Icinga-Server deployen.
Zum Einsenden der Daten braucht es den bereitgestellten Slot für den Host+Service auf dem Icinga-Service. Der Client spricht zum Einliefern der Monitoring-Daten ebenfalls mit einer REST-API - aber dann mit der des Icinga Daemons.
Zum Abstrahieren der REST-API Zugriffe auf verschiedene APIs habe ich alles rund um Http abstrahiert und eine Bash-Komponente geschrieben, die diverse Funktionen für Http-Zugriffe und Abfragen in Skripten einfacher verfügbar macht. Die Verwendbarkeit in Skripten war der Fokus. Die Funktionen ähneln vom Aussehen Methoden einer Klasse: “http.[Funktion]”.
Macht man einen Http-Request, so bleibt dessen Antwort im RAM. Bis man den nächsten Request macht - oder die Shell / das Skript beendet.
Weil es ein Wrapper von Curl ist, kann man alle Http-Methoden, wie GET, HEAD, POST, PUT, DELETE verwenden.
Um einen ersten Eindruck zu vermitteln:
http.makeRequest GET https://www.axel-hahn.de/
Diese Aktion erzeugt keine Ausgabe.
Man kann dann mit Funktionen den Statuscode abfragen, den Http Response Header, den Body oder aber die Curl Daten (darin sind z.B. Upload- und Download-Speed und Verbindungszeiten).
http.getResponseHeader
… gibt alle Http-Response-Headerzeilen aus.
http.getStatuscode
… zeigt den Statuscode
http.isOk
… testet, ob die Anfrage mit einem 2xx Code zurückkam.
Für Icinga wurde der Zugriff mit Basic Authentication umgesetzt.
GET Abfragen lassen sich für N Sekunden cachen. Darüber hinaus kann man den Response exportieren und wieder importieren. Nach dem Import kann man wiederum den Response mit allen Funktionen erfragen - mit http.getRequestAge holt man sich das Alter der Ausführungszeit des Requests. Man kann ein Debugging aktivieren, um die interne Verarbeitung offenzulegen und nachzuvollziehen.
Und Einiges mehr.
Falls das für euch interessant klingt, schaut euch das Bash-Skript doch einmal an.
weiterführende Links:
- Gitlab: iml-open-source/bash-rest-api-client
- Icinga Open Source Monitoring Tool
- Icingaweb - Director REST API
- Icinga: REST API
Linux: bei Änderung einer / mehrerer Dateien ein Kommando starten
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:
- Download/ Readme: git-repo.iml.unibe.ch: onfilechange
- Docs: os-docs.iml.unibe.ch/onfilechange/
preDispatcher - speed up my slow Concrete5 website
Meine Concrete5 Webseite wurde langsamer und langsamer. Sie wird auf einem Shared Hosting betrieben (was ohnehin nicht die schnellste Option sein kann) - hier kann ich zudem keinen Varnish oder auch nur irgendeinen anderen Caching Dienst installieren und davorschalten, sondern muss mich mit .htaccess und Standard-PHP-Mitteln behelfen können.
Das Initialisieren eines Requests in Concrete5 (Bootstrapping) braucht scheinbar sehr lange. Selbst statische Inhalts-Seiten, die ein aktives Fullpage Cache haben, benötigen für die Verarbeitung am Server mehr als 200 ms. Hinzu kommen für einen kompletten Request dann noch Netzwerkzeiten für Namensauflösung (DNS), Anfrage zum Server senden … und das Ergebnis zum Browser zurücksenden, was der Browser dann rendert. Meine schnellsten Seiten aus dem CMS waren bei 300 ms. Andere brauchten 3 Sekunden und mehr. Concrete5 ist einfach langsam.
Ich habe einen Cache geschrieben, der Concrete5 vorgeschaltet ist und im Filesystem seine Caching-Daten ablegt. Kurz er hat minimalste Anforderungen und arbeitet mit einem Shared Hoster. Dieses “Vorschalten” umgeht die lange Initialisierungszeit von Concrete5 - dies macht die Seite schnell.
Vor einigen Tagen habe ich eine erste Version meines preDispatchers eingespielt. Erwartungsgemäss muss man ein paar Kinderkrankheiten ausmerzen. Aber erste Ergebnisse in der Webseiten-Statistik (Matomo) zeigen, dass es eine gute Entscheidung war: die mittleren Seiten-Generierungs-Zeiten sanken von über 2s auf unter 0.4s
Der PreDispatcher besitzt eine Debugging-Ausgabe, die die Arbeitsweise veranschaulicht und den Unterschied deutlich macht. Das ist ein ungecachter Aufruf einer Seite mit Fullpage Cache in C5 - also inkl. Bootstrapping + Auslieferung einer in C5 gecachten Seite:
Der PreDispatcher speichert den Request, der nicht im Cache ist (oder dessen Caching Zeit abgelaufen ist). Der nächste Request auf dieselbe Seite wird dann schnell. Richtig schnell:
Wie lange eine Seite aus einem Cache kommt? Man definiert einen Default für alle Seiten. Mit einer Liste von Regex für aufzurufende URLS kann man die Standard-Vorgabe übersteuern und einen neuen Wert zuweisen.
Zudem gibt es eine Erkennung, was nicht gecacht werden darf - oder wo ein Cache verworfen werden muss. Ich kann mich im C5 Backend einloggen - und der Cache jeder mit Login aufgerufenen Seite wird verworfen.
Ich bin wohl auf dem richtigen Weg. Aber ein wenig Feintuning braucht es noch. Bei Interesse, schaut auf Github … oder fragt mich an :-)
Der PreDispatcher ist Freie Software - unter GNU GPL 3!
weiterführende Links:
- Github: pre-dispatcher for more speed
- Concrete5 webseite
A Touch Of Glass - Theme für Flatpress
Mein bisheriger Blog war über Jahre immer ein Custom style … aber eben nicht public.
Nun habe ich meinen erstes Theme für Flatpress veröffentlicht. Vom Look her ist es der klassische Blog Style mit einem hellen Theme als Basis. Wegen der Transparenzen taufte ich es “A Touch Of Glass”.
Warum überhaupt … es gibt ja bereits mehrere Themes?!
- Mich stört in Flatpress, dass man den Filter auf einen Monat oder eine Kategorie nicht visualisiert hat. Ich hatte es bis anhin mit einem Hack gelöst. In diesem Theme ist es mit Javascript implementiert: In der Widget-Box ist es nun hervorgehoben als auch im Headerbereich sichtbar.
- Mehrere Themes für ein 2 oder 3-Spalten-Layout? Das ist unnötig. Wer mag, darf es gern adaptieren. Im Flatpress-Backend platziert man Widgets in einzelne Bereiche. Von mind. 1 Widget benutzte Spalten werden angezeigt; ungenutzte nicht. Klingt banal. Und ist es per CSS an sich auch.
- Es fehlen Icons. Naja, an allen Ecken und Enden. Ich habe im Theme per CDN Fontawesome eingebunden und an so einigen Stellen per CSS im Frontend als auch Backend integriert.
- Ich wollte ein cooleres Backend. Es soll schliesslich auch 2019 Spass machen, einen neuen Blog-Eintrag zu machen.
Das Theme gibt etliche Rahmenbedingungen vor. Die Syles - 4 liefere ich einmal mit - sind nur noch extrem einfache CSS Dateien, die einige Default-Farben übersteuern.
Weitere Farb-Schemata zu erstellen wird zum Kinderspiel. Wer mag, kann sich eine style.css eines Farbschemas ansehen: es werden CSS Variablen definiert und diese in denjenigen CSS Selektoren angewendet, die übersteuert werden sollen.
Hey, wenn ihr es für gut befindet, empfehlt/ teilt es weiter :-)
UPDATE
- 19.06.2019: Es sind ein Freitextfilter mit Highligntning bei Kategorieen und auf- und zuklappbare Jahre im Archiv hinzugekommen. Ich hab es nun mal v1.0 genannt :-)
- 06.08.2019: Mein Twitter-Posting wurde auf dem Flatpress Channel eingefügt (s. Link [6])
weiterführende Links:
- Github: Projekt Seite des Themes
- Github: Theme A Touch Of Glass als ZIP
- Flatpress.org Blogging Engine in PHP ohne Datenbank
- Fontawesome Iconset
- Twitter: Axels Tweet
- Twitter: Flatpress Tweet … und Channel
Pimped Apache Status: über 500 Downloads im März
Ich bin leider erst soeben darüber gestolpert: diesen März gab es auf Sourceforge einen absoluten Peak von 565 Downloads im Monat.
Warum habe ich das nicht gesehen?
In die tageweise Statistik reingezoomt … davon waren 500 an einem Tag (19.3.) - ich glaube, da hat sich wer einen Scherz erlaubt und wget bemüht - oder gar öfter F5 im Browser gedrückt.
So schnell kann eine kleine Euphorieblase wieder platzen.
weiterführende Links:
- Axels Webseite - Docs Pimped Apache Status Get started - hier ist das Youtube Video
- Github: Pimped Apache Status
- Sourceforge: Pimped Apache Status