Springe zum Inhalt

Kürzlich ergab sich das Problem, Syslog-Nachrichten an einen Remote-Host verschicken zu müssen, der sonst dazu verwendete Befehl logger auf dem System aber noch kein Verschicken an Remote-Systeme unterstützte. Leider gab es für das betreffende Gerät auch keine neuere Software, es handelte sich um eine externe Netzwerk-Festplatte von WD, ein My Book Live.

Wenn sonst keine entsprechenden Werkzeuge zur Verfügung stehen, ist es oft ein unterschätztes Feature, dass bash direkt an Netzwerkadressen senden oder von diesen empfangen kann. Glücklicherweise unterstützt die auf den Geräten installierte bash-Version das Lesen und Schreiben an Netzwerkadressen per TCP oder UDP. Das ursprüngliche Syslog-Nachrichtenformat, beschrieben in RFC3164, ist reiner Text. Gesagt getan, ein Skript muss her:

#!/bin/bash
 
SEVERITY=${1:-7}
MESSAGE=$2
LOGHOST=Hostname oder IP-Adresse des Remote-Syslog-Hosts
 
declare -A SEVERTIES=([emergency]=0 [alert]=1 [critical]=2 [error]=3 [warning]=4 [notice]=5 [informational]=6 [debug]=7)
re='^[0-9]+$'
if ! [[ $SEVERITY =~ $re ]]; then
        SEVERITY=${SEVERTIES[$SEVERITY]}
        if [ -z "$SEVERITY" ]; then
                echo Severity not found >&2
                exit 1
        fi
fi
read -d $'\0' PROCNAME ARGS </proc/$PPID/cmdline
echo "<13$SEVERITY>$PROCNAME[$PPID]: $MESSAGE" >/dev/udp/$LOGHOST/514

Das Skript hat zwei Parameter, der erste gibt den Schweregrad an, welcher als numerischer Wert oder in seiner Textdarstellung übergeben werden kann. Der zweite Parameter ist die Nachricht selbst. Vor dem ersten Aufruf muss noch der Inhalt der Variablen LOGHOST angepasst werden.

Wenn das Skript nun z.B. unter dem Namen rlog.sh abgespeichert wird, kann es aus anderen Skripten wie folgt aufgerufen werden (vorher nicht vergessen, das Skript auch ausführbar zu machen):

rlog.sh debug "Ich bin eine Testnachricht"

Natürlich muss auf der Empfängerseite auch ein syslog-Daemon auf dem Port 514 lauschen. In der Debian-Standardinstallation tut der dortige rsyslogd das nicht. Dazu muss die Datei /etc/rsyslogd.conf angepasst bzw. die Kommentarzeichen vor folgenden Zeilen entfernt werden:

module(load="imudp")
input(type="imudp" port="514")

Möchte man nun die von Remote eintreffenden Nachrichten auf dem Syslog-Host in eigene Logdateien schreiben, können unter /etc/rsyslog.d/ entsprechende Konfigurationdateien erstellt werden.

if $fromhost-ip == [ '192.168.0.191', '192.168.0.192', '192.168.0.193' ] then /var/log/nas.log
& stop

In diesem Beispiel werden Syslog-Meldungen, welche von den angegebenen IP-Adressen empfangen werden, in das Logfile /var/log/nas.log geschrieben.

Von jetzt an können auch die hier vorhandenen WD My Book Live Syslog-Nachrichten schreiben:

rlog.sh debug "Ich bin eine Nachricht von $HOSTNAME"

3

Für den Betrieb des dezentrale Netzwerk Friendica, welches auch hier auf einer eigenen Instanz läuft, müssen periodisch Nachrichten verschickt und notwendige andere Aufgaben abgearbeitet werden. Früher konnte dazu ein Cron-Job eingerichtet oder alternativ ein Addon installiert werden, welche diese Aufgaben periodisch ausführte. Mittlerweile hat Friendica dafür einen eigenen Daemon bekommen, dessen Einbindung in ein Debian-System mit systemd hier kurz vorgestellt wird.

Der Update-Daemon erzeugt ein PID-File, dessen Name und Pfad in der Konfigurationsdatei "config/local.config.php" eingestellt wird:

 'system' => [
  'pidfile' => '/run/friendica/daemon.pid',
 ],

Beim Systemstart existiert obiges Verzeichnis noch nicht. Debian verwaltet flüchtige Dateien und Verzeichnisse mit systemd-tmpfiles. Damit dieses Verzeichnis beim Systemstart automatisch angelegt wird, kann in die Datei "/etc/tmpfiles.d/friendica.conf" Folgendes eingetragen werden:

d /run/friendica 0755 www-data www-data -

Das Verzeichnis wird mit den angegebenen Berechtigungen und Eigentümer angelegt. Damit das Verzeichnis sofort zur Verfügung steht, wird folgender Befehl verwendet:

systemd-tmpfiles --create --prefix /run/friendica

Anschließend wird das Unit-File für systemd unter "/etc/systemd/system/friendica-daemon.service" mit folgendem Inhalt angelegt:

[Unit]
Description=Friendica daemon
After=network.target mysqld.service
Requires=network.target remote-fs.target nss-lookup.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/srv/friends
Type=simple
StandardOutput=null
StandardError=syslog
ExecStart=/usr/bin/php ./bin/daemon.php start
ExecStop=/usr/bin/php ./bin/daemon.php stop
PIDFile=friendica/daemon.pid
PrivateTmp=true
InaccessibleDirectories=/home /root /boot /opt /mnt /media
ReadOnlyDirectories=/etc /usr
Restart=always

[Install]
WantedBy=multi-user.target

Der Pfad bei WorkingDirectory muss auf den Pfad der lokalen Friendica-Installation angepasst werden. Anschießend werden die Unit-Files von systemd neu geladen:

systemctl daemon-reload

Jetzt kann der Update-Daemon mit systemd gestartet werden:

systemctl start friendica-daemon.service

Nach dem erfolgreichen Start schreibt der Update-Daemon seine PID in die oben angegebene Datei "/run/friendica/daemon.pid". Die gleiche PID sollte in der Ausgabe des folgenden Befehls angezeigt werden:

systemctl status friendica-daemon.service

Sollte bis hier hin alles korrekt verlaufen sein, kann der Update-Daemon für den automatischen Start beim Systemstart aktiviert werden:

systemctl enable friendica-daemon.service