All articles

systemd-resolvd (v250) broken in testing

Every other distribution/version works but not systemd 250...

Debian 12

root@lxc-local-debian12:/# resolvectl
Global
       Protocols: +LLMNR +mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub

Link 2 (eth0)
Current Scopes: LLMNR/IPv4 LLMNR/IPv6
     Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported

Debian 11

root@lxc-local-debian11:/# resolvectl
Global
       Protocols: +LLMNR +mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub

Link 2 (eth0)
Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
     Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
   DNS Servers: 172.22.240.1

Docker-Gitea-Postgres Part 5: Posgres MD5- und SCRAM-Passwörter

Teil 5 einer Reihe über Gitea & Postgres im Docker-Container: Postgres MD5- und SCRAM-Passwörter

Hintergrund dieser Reihe ist das notwendige Update einer Docker-Gitea-Instanz und in diesem Rahmen auch das Major-Version-Upgrade der zugehörigen Postgres-Datenbank.

Postgres MD5- und SCRAM-Passwörter

Mit Version 10 hat Postgres Abschied von den alten und potentiell unsicheren MD5-Passwort-Hashes genommen. Ersatz dafür sind die sog. "SCRAM secrets". Das bedeutet aber auch, dass bei einem Major-Upgrade von 9 auf 10 (oder danach) alle Benutzer keine "passend" verschlüsselten Passwörter mehr haben.

Vorgeschichte

Nachdem Gitea nicht mehr starten bzw. dauerhauft laufen wollte, bin ich auf einigen Umwegen auf folgenden Log-Eintrag gestoßen:

root@docker:~ # docker logs gitea_db
[...]
FATAL:  password authentication failed for user "gitea"
DETAIL:  User "gitea" does not have a valid SCRAM secret.
    Connection matched pg_hba.conf line 100: "host all all all scram-sha-256"
[...]

Wenn man dies direkt im Container ausprobiert, kommt auch nur eine (wenig sagende) Fehlermeldung:

root@docker:~ # docker exec -it gitea_db bash
root@bash-5.1# psql -U gitea -h 172.31.3.2
  psql: error: connection to server at "172.31.3.2", port 5432 failed: FATAL:  password authentication failed for user "gitea"

SCRAM als Ersatz für MD5

Wenn man sich im Container umsieht, findet man auch die entsprechenden Stellen, an denen die Postgres-Instanz auf SCRAM konfiguriert wird;

root@bash-5.1# grep password_encryption /var/lib/postgresql/data/postgresql.conf 
#password_encryption = scram-sha-256    # scram-sha-256 or md5

root@bash-5.1# grep -v "^#\|^$" /var/lib/postgresql/data/pg_hba.conf 
local   all             all                                     trust
host    all             all             127.0.0.1/32            trust
host    all             all             ::1/128                 trust
local   replication     all                                     trust
host    replication     all             127.0.0.1/32            trust
host    replication     all             ::1/128                 trust
host all all all scram-sha-256

Natürlich ist das Ersetzen von MD5 durch einen stärkeren Algorithmus notwendig und zu begrüßen, letztendlich war es aber der Aufhänger für diese ganze Reihe von Artikeln ;)

Um jetzt zu sehen, welche Benutzer bereits ein SCRAM-Passwort haben, verbindet man sich mit der Datenbank und stellt eine Anfrage:

root@bash-5.1# psql -U gitea
psql (14.2)
Type "help" for help.

gitea=# SELECT rolname, rolpassword ~ '^SCRAM-SHA-256\$' AS scram_pw FROM pg_authid WHERE rolcanlogin;
 rolname | scram_pw 
---------+--------------
 gitea   | f
(1 row)

Man sieht, der Benutzer "gitea" hat offensichtlich noch kein SCRAM-Passwort ("f"alse).

Da es in diesem (Gitea-Docker-)Fall nur ein Benutzer ist, kann man das Passwort auch schnell von Hand setzen - wie es im .env, Ansible-Playbook, ... gesetzt wurde:

gitea=# \password gitea
Enter new password for user "gitea": 
Enter it again: 

Im Erfolgsfall gibt es keine weitere Ausgabe, stimmen die beiden Versuche nicht überein, kommentiert Postgres dies mit einem Passwords didn't match.. Die Datenbank-Commandline kann man per exit verlassen. Dann kann man auch nochmals kurz an der Commandline kontrollieren, ob der Benutzer nun ein SCRAM-Passwort hat:

root@bash-5.1# echo "SELECT rolname, rolpassword ~ '^SCRAM-SHA-256\$' AS scram_pw FROM pg_authid WHERE rolcanlogin;" | psql -U gitea
 rolname | scram_pw 
---------+--------------
 gitea   | t
(1 row)

Schluss

Nach dem Setzen des Passworts als SCRAM secret konnte sich der Gitea-Container wieder ohne Probleme an die neue Postgres-Instanz verbinden. Seit dem läuft Gitea und Postgres also wieder in aktueller Version!

Docker-Gitea-Postgres Part 4: Gitea startet nicht

Teil 4 einer Reihe über Gitea & Postgres im Docker-Container: Gitea startet nicht

Hintergrund dieser Reihe ist das notwendige Update einer Docker-Gitea-Instanz und in diesem Rahmen auch das Major-Version-Upgrade der zugehörigen Postgres-Datenbank.

Docker und Debugging - zwei Welten treffen aufeinander

Vorlauf

Bis zu diesem Schritt lief soweit alles problemlos ab:

  • Backup von Gitea - und auch dessen Restore auf einer anderen Maschine!
  • Backup der alten Postgres-9-Instanz
  • Testweiser Restore des Postgres-Backups auf einem Postgres-9 und Postgres-14

Gitea startet nicht mehr - oder doch?

Ein Versuch auf das Web-Frontend zuzugreifen, brachte verschiedene Fehler des Reverse-Proxys zu Tage. Ein Zugriff auf Gitea war aber nicht möglich.

Erst nach einiger Zeit und einigen docker ps -a fiel mir auf, dass der Gitea-Container sich offensichtlich immer wieder beendete - aber eben nicht sofort, sondern nach ca. einer Minuten. Er wurde dann wieder neu gestartet und nach einer weiteren Minute begann das Spiel von vorne. Von einem Blick in die Logs erhofft man sich ja Aufschluss, was da gerade vor sich geht:

root@docker:~ # docker logs gitea
Server listening on :: port 22.
Server listening on 0.0.0.0 port 22.
cmd/web.go:102:runWeb() [I] Starting Gitea on PID: 15
cmd/web.go:150:runWeb() [I] Global init
routers/init.go:107:GlobalInitInstalled() [I] Git Version: 2.30.3, Wire Protocol Version 2 Enabled
routers/init.go:110:GlobalInitInstalled() [I] AppPath: /usr/local/bin/gitea
routers/init.go:111:GlobalInitInstalled() [I] AppWorkPath: /app/gitea
routers/init.go:112:GlobalInitInstalled() [I] Custom path: /data/gitea
routers/init.go:113:GlobalInitInstalled() [I] Log path: /data/gitea/log
routers/init.go:114:GlobalInitInstalled() [I] Configuration file: /data/gitea/conf/app.ini
routers/init.go:115:GlobalInitInstalled() [I] Run Mode: Prod
Received signal 15; terminating.

Und das wiederholte sich immer und immer wieder. Die ersten beiden Zeilen kommen BTW vom OpenSSH-Server, welcher auch im Gitea-Container läuft.

Nach einiger Zeit (und Frust) bin ich dann wieder mal in den Container gegangen und hab dort nach weiteren Informationen gesucht. Und siehe da, im Gitea-Log-File stehen Informationen, die es - warum ich immer - nicht ins docker logs geschafft haben:

root@bash-5.1# cat /data/gitea/logs/gitea.log
[...]
routers/common/db.go:27:InitDBEngine() [I] ORM engine initialization attempt #8/10...
cmd/web.go:153:runWeb() [I] PING DATABASE postgres
routers/common/db.go:33:InitDBEngine() [E] ORM engine initialization attempt #8/10 failed. Error: pq: password authentication failed for user "gitea"
routers/common/db.go:34:InitDBEngine() [I] Backing off for 3 seconds
[...]

Warum zum Geier schafft es eine solch essentielle Fehlermeldung nicht in die docker logs?! Warum auch immer ich die Idee hat, mir im Container die Logs anzusehen - ohne diese Zeilen hätte ich vermutlich bald aufgegeben und wäre wieder auf die alte Postgres-Version zurückgegangen.

Was sagt denn die Datenbank dazu?

Mit diesem Hinweis schaute ich dann natürlich auch noch in die docker logs der Datenbank. Und siehe da:

root@bash-5.1# docker logs gitea_db
[...]
FATAL:  password authentication failed for user "gitea"
DETAIL:  User "gitea" does not have a valid SCRAM secret.
    Connection matched pg_hba.conf line 100: "host all all all scram-sha-256"
[...]

Der Fehler ist also weniger bei Gitea- als in der Postgres-Datenbank zu suchen - wobei "Fehler" hier natürlich auch nicht korrekt ist. Der alte, aus dem Backup stammende, gitea-Benutzer der Postgres-Datenbank hat einfach kein passend verschlüsseltes Passwort!

Das Setzen eines neue Passworts wird im Teil 5: Postgres MD5- und SCRAM-Passwörter beschrieben.

Fazit

Solche Dinge begegnen mir im Docker-Umfeld immer und immer wieder. Gar keine Logs, Logs nicht an der vermuteten/offiziellen Stelle, zu schnell rotiert Logs - Gründe dafür gibt's viele. Aber genau das sorgt dafür, dass man ohne tiefes Wissen gar keine Chance mehr hat, selbständig aus dieser Situation wieder herauszukommen. Docker wurde eingeführt, damit sich Admins mit gewissen Themen nicht mehr beschäftigen müss(t)en - aber dann eben einfach an einer Wand zerschellen, weil sie keine Ahnung (in diesem Fall rund um die Logs) haben...

Docker-Gitea-Postgres Part 3: Postgres Upgrade

Teil 3 einer Reihe über Gitea & Postgres im Docker-Container: Postgres Upgrade

Hintergrund dieser Reihe ist das notwendige Update einer Docker-Gitea-Instanz und in diesem Rahmen auch das Major-Version-Upgrade der zugehörigen Postgres-Datenbank.

Postgres

Major-Versionen, interne Struktur

Bis einschließlich zur Version 9 waren die zweistelligen Versionsnummern (die letzte Version war 9.6) die Haupt- oder "Major"-Versionen von Postgres. Dass die zweite Stelle im Allgemeinen bzw. bei vielen Projekten als "Minor"-Version bezeichnet wird, lief dem entgegen. Trotzdem war beim Sprung 9.5 auf 9.6 ein entsprechendes Vorgehen notwendig, da sich die interne Datenstruktur geändert hat (bzw. ändern hätte können) und die neuen Version nicht mit den alten Dateien auf der Platte umgehen konnte.

Ab der Version 10 sind jetzt auch bei Postgres Major-Versionssprünge an der ersten Stelle erkennbar, z.B. von 10 auf 11.

Die letzten Sprünge, an denen ein Upgrade nicht einfach durchgeführt werden konnte, waren folglich: 9.4 → 9.5 → 9.6 → 10 → 11 → 12 → 13 → 14

Welche Postgres-Versionen noch supported werden, kann man auf der "Versioning Policy"-Seite der Postgres-Dokumentation nachsehen.

Upgrade mit "pg_upgrade"

Seit einiger Zeit bringt Postgres ein Tool namens pg_upgrade mit, welches den alten und etwas aufwändigen Weg nicht mehr notwendig macht. Dieses Command ist allerdings auf einen Betrieb des Postgres-Servers auf einer "normalen" Linux-Installation (Host, VM, OS-Container, ...) ausgelegt und kann hier nicht helfen.

Als Alternative stehen allerdings mehrere Scripte, Tools und Docker-Container zur Verfügung, welche dieses Upgrade automagisch durchführen sollen (können). Da ich aber sowieso ein Backup der Datenbank machen möchte, bediene ich mich aus dem Skript des zweiten Teils dieser Reihe

Klassisches Upgrade

Das klassische Upgrade entspricht einem Backup, einem Upgrade des Postgres-Server und dem Restore. Die entsprechenden Schritte sind im zweiten Teil dieser Reihe (Postgres Backup) beschrieben.

Upgrade mit Docker

Ich habe mich inzwischen aus Sicherheitsgründen entschieden, das "alte" Daten-Docker-Volume erstmal aufzuheben und für die neue Postgres-Version ein neues Docker-Volume anzulegen. Erinnerung: Die neue Postgres-Version kann mit dem on-disk-format der alten Version leider nichts anfangen bzw. sie öffnen.

Folgende Schritte sind dann notwendig:

  • Den Gitea-Container stoppen, damit keine Schreibzugriffe (und später auch Lesezugriffe) auf die Datenbank kommen
  • Ein neues Volume (hier: gitea_db_14data, die 14 kommt von der Postgres-Major-Version) anlegen (lassen) - z.B. durch Anpassung im docker-compose.yml oder Ansible-Playbook oder wie auch immer die Container(-Volumes) angelegt werden/wurden.
  • Den Postgres-Container bzw. den Tag/Version im docker-compose.yml, Ansible-Playbook, ... entsprechend ändern und anlegen (lassen). In einem Fall habe ich ein Upgrade von 9-alpine auf 14-alpine durchgeführt und es hat problemlos funktioniert.
  • Den Datenbank-Container (und nur diesen) starten. Im Zweifelsfall beide Container starten und gitea wieder stoppen.
  • Anhand des zweiten Teiles dieser Reihe, Abschnitt "Restore im Docker" die Backup-Datei in den Container kopieren und wieder in die Postgres einspielen.
  • Den Gitea-Container wieder starten
  • Wen man sicher ist, dass es nicht mehr braucht wird, das Volume gitea_db_data (das alte Volume! Ohne "14"!) löschen.

Docker-Gitea-Postgres Part 2: Postgres Backup

Teil 2 einer Reihe über Gitea & Postgres im Docker-Container: Postgres Backup

Hintergrund dieser Reihe ist das notwendige Update einer Docker-Gitea-Instanz und in diesem Rahmen auch das Major-Version-Upgrade der zugehörigen Postgres-Datenbank.

Postgres

Backup allgemein

Um aus einer laufenden Postgres-Instanz (nahezu) alle Daten zu sichern, gibt es den Befehl pg_dumpall. Da das entstehende Backup reiner Text ist, wird es gleich in einem Rutsch mit xz komprimiert, damit es kleiner wird.

postgres@db:~ # pg_dumpall | xz >pg-backup.xz
[...]

Umgekehrt kann man auch einen Dump in eine (leere) Datenbank wieder einspielen :

postgres@db:~ # xzcat pg-backup.xz | psql -U <USERNAME> -d <DATABASE>

Backup im Docker

Da in den meisten Docker-Umgebungen nicht nur eine Postgres-Datenbank laufen wird, habe ich mir im Laufe der Zeit ein Script geschrieben, welches bei Übergabe des Container-Namens sich ein Backup auf den Host (konkret: ins aktuelle Verzeichnis) zieht:

root@docker:~ # .../postgres-backup.sh gitea_db
-rw-r--r-- 1 root root   115320 Apr 17 09:59 gitea_db_2022-04-17_09:59:23_postgres:9-alpine_9.6.24.xz

Im Backup-Dateinamen sind nacheinander Container-Name, Zeitstempel, Image-Name und Posgres-Version hinterlegt. So kann man auch z.B. im Rahmen eines Upgrades ;) nachvollziehen, mit bzw. auf Basis welcher Version das Backup angelegt wurde.

Das Script macht folgende Schritte:

  • (Zeile 3-13) Basierend auf dem übergebenen Namen wird die Container-ID ermittelt
  • (Zeile 14-19) Beginnt der zu Grunde liegende Image-Name nicht mit "postgres" wird das Script abgebrochen - es ist vermutlich kein Postgres-Container
  • (Zeile 21-29) Der Postgres-Username und -Version werden aus den Container-Umgebungsvariablen extrahiert
  • (Zeile 31-36) Der Backup-Dateinamen wird generiert und sichergestellt, dass es nicht bereits existiert
  • (Zeile 37-39) pg_dumpall wird aufgerufen, das Ergebnis durch xz komprimiert und ein ls -l auf die Datei angezeigt
#!/bin/ash

PGCONTAINER=$1
PGCONTID=$(docker ps -qf "name=^${PGCONTAINER}$")

if [ -z "$PGCONTID" ]; then
    echo "Container '${PGCONTAINER}' not found"
    exit 1
elif [ $(echo ${PGCONTID}| wc -m) -ne 13 ]; then
    echo "Unknown container id: ${PGCONTID}"
    exit 1
fi

DIMAGE=$(docker inspect ${PGCONTID} | jq '.[].Config.Image' | tr -d '"')
PGIMAGE=$(basename $DIMAGE | grep '\(^\|/\)postgres:')
if [ -z "${PGIMAGE}" ]; then
    echo "Not a Posgres image '${DIMAGE}'"
    exit 1
fi

export $(docker inspect ${PGCONTID} | jq '.[].Config.Env' | grep '"POSTGRES_USER\|"PG_VERSION' | tr -d '"' | sed -e 's/,$//')

if [ -z "${POSTGRES_USER}" ]; then
    echo "No Posgres user found"
    exit 1
elif [ -z "${PG_VERSION}" ]; then
    echo "No Postgres version number found"
    exit 1
fi

BACKUPFILE=${PGCONTAINER}_$(date +%F_%T)_${PGIMAGE}_${PG_VERSION}
if [ -f "${BACKUPFILE}.xz" ]; then
    echo "Backupfile exists"
    exit 1
fi

docker exec -it -w /tmp ${PGCONTID} sh -c "pg_dumpall -U ${POSTGRES_USER}" | xz >${BACKUPFILE}.xz

ls -l ${BACKUPFILE}.xz

Restore im Docker

Ich habe es nicht geschafft, die Backup-Datei vom Host aus direkt an einen psql in einen Container per Pipe zu übergeben. Falls hier jemand einen Tipp hat, gerne per Mail an mich ;)

Um also die Daten in den neu angelegten (oder umgezogenen oder...) Container zu bringen, kopiert man die Backup-Datei in den Container:

root@docker:~ # docker cp $BACKUPFILE gitea_db:/tmp/

Der zweite Schritt besteht dann darin, im Container das Backup wieder an Postgres zu verfüttern:

root@docker:~ # docker exec -it gitea_db bash
root@bash-5.1# psql -U gitea -d gitea < /tmp/gitea_db_2022-04-17_09:59:23_postgres:9-alpine_9.6.24.xz
root@bash-5.1# rm /tmp/gitea_db_2022-04-17_09:59:23_postgres:9-alpine_9.6.24.xz

Es macht natürlich keinen Sinn, das Backup im Container liegen zu lassen, es ist schließlich nur eine Kopie, daher wird es auch gleich wieder gelöscht.

Anmerkungen:

  • Meine Docker-Installationen laufen im Allgemeinen auf einem btrfs-Dateisystem. Daher ist Kopieren und Löschen ein Vorgang, der keinerlei Speicher benötigt. Läuft Docker allerdings mit irgendeiner Art von Images, dann ist dieser HD-/SSD-Speicherplatz bis zum nächsten Container-Anlegen und anschließendem "purge" verloren! Hier geht's nur um ca. 100kB, also wirklich nicht viel. Bei einer Multi-GiByte-Datenbank sieht das dann vielleicht anders aus!
  • Natürlich könnte man die Backup-Datei in ein temporäres Docker-Volume kopieren, dieses in den neuen Datenbank-Container einhängen und von dort das Restore machen. Der Aufwand war/ist mir aber zu groß.
  • Wer sofort seinen Speicher zurück möchte, der kann natürlich nach dem Restore den Container zerstören und neu anlegen. Dann ist der Speicher nach der nächsten Maintainance auch wieder frei.

Docker-Gitea-Postgres Part 1: Gitea Backup

Teil 1 einer Reihe über Gitea & Postgres im Docker-Container: Gitea Backup

Hintergrund dieser Reihe ist das notwendige Update einer Docker-Gitea-Instanz und in diesem Rahmen auch das Major-Version-Upgrade der zugehörigen Postgres-Datenbank.

Gitea

Backup allgemein

Gitea hat eine integrierte Backup-Funktion, welche man sehr einfach über die Command-Line aufrufen kann. Ergebnis ist dann eine ZIP-Datei, welche später oder wo anders wieder eingespielt werden kann:

gitea@gitea:~ # gitea dump -c .../app.ini --file /tmp/gitea-dump.zip

Backup im Docker

Wenn Gitea im Docker läuft, muss man natürlich auf die laufende Gitea-Instanz im Container zugreifen und anschließend die Sicherung aus dem Container holen. Dies kann mit dem folgenden Script passieren, welches der Sicherung am Schluss auch noch einen Zeitstempel verpasst:

#!/bin/ash

CONT_NAME=gitea
CONT_ID=$(docker ps -qf "name=^${CONT_NAME}$")
docker exec -u git -it -w /tmp ${CONT_ID} bash -c '/app/gitea/gitea dump -c /data/gitea/conf/app.ini --file /tmp/gitea-dump.zip'
docker cp ${CONT_ID}:/tmp/gitea-dump.zip .
docker exec -u git -it -w /tmp ${CONT_ID} bash -c 'rm /tmp/gitea-dump.zip'
BACKUPFILE=gitea-dump-$(date +"%Y%m%d%H%M").zip
mv ./gitea-dump.zip $BACKUPFILE

Da ich aktuell nur eine Gitea-Instanz am Laufen habe, ist der Container-Name im Script in Zeile 3 fest auf gitea gesetzt - natürlich kann man das Script an dieser Stelle erweitern und z.B. den Container-Namen an der Command-Line übergeben. Oder über ein Konstrukt eine Schleife bauen, welche gleich alle Gitea-Instanzen sichert.

Apropos Anpassungen: Meine Docker-Hosts nutzen AlpineLinux, daher ruft das Script in Zeile 1 eine ash auf - dies muss ggf. noch auf sh oder bash korrigiert werden.

Restore

Leider gibt es aktuell kein Restore-Command für Gitea. Die notwendigen Schritte sind jedoch IMHO ausreichend in der - nicht immer sehr ausführlichen - Dokumentation von Gitea unter Usage: Backup and Restore beschrieben. Bei mir haben die Schritte funktioniert - sowohl beim Restore als auch beim Umzug auf einen anderen Rechner/Host. Falls der Link nicht mehr gehen sollte, hier die Schritte:

# open bash session in container
root@docker:~ # docker exec --user git -it 2a83b293548e bash
# unzip your backup file within the container
root@bash-5.1# unzip gitea-dump-1610949662.zip
root@bash-5.1# cd gitea-dump-1610949662
# restore the gitea data
root@bash-5.1# mv data/* /data/gitea
# restore the repositories itself
root@bash-5.1# mv repos/* /data/git/repositories/
# adjust file permissions
root@bash-5.1# chown -R git:git /data
# Regenerate Git Hooks
root@bash-5.1# /usr/local/bin/gitea -c '/data/gitea/conf/app.ini' admin regenerate hooks

systemd is enterprise grade software...

systemd does not like to run with newer kernels if there are new capabilities...

root@buster:~ # systemctl show dnsmasq >/dev/null; echo $?
Failed to parse bus message: Invalid argument
1

I really like that software. NOT.

This breaks many software packages which (have to) use systemd, e.g. Ansible - see Github Ansible Issue #71528

Quick fix for Debian Buster/Backport's /usr/lib/python3/dist-packages/ansible/modules/system/systemd.py (Ansible 2.9.6)

Fixes should go into Ansible 2.10.4 and 2.9.16.

Using oci template with lxc-create

lxc-create -t oci does not work out of the box on Devuan 3 "Bewulf"/Debian 10 "Buster".

  1. Install umoci from distribution
  2. Install skopeo (Chimaera/Bullseye version) from e.g. http://ftp.de.debian.org/debian/pool/main/s/skopeo/
  3. Create /etc/containers/policy.json with
{
  "default": [
    {
      "type": "insecureAcceptAnything"
    }
  ],
  "transports":
    {
      "docker-daemon":
        {
          "": [{"type":"insecureAcceptAnything"}]
        }
    }
}

As Docker is not LXC most containers need some tuning in their config!

firewalld und permanente Port-Freigabe

Bei der Installation einer Appliance auf Basis von CentOS 7 wollte ich - wie immer - SSH auf "meinen" Port konfigurieren. Leider zeigte sich die Appliance und deren verpflichtende Verwendung von firewalld nicht ganz so kooperativ - sie bestand auf Port 22 🥴

Natürlich könnte man es in den Files der Appliance überschreiben, aber bei einem Update würden die Änderungen wieder platt gebügelt - also keine Alternative. Also habe ich in der "public"-Zone der Firewall einen neuen Port hinzugefügt, der dann ab sofort geöffnet wird. Das "--permanent" sorgt dafür, dass der Port auch nach einem Reboot wieder geöffnet wird:

% firewall-cmd --zone=public --add-port=2222/tcp --permanent

Dadurch bleibt dann leider Port 22 natürlich offen. Aber wer seine ~/.ssh/config im Griff hat kann ja z. B. Portsentry oder ähnliches auf diesen Port binden 😁

Apropos SSH-Port

Wenn schon jemand den SSH-Port ändert, dann bitte kreativ sein! Verwendet nicht

  • 22
  • 222
  • 2222
  • 2223
  • 4422
  • 6622
  • 8822
  • 9922
  • 22222

Diese Ports (und bestimmt noch mehr) sind in div. SSH-Scan-Scripts enthalten...

Debian und die /etc/network/interfaces

Ach ja, Debian...

Seit einiger Zeit hat ifupdown die Möglichkeit, nicht alle Netzwerk-Interfaces in /etc/network/interfaces zu pflegen, sondern diese z.B. in /etc/network/interfaces.d/ als kurze Dateien abzulegen. Gerade wenn man mal 10 VLANs und dazu jeweils eine Bridge hat (ja, ein Virtualisierungsserver), macht das die Sache IMHO deutlich übersichtlicher.

Wenn ich mich richtig erinnere, dann gab es zuerst die Möglichkeit per source /etc/network/interfaces.d/* einzelne Dateien bzw. Wildcards einzulesen. Später kam dann noch ein source-directory /etc/network/interfaces.d/ dazu.

Leider hat man es von Anfang an versäumt, statt nur "*" ein Suffix für die Schnippsel zu definieren, also z.B. source /etc/network/interfaces.d/*.iface - somit wird auch bei einem frisch installiertem Debian/Buster alles gelesen, was in diesem Verzeichnis liegt.

Das führt jetzt zu der dämlichen Situation, dass der Editor (der hoffentlich automatisch Backup-Files anlegt), nachdem man statt DHCP eine feste IP-Adresse eingetragen hat, folgendes hinterlässt:

root@buster:/etc/network/interfaces.d# ls
eth0.cfg  eth0.cfg~

Und was macht ein ifup eth0 draus? Das da:

root@buster:/etc/network/interfaces.d# ip a ls dev eth0
2: eth0@if28: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether fe:ac:16:f0:00:bb brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.10.10.10/28 brd 10.10.10.15 scope global eth0
       valid_lft forever preferred_lft forever
    inet 172.22.240.100/24 brd 172.22.240.255 scope global dynamic eth0
       valid_lft 3086sec preferred_lft 3086sec
    inet6 fe80::fcac:16ff:fef0:bb/64 scope link
       valid_lft forever preferred_lft forever

Die Lösung? Eigentlich GANZ einfach. Es gäbe ja sogar zwei...

  1. Entweder man definiert ein Suffix (z.B. *.iface, siehe oben) und macht dann source /etc/network/interfaces.d/*.iface, ignoriert also alles andere.
  2. Man stellt (zumindest bei Neuinstallationen) auf source-directory /etc/network/interfaces.d/ um, welches nur folgende RegExp zulässt: ^[a-zA-Z0-9_-]+$

Ich bin ein Freund von Zweiterem, deswegen stell ich das auch mit meiner Ansible-Grundinstallation um.

Gestern allerdings fiel mir das auf die Füße. Nach einem Reboot kam der vServer nicht mehr hoch. Warum? Darum:

root@buster:/etc/network/interfaces.d# ls
50-cloud-init.cfg

In der RegExp für source-directory ist kein Punkt dabei! Daher werden Dateien mit einem Suffix nicht gelesen. Darüber lässt sich jetzt auch streiten, ob das sinnvoll ist, klar. An anderer Stelle ist das aber (im Debian-System, z.B. Cron-Scripte, die per run-parts aufgerufen werden) dann auch wieder so, es zieht sich also durch. Ich fände es als Default immer noch besser, als Backup-Dateien (welche auf "~" enden) wie Schnippsel zu behandeln und sie einzulesen.

An anderer Stelle hat man gelernt: War es bei Apache 2 in Debian möglich, im Verzeichnis /etc/apache2/sites-enabled/ beliebige Dateinamen abzulegen, werden inzwischen nur noch Schnippsel mit der Endung "*.conf" inkludiert.

Fazit:
Durch eine unbedachte Default-Einstellung bei der Einführung eines eigentlich SEHR coolen Features (source mit "*" als Wildcard), hat man Probleme in der Zukunft vorprogrammiert.

Devuan (oder Debian) auf AMD Ryzen 5 Pro 4650G

Wer einen der neuen Ryzen-CPUs sein eigen nennt, wird schnell feststellen, dass es unter Devuan 3 "Beowulf" bzw. Debian 10 "Buster" mit der Grafikkarte gibt. Nach der Installation des Linux-Kernels 5.7 aus den Backports plus firmware-amd-graphics war das Problem erledigt. Zur Vervollständigung habe ich noch die AMD64-Microcode-Updates und die passenden X.org-Treiber installiert.

root@beowulf:~# apt install amd64-microcode xserver-xorg-video-amdgpu
root@beowulf:~# apt install -t beowulf-backports linux-image-amd64 firmware-amd-graphics

Archlinux hat mich auf die richtige Spur geleitet. Aber ich hab mal wieder festgestellt, dass Archlinux nix für mich ist ;)

Raspberry Pi: NFS-Root

(updated )
by Sven Velt

Nur als kurzer Link: http://youresuchageek.blogspot.de/2013/01/raspberrypi-root-over-nfs-share.html

Nuernberg Rams in der GFL2 (2. American Football "Bundesliga")

So ganz glauben kann ich's eigentlich noch nicht, aber es ist wohl war: Durch den Rückzug der Plattling Black Hawks aus der GFL (1. Liga) bzw. Verzicht auf den Startplatz in der GFL2 gab es einen freien Platz, der dem American Football Verband Bayern "zusteht". Und da die Nuernberg Rams in der abgelaufenen Regionalliga-Saison (3. Liga) den 2. Platz belegt haben, sind sie natürlich Kandidat Nummer 1 (gewesen).

Das heißt dann effektiv: Vier Jahre Spielbetrieb, vier mal Aufstieg, 31 gewonnene und nur 2 verlorene Spiele. Diese Statistik wird sich zwar vermutlich nächstes Jahr deutlich ändern (leider) und doch freu ich mich auf dann sieben Heimspiele (dieses Jahr waren's ja nur vier). Und das alles, obwohl ich nach dem ersten (verlorenen) Saisonspiel schon gedacht habe: Nur nicht absteigen! Das gilt dann wohl nächstes Jahr ;-)

PS: Weiß jemand schon was über die Auf-/Abstiegsmodalitäten 2012?

check_icmp liefert mit Squeeze mehr PerfDatas als mit Lenny

Alternativ-Titel: Keine PNP4Nagios-Graphen mehr mit check_icmp nach Squeeze-Upgrade

Irgendwann zwischen den Releases 1.4.12 (Lenny) und 1.4.15 (Squeeze) sind bei "check_icmp" zwei zusätzliche PerfData-Werte hinzugekommen "rtmin" und "rtmax". Beim Update meiner privaten Nagios-Installation ist mir das natürlich ziemlich auf die Füße gefallen, denn die vorhandenen RRD-Files von PNP4Nagios kannten nur die zwei bisherigen "rta" und "pl" PerfDatas bzw. Datasources.

Jetzt hätte man natürlich einfach alle RRDs, die es betrifft, löschen können, dann hätte sie PNP4Nagios wieder neu angelegt. Aber damit wären dann ja auch die alten Werte verloren gegangen. Also habe ich nach einer Lösung gesucht, wie man die RRD-Dateien erweitern kann.

Da das leider nicht so einfach möglich ist, habe ich mir ein Python-Skript geschrieben, dass letztendlich die Daten aus der RRD-Datei dump't (XML), das XML an den entsprechenden Stellen erweitert, und dann aus diesem "neuen" XML wieder eine RRD-Datei baut. Und siehe da, es funktioniert :)

BITTE VORHER DIE RRD-DATEIEN SICHERN!

Aufruf: add_ds.py [-v] Ping.rrd
Dadurch wir eine neue Datei "Ping.rrd.new" erzeugt, die entsprechend erweitert ist.

Theoretisch wäre es sogar möglich, das Tool folgendermaßen aufzurufen:
cd /var/lib/pnp4nagios/perfdata; add_ds.py --rename */Ping.rrd
ICH würd's aber nur mit einer vorherigen Sicherung machen ;-)

Update 1:
Das Skript ist so (vor)eingestellt, dass es genau für diesen Fall (Lenny->Squeeze) funktioniert.

Update 2:
Noch etwas genauer: Es überprüft, dass genau zwei ("--expect=2") DS/Datasources in der RRD-Datei existieren und fügt dann zwei weitere ("--addds=2") des Typs GAUGE ("--adddstype=GAUGE") hinzu. Über die Parameter kann man dies steuern und natürlich für andere Fälle auch andere Datasources hinzufügen.

Download
Da ich noch nicht ganz schlüssig bin, wo ich das Skript letztendlich hinlegen werde, wird es einfach mal hier angehängt.

Nagios-Portal Workshop in Hannover

Die letzten beiden Tage fand in Hannover der Nagios-Portal Workshop bei der Kassenärztliche Vereinigung Niedersachsen statt. Erst einmal ein herzliches Dankeschön an die KVN für die Bereitstellung der Räume und Getränke und natürlich auch dem Organisator für das Essen und das Rahmenprogramm!

Ich kann mich im Prinzip nur Wiederholen: Über solche Veranstaltungen kann man sich viel Input der verschiedenen Projekte holen, schnell einen Überblick über Neuigkeiten bekommen und natürlich kommen auch Gespräche mit anderen Nagios-Admins hier nicht zu kurz.

Deswegen nochmal ein Dank an die Veranstalter - und ich freu mich schon auf nächstes Jahr :)

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 »