IP im Webauftritt blockieren

Samstag, 25. November, 2023

Heute Abend hat mein Appmonitor [1] festgestellt, dass meine Webseite keine Antworten mehr beim Monitoring-Check sendet.
Nach einigen Minuten kam der Webservice wieder … und verabschiedete sich aufs Neue.

In der Webseitenstatistik Matomo [2] war schnell ein potentieller Kandidat gesichtet, der “etwas” mehr als üblich Seiten vom Webauftritt abruft: 4000 Requests über 5 Stunden - das ist mehr als das übliche Mass von 1 bis 2-stelligen Seitenaufrufen von einem Benutzer.

2023-11-24-many-requests-fra.png

Abhilfe:

Mein Provider nutzt den Apache Httpd. In der .htaccess im Webroot habe ich die gefundene IP blockiert. Matomo anonymisiert die IP-Adressen - ich sehe sie nicht komplett. Ich war so frei und habe den kompletten D Block ausgeknipst.

...
# -- DENY given IP addresses --
<RequireAll>
    Require all granted

    # 2023-11-24 Roubaix FRA - provider ip-15-235-42.net
    Require not ip 15.235.42.0/24 

</RequireAll>
...

Weiterführende Links

  1. IML Appmonitor Docs (Freie Software; PHP) Source
  2. matomo.org - Webseiten-Analyse (Freie Software; PHP und Mysql)

Dokus für 2 Bash-Projekte

Freitag, 25. August, 2023

Ich skripte meine Dinge hauptsächlich in Bash.
Und weil niemand etwas nutzt, was nicht dokumentiert ist, habe ich 2 neue Dokumentationen online gestellt:

(1)

Kürzlich habe ich eine Bash-Komponente geschrieben, die die Handhabe der ANSI Farben vereinfacht.
Man kann eingfach Farben für Vordergrund und Hintergrund setzen - mit Namen einer Farbe oder HTML-CSS-Farbangabe.

Doc zu bash_colorfunctions

Rein zur Veranschaulichung: damit kann man farbige Texte ausgeben mit

color.echo "white" "green" "Yep, it seems to work!"

… oder aber die Farbe nur setzen, um nachfolgende Kommandos in jener Farbe die Ausgabe machen zu lassen. Zum Aufheben der Farbdefinition ruft man ein color.reset auf:

color.fg "blue"
ls -l
color.reset

(2)

Schon einige Monate auf Github ist mein Projekt, das mit Hilfe eines lokal installiertten Nginx den Zugriff auf eine Webapplikation als Docker Container mit Https und mit Namen der Applikation ansprechen lässt.

Doc zu nginx-docker-proxy

Beide Projekte sind freie Software und Opensource.

Bash: lsup zur Anzeige der Dateiberechtigungen

Donnerstag, 25. Mai, 2023

Wie oft ich das schon im Linux Filesystem gebraucht habe: in einem aktuellen oder angegebenen Verzeichnis prüfen, ob der Linux-Benutzer XY bis dorthin “durchkommt” und Berechtigungen in einem Verzeichnis oder auf eine Datei hat.

Also schrieb ich ein Shellskript. Man ruft es mit einem Parameter für ein zu prüfendes Verzeichnisses auf. Oder ohne Parameter für das aktuelle Verzeichnis.

Ich fange mal mit dessen Ausgabe an:

$ lsup
drwxr-xr-x 1 root root       244 Apr  2 23:34 /
drwxr-xr-x 1 root root       100 Jun  4  2022 /home
drwx------ 1 axel autologin 1.7K May 25 18:17 /home/axel
drwxr-xr-x 1 axel autologin  232 May 25 19:50 /home/axel/tmp

Ab dem Root-Verzeichnis werden mit ls -ld alle Verzeichnisebenen bis zum angegebenen Punkt angezeigt.
Syntax:

$ lsup -h

===== LSUP v1.3 :: make an ls upwards ... =====

Show directory permissions above by walking from / to the given file.
You can add no or one or multiple files as params.

SYNTAX:
  lsup                 Walk up from current directory
  lsup FILE [FILE N]   Walk up from given file/ directory
                       If the target is relative it will walk up
                       to the current directory
  lsup -h              Show this help and exit

EXAMPLES:
  lsup
  lsup .
  lsup /var/log/
  lsup my/relative/file.txt
  lsup /home /tmp /var

Zur Installation: als User root;: cd /usr/bin/ und nachfolgenden Code in eine Datei namens “lsup” werfen und ein chmod 0755 lsup hinterher.

#!/usr/bin/env bash
# ======================================================================
#
# Make an ls -d from root (/) to given dir to see directory  
# permissions above
#
# ----------------------------------------------------------------------
# 2020-12-01  v1.0  Axel Hahn
# 2023-02-06  v1.1  Axel Hahn  handle dirs with spaces
# 2023-02-10  v1.2  Axel Hahn  handle unlimited spaces
# 2023-03-25  v1.3  Axel Hahn  fix relative files; support multiple files
# ======================================================================

_version=1.3

# ----------------------------------------------------------------------
# FUNCTIONS
# ----------------------------------------------------------------------
function help(){
 local self=$( basename $0 )
 cat <<EOH

===== LSUP v$_version :: make an ls upwards ... =====

Show directory permissions above by walking from / to the given file.
You can add no or one or multiple files as params.

SYNTAX:
  $self                 Walk up from current directory
  $self FILE [FILE N]   Walk up from given file/ directory
                       If the target is relative it will walk up
                       to the current directory
  $self -h              Show this help and exit

EXAMPLES:
  $self
  $self .
  $self /var/log/
  $self my/relative/file.txt
  $self /home /tmp /var

EOH
}

# ----------------------------------------------------------------------
# MAIN
# ----------------------------------------------------------------------

if [ "$1" = "-h" ]; then
    help
    exit 0
fi

test -z "$1" && "$0" "$( pwd )"

# loop over all given params
while [ $# -gt 0 ]; do
    # param 1 with trailing slash
    mydir="${1%/}"
    if ! echo "$mydir" | grep "^/" >/dev/null; then
        mydir="$( pwd )/$mydir"
    fi

    ls -ld "$mydir" >/dev/null 2>&1        || echo "ERROR: File or directory does not exist: $mydir" 
    ls -ld "$mydir" >/dev/null 2>/dev/null || exit 1

    mypath=
    arraylist=()
    arraylist+=('/')

    IFS="/" read -ra aFields <<< "$mydir"
    typeset -i iDepth=${#aFields[@]}-1

    for iCounter in $( seq 1 ${iDepth})
    do
        mypath+="/${aFields[$iCounter]}"
        arraylist+=( "${mypath}" )
    done

    # echo ">>>>> $mypath"
    eval "ls -lhd ${arraylist[*]}"
    shift 1
    test $# -gt 0 && echo
done

# ----------------------------------------------------------------------

Viel Spass damit!

Fontawesome Upgrade von Version 5 auf Version 6

Dienstag, 23. Mai, 2023

Um Fontawesome von Version 5 auf 6 zu aktualisieren, gibt es einen Upgrade-Guide [1].

Aber das ist viel zu kompliziert :-)

nachdem ich einige Web-projekte umgestellt habe (das Intranet unseres Instituts, IML Appmonitor, ahCrawler, Pimped Apache Status) kann ich meinen Ansatz präsentieren:

  1. Man entferne das eingebundene CSS File von Fontawesome 5 und ersetze es durch das der Version 6, z.B.:
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
  2. Die meisten Icons sollten nach wie vor da sein. Aber wir aktualisieren einmal die Schreibweise der CSS Klassen für die Version 6.
  3. im Projketordner Suchen und Ersetzen “fas fa” –> “fa-solid fa”
  4. im Projketordner Suchen und Ersetzen “far fa” –> “fa-regular fa”

Damit sind 98% erledigt. Nun sollte man die Webseite nochmal genau anschauen. Es kann sein, dass es noch das ein oder andere Prefix umzustellen gilt (z.B. für Brands). Oder aber es gibt auch einige (wenige) Icons, die nun anders heissen - wenngleich sich diese vielleicht nur schwer finden lassen - für diese muss man in [2] die neue Schreibweise ermitteln.

Viel Glück bei der Umstellung!

Weiterführende Links:

  1. Fontawesome.com: Upgrade (en)
  2. Fontawesome.com: frei verwendbare Icons durchsuchen (en)

Pimped Apache Status - PHP 8.2 kompatibel

Montag, 22. Mai, 2023

Der Pimped Apachestatus ist ein Webtool, dass die etwas schwer verdauliche Apache Serverstatus Page aufbereitet. Es gibt verschiedene Ansichten, sortier- und filterbare Tabellen und Graphen. Das ganze funktioniert nicht nur für einen einzelnen Server, sondern auch für mehrere Webhosts, z.B loadbalante Webeiten.

2023-05-22-pimped-apache-status.png

Am Wochenende gab es ein Update, in dem einige Vendor-Bibliotheken aktualisiert wurden.

Da die als kompatibel bestätigte Version 8.0 alsbald ausläuft, wurde es mit neueren PHP Versionen getestet. Es ist nunmehr PHP 8.2 kompatibel.

Zum Aktualisieren meldet sich der Updater. Bei Installationen mit git bitte git pull verwenden.

Weiterführende Links:

Bash-Skript - einfaches Multi-Ping-Monitoring in Fast-Echtzeit

Mittwoch, 10. Mai, 2023

Ich brauchte da auf die Schnelle mal was: ich wollte mehrere Systeme mit Ping antesten, ob sie im Netz sind.
Die Liste der zu testenden Systeme sollte untereinander stehen und pro System angeben; ich bin erreichbar … oder auch nicht.

Ja natürlich haben wir ein System-Monitoring, aber das ist etwas träge - ich wollte das Ganze alle wenige Sekunden aktualisieren. Im Rack wollte ich Kabel ziehen und umstecken - und nebenher sehen, welches Gerät offline geht und wieder da ist.

Hier mein Bash-Skript:

#!/bin/bash

cfgfile="$0.cfg"

while true; do
    clear
    echo ">>>>> PING TEST :: $( date )"
    echo 
    cat "$cfgfile" | grep "^[a-z1-9]" | while read -r target
    do
        printf "%-35s > " $target
        if ! ping -c1 $target 2>&1 | grep "transmitted"; then
            echo "FAILED"
        fi
    done
    sleep 1
done

Im Endlos-Loop wird der Bildschirm gelöscht, ein Header mit Datum ausgegeben. Ich lese eine Datei aus, die meine Liste von Geräten enthält.
Ein Gerät wird einmalig angepingt (Parameter -c 1) - genau das geht sehr schnell. Es wird ausgegeben, ob es erreichbar war oder nicht.
Nach Abarbeiten der Liste folgt ein sleep 1 - und nach dieser nur kurzen Wartezeit geht es von vorn los.

Die Configdatei mit der Liste der Server - je einer pro Zeile - Leerzeilen, Kommentare u.ä werden ignoriert:

#
# my server list
#
server-01.example.com
server-02.example.com
server-03.example.com
server-04.example.com
server-05.example.com

Das Ganze sieht in der Ausgabe am Terminal grob aus:

 >>>>> PING TEST :: Mi 10 Mai 2023 16:37:41 CEST

server-01.example.com               > 1 packets transmitted, 1 received, 0% packet loss, time 0ms
server-02.example.com               > 1 packets transmitted, 1 received, 0% packet loss, time 0ms
server-03.example.com               > 1 packets transmitted, 1 received, 0% packet loss, time 0ms
server-04.example.com               > 1 packets transmitted, 1 received, 0% packet loss, time 0ms
server-05.example.com               > FAILED 

A Touch Of Glass - Update

Mittwoch, 10. Mai, 2023

Das war ja ärgerlich: die Loginseite erschien nicht mehr. Ich hatte es nicht bemerkt, weil mein Login gespeichert war und ich mich nicht mehr interaktiv eingeloggt habe.

Ich hatte zuletzt in den (Smarty) Templates alle Includes mit Hochkommas versehen.

{include file='widgets.tpl'}

Dummerweise auch in der defaults.tpl, wo eine Variable drin war - das hier hingegen funktioniert natürlich nicht:

{include file='$content'}

Die Hochkomma müssen bei Variablen weg. Das wurde nun korrigiert.

Weiterführende Links:

Benachrichtigungen mit notify-send als root und per cron

Sonntag, 16. April, 2023

Mein Backup-Skript (es dumpt lokale Datenbanken, unterstützt zig Hooks, sichert mit Restic/ Duplicity) kennt einen neuen Trick.
Auf meinem Linux-Desktop wollte ich Popup-Informationen zu einem im Hintergrund (Cronjob als root) gestarteten Skript sehen.

Und wie geht das?

Eine gängige Lösung ist notify-send (aus dem Paket libnotify).

$ notify-send --help
Usage:
  notify-send [OPTION?] <SUMMARY> [BODY] - create a notification

Help Options:
  -?, --help                        Show help options

Application Options:
  -u, --urgency=LEVEL               Specifies the urgency level (low, normal, critical).
  -t, --expire-time=TIME            Specifies the timeout in milliseconds at which to expire the notification.
  -a, --app-name=APP_NAME           Specifies the app name for the icon
  -i, --icon=ICON                   Specifies an icon filename or stock icon to display.
  -c, --category=TYPE[,TYPE...]     Specifies the notification category.
  -e, --transient                   Create a transient notification
  -h, --hint=TYPE:NAME:VALUE        Specifies basic extra data to pass. Valid types are boolean, int, double, string, byte and variant.
  -p, --print-id                    Print the notification ID.
  -r, --replace-id=REPLACE_ID       The ID of the notification to replace.
  -w, --wait                        Wait for the notification to be closed before exiting.
  -A, --action=[NAME=]Text...       Specifies the actions to display to the user. Implies --wait to wait for user input. May be set multiple times. The name of the action is output to stdout. If NAME is not specified, the numerical index of the option is used (starting with 0).
  -v, --version                     Version of the package.

Das funktioniert problemlos im Kontext des aktuell eingeloggten Benutzers mit einer X-Session.
Aber mit sudo oder als Cronjob als root?

Aber eines nach dem Anderen.

Wenn ich ein Skript mit sudo starte, dann enthält die Umgebungsvariable SUDO_USER denjenigen Benutzer, der das sudo ausgelöst hat. Das Skript läuft dann als User root. Das notify-send soll aber nicht auf einer X-Session des root Users etwas enblenden, sondern einem anderen unprivilegierten Benutzer. Hier kommt die Variable DBUS_SESSION_BUS_ADDRESS ins Spiel. Wenn man die UID des Benutzers kennt, kann man es sich zusammensetzen. Diese bekommt man mit id -u [Benutzername] … und der Benutzername ist ja in SUDO_USER.

Snippet:

if [ -n "$SUDO_USER" ]; then
  export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u $SUDO_USER)/bus
fi

Mit jenem Snippet kann man im selben Skript auslösen

su "$SUDO_USER" -c "notify-send 'Titel' 'Mein Nachrichtentext'"

und es kommt bei … genau: “meinem” Desktop an und nicht bei root. Wunderbar!

Jetzt ist da noch die Sache mit dem Cronjob als root. Hier ist ja kein sudo. Aber das ist gar banaler als man denkt: man setzt einfach die Variable SUDO_USER im Environment - also vor den Deinitionen der Zeitangaben und Aufrufe:

$cat /etc/cron.d/client-backup 
SUDO_USER=axel
17 * * * * root /usr/local/bin/cronwrapper.sh 1440 /opt/imlbackup/client/backup.sh 'iml-backup'

Feintuning:

ein Simples notify-send “Titel” “Mein Nachrichtentext” verschwindet nach ein paar Sekunden. Wenn ein Fehler auftritt, dann möchte ich die Meldung sehen, lesen und proaktiv verschwinden lassen. Genau das erledigt der Parameter –urgency für uns

notify-send –urgency=critical “Fehler” “Da ging etwas schief :-/”

Hier noch ein kompletteres Bash Snippet:

if [ -n "$SUDO_USER" ]; then
  export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u $SUDO_USER)/bus
fi

(...)

# show a desktop notification using notify-send
# param  string   summary (aka title)
# param  string   message text
# paran  integer  optional: exitcode; if set it adds a prefix OK or ERRROR on summary and sets urgency on error
function notify(){
  local _summary="$1"
  local _body="$( date +%H:%M:%S ) $2"
  local _rc="$3"

  local _urgency="normal"

  if [ -n "$DBUS_SESSION_BUS_ADDRESS" ]; then
    if [ -n "$_rc" ]; then
      if [ "$_rc" = "0" ]; then
        _summary="OK: ${_summary}"
      else
        _summary="ERROR: ${_summary}"
        _urgency="critical"
      fi
    fi
    su "$SUDO_USER" -c "notify-send --urgency=${_urgency} '${_summary}' '${_body}'"
  fi
}

Timeshift und Prozentrechnung

Sonntag, 2. April, 2023

Timeshift speichert Snapshots eines Linux-Systems. Es kann sich u.a. als Hook in den Paketmanager einklinken und vor jedem Update einen Snapshot anlegen, um im Falle eines Nicht-Funktionierens zurückzurollen.

  • Wenn die Snapshots auch auf der Systemdisk abgelegt werden, wird das Grub-Menü um die Auswahl der letzten Snapshots erweitert.
  • Falls nicht, wird ein Rsync zum Sichern des Snapshots bemüht. Wenn man sein Linux booten kann (also notfalls von USB Stick), kann man Timeshift auch so einen anderen Stand wiederherstellen lassen.

Einen kleinen Schönheitsfehler gibt es aber. Im CLI Modus gibt Timeshift eine Fortschrittsinfo aus. Dumm nur, wenn es bei 100% gar nicht fertig ist.

2023-04-02-timeshift.png

Naja, ich kann darüber hinwegsehen. Wenn der Moment kommt, wo man mal ein Backup braucht, ist man froh um jeden verfügbaren Zwischenstand von so vielen Informationen wie möglich.

Ich fahre auf meinen Linux-PCs mit einer Kombination von Timeshift und Restic (IML Backup). Aber man will ja selbst keinen interaktiven Aufwand und sich nicht darum kümmern. Aber ich weiss, dass ich mich auf das Funktionieren beider Varianten in deren Kombination mit Snapshots und Datei-Backups verlassen kann.

Weiterführende Links

Theme “A touch of glass” aktualisiert

Mittwoch, 29. März, 2023

Ich habe einmal für den Blog Flatpress ein Theme bereitgestellt.

Die schlechte Nachricht: Nach Update auf die aktuelle Flatpress-Version ging leider nicht mehr viel.
Die gute: es war einfach zu beheben.

2023-03-29_atog.png

Weiterführende Links