Autorenarchiv: Jörg Kastning

Meinung: DNS4EU – Kurz vorm Klo in die Hose gesch…

In diesem Jahr wird in Deutschland und der EU neben Künstlicher Intelligenz auch viel über digitale Souveränität diskutiert. Es ist kein Geheimnis, dass Europa bei IT-Anwendungen, Diensten und -Produkten den Anschluss an Nordamerika und Asien verloren hat bzw. sich freiwillig in eine Abhängigkeit begeben hat. Da erscheint DNS4EU wie ein kleiner LIchtblick.

Ein DNS-Dienst, betrieben in der EU, konform zur Datenschutz-Grundverordnung (DSGVO). Das hört sich erstmal gut an — ist es aber nicht.

Wie eine Recherche des IT-Consultant Jens Link ergab: „…,geht im Prinzip der gesamte Traffic durch Netze einer Firma außerhalb der EU.“ Genau gesagt durch Großbritanien, welches seit 2020 nicht mehr Mitglied der EU ist. Das ist aus mindestens den folgenden zwei Gründen ungünstig.

DNS-Datenverkehr ist meistens unverschlüsselt. Jede Person mit Zugriff auf den Datenverkehr kann mitlesen, wer wann welche Internetseite oder genauer gesagt Domain aufruft. Das ist nunmal so, unabhängig davon welche Route der Datenverkehr im Internet einschlägt.

England ist Mitglied der sogenannten Five Eyes, einer engen Kooperation der Geheimdienste aus Australien, Canada, England, Neuseeland und den USA. Für die Dienste dieser Staaten sind EU-Bürgerinnen und Bürger Angehörige von Drittstaaten, deren Daten zu geheimdienstlichen Zwecken gesammelt und ausgewertet werden dürfen. Spätestens seit der globalen Überwachungs- und Spionageaffäre ist bekannt, dass dies auch geschieht.

Was nützt es also, einen Dienst zu haben, dessen Betreiber sich zwar an die DSGVO im speziellen und die europäische Rechtsordnung im allgemeinen halten müssen, der gesamte Datenverkehr aber über jemanden geleitet wird, der daran nicht gebunden ist?

Den Ansatz und die Idee hinter DNS4EU finde ich gut, die Umsetzung mangelhaft. Solange der Datenverkehr den Rechtsraum der EU verlässt, bietet DNS4EU keinen Mehrwert zu bestehenden Diensten. Da bleibe ich lieber bei dnsforge.de oder den DNS-Resolvern meiner Internetdiensteanbieter.

Weitere Artikel zum Thema DNS in diesem Blog:

Zwischen Microblogging, TikTok-Videos und Social Media – Wo steht das Bloggen heute?

Ich lese und schreibe gerne. Lesen kann ich fast überall, ohne meine Umgebung zu stören. Gleichzeitig habe ich meine Ohren frei, um meine Konzentration schnell auf andere Dinge lenken zu können, ohne dass sich jemand durch Kopfhörer auf bzw. in meinen Ohren ausgeschlossen fühlt.

Ähnlich ist es mit dem Schreiben. Ich kann schreiben, während nebenbei das Fernsehen oder Radio läuft oder ich im Park oder einem Biergarten sitze. Podcasts und Videos lassen sich in diesen Umgebungen nur schwierig aufzeichnen.

Zudem bin ich in einer Zeit aufgewachsen, wo die Internetbandbreite noch so schmal war, dass an die flächendeckende Verbreitung von Audio und Video noch nicht zu denken war.

So ist das geschriebene Wort bis heute mein Favorit für die Aufnahme und Verbreitung von Wissen. Und damit sind Blogs für mich auch heute ein wichtiger und geschätzter Bestandteil des Internets, die für mich einen hohen Stellenwert besitzen.

Ich habe noch kein einziges TikTok-Video gesehen und kann dessen Stellenwert für die Gesellschaft nicht beurteilen. Ich finde generell nur sehr wenig Gefallen an Internetvideos, da sich bei mir der Eindruck verfestigt hat, dass diese häufig in die Länge gezogen werden, um noch eine Werbeunterbrechung oder Produktplatzierung unterbringen zu können. Ich fand bisher nur sehr wenige Videos hilfreich.

Wir Menschen sind jedoch teils sehr unterschiedlich und so ist mir bewusst, dass es natürlich auch eine Nutzergruppe gibt, welche Videos jederzeit den Vorzug vor einem Blogartikel gibt. Das ist auch vollkommen in Ordnung. Nutzt das Medium, welches euch am meisten anspricht.

Microblogging und Social Media sind für mich persönlich Synonyme für Mastodon. Hier folge ich meinen Bekannten, Freunden und interessanten Personen, deren Beiträge mich interessieren. Ich selbst teile hier meine Gedanken, Tageslaune und weise auf neue Artikel in meinem Blog hin. Falls ihr daran interessiert seid, findet ihr mich unter @Tronde@social.anoxinon.de.

Microblogging sehe ich es bestenfalls als Ergänzung zu einem Blog. Mit den Threads auf den diversen Plattformen konnte ich mich nie anfreunden. Wenn jemand etwas in mehr als 512 Zeichen ausdrücken möchte, freue ich mich, wenn dies in einem Blog niedergeschrieben wird, den ich gemütlich am Stück lesen kann.

Dies war nun meine Meinung. Welchen Stellenwert besitzen Blogs für euch?

Dieser Beitrag ist Teil der #BlogWochen2025, welche von von Benedikt, Dirk und Robert zum runden Geburtstag ihrer Blogs ausgerufen wurden.

Was ist das Red Hat Offline Knowledge Portal und wie betreibt man es als systemd.service?

In diesem Tutorial erkläre ich, worum es sich beim Red Hat Offline Knowledge Portal handelt, unter welchen Voraussetzungen man es nutzen kann und wie man es als systemd.service auf dem eigenen Rechner betreibt.

An einigen Stellen verweise ich auf die offizielle Red Hat Dokumentation, um das Tutorial nicht unnötig zu verlängern.

Was ist das Red Hat Offline Knowledge Portal?

Wie der Name suggeriert, handelt es sich um eine offline nutzbare Version des Red Hat Customer Portal und unserer Knowledge Base, Errata, Produktdokumentation, CVE-Datenbank und Red Hat Security Data API. Das folgende Bildschirmfoto zeigt die Startseite.

Startseite des Red Hat Offline Knowledge Portal

Ausgeliefert wird es als OCI-kompatibles Container-Image über registry.redhat.io (Authentifizierung erforderlich). Informationen zum aktuellen Image und den Vorgängerversionen finden sich auch im Red Hat Ecosystem Catalog. Der Inhalt wird wöchentlich aktualisiert und als aktualisiertes Container-Image bereitgestellt.

Wofür soll das gut sein?

Als Systemadministratoren oder Technical Account Manager (TAM) möchten wir auch auf die im vorstehenden Abschnitt genannten Informationen zugreifen können, wenn wir uns in einer Umgebung befinden, in der ein Internetzugriff nicht möglich ist. Darunter fallen zum Beispiel:

  • Vom Internet getrennte bzw. isolierte IT-Umgebungen
  • Einige Züge der Deutschen Bahn
  • Besprechungsräume und Büros mit bescheidener Signalstärke für das Diensttelefon
  • Umgebungen, in denen der Zugriff auf die Online-Informationen ermüdend langsam ist

Ich persönlich möchte das Offline Knowledge Portal zum Beispiel gerne auf meinem Arbeitslaptop dabei haben, um unterwegs jederzeit auf die darin enthaltenen Informationen zugreifen zu können. Es ist so schnell, dass ich nicht mehr auf Zug-WLAN, langsame Mobilfunkverbindungen oder die langsame Online-Version (an einer Verbesserung wird gearbeitet) warten muss.

Wer kann das benutzen?

Folgende Voraussetzungen müssen erfüllt sein, um das Offline Knowledge Portal nutzen zu können:

  • Es wird eine aktive Red Hat Satellite Subscription benötigt
  • Gültige Customer Portal, Red Hat Developer oder Registry Service Account -Zugangsdaten
  • Internetzugang, um das Container-Image herunterladen zu können
  • Eine rootless Podman Umgebung in Version 4.4 oder aktueller, welche diese Anforderungen erfüllt
  • Ein gültiger Offline Knowledge Portal access key
  • Zugangsdaten für registry.redhat.io in einer Datei für eine automatisierte Anmeldung liegen vor; siehe container-auth.json(5) für weitere Informationen

Wie kann man das dann benutzen?

Wer die schnelle Lösung sucht, findet diese in Chapter 1. Launching Red Hat Offline Knowledge Portal. Ich zeige an dieser Stelle, wie man das Offline Knowledge Portal als systemd.service konfigurieren und dann wie einen normalen Dienst steuern kann. Im folgenden Codeblock findet ihr mein Podman Quadlet, mit dessen Hilfe der systemd.service generiert wird. Die Datei habe ich in diesem Pfade abgelegt: ~/.config/containers/systemd/rhokp.container.

:~$ cat .config/containers/systemd/rhokp.container
[Unit]
Description=Red Hat Offline Knowledge Portal

[Container]
AutoUpdate=registry
ContainerName=RHOKP
Image=registry.redhat.io/offline-knowledge-portal/rhokp-rhel9:latest
PublishPort=127.0.0.1:8080:8080
PublishPort=127.0.0.1:8443:8443
Pull=newer
Secret=rhokp_access_key,type=env,target=ACCESS_KEY

[Service]
# Extend Timeout to allow time to pull the image
TimeoutStartSec=900

[Install]
# Start by default on boot
# WantedBy=multi-user.target default.target

Erklärung des Abschnitts [Container]:

  • AutoUpdate=registry
    • Aktiviert automatische Updates für den Container
    • Podman prüft dabei, ob in der Container-Registry eine neuere Version des Container-Images vorhanden ist, wenn der podman-auto-update.timer abgelaufen ist
  • ContainerName=RHOKP
    • Gibt dem Container einen Namen
    • Dieser wird in der Ausgabe von podman ps angezeigt
  • Image=registry.redhat.io/offline-knowledge-portal/rhokp-rhel9:latest
    • Fully qualified container reference
    • Der Tag latest ist zu verwenden, damit automatische Updates funktionieren
  • PublishPort=
    • Da ich das Offline Knowledge Portal auf meinem Arbeitslaptop ausführe und nur selbst nutze, binde ich den Dienst an die IP-Adresse 127.0.0.1
    • Soll der Dienst im Netzwerk angeboten werden, ist eine entsprechend erreichbare IP-Adresse zu verwenden
  • Pull=newer
    • Mit dieser Pull-Policy wird bei jedem Container-Start geprüft, ob eine neue Image-Version in der Container-Registry verfügbar ist und lädt diese ggf. herunter
    • Auf diese Weise muss ich nicht auf den Ablauf von podman-auto-update.timer warten
    • Es macht es mir einfacher, das Image auf meinem Laptop aktuell zu halten
  • Secret=rhokp_access_key,type=env,target=ACCESS_KEY
    • Ich habe meinen Offline Knowledge Portal Access Key in einem Podman-Secret namens rhokp_access_key gespeichert, welches beim Container-Start in die Umgebungsvariable ACCESS_KEY gemappt wird
    • So stelle ich sicher, dass mein Zugangstoken nicht in der Ausgabe von podman inspect auftaucht oder mit dem Container in eine Datei gespeichert wird und ggf. unkontrolliert mein System verlässt

Weitere Informationen finden sich in den Manpages podman-systemd.unit(5) und podman-secret(1).

Bitte beachtet, dass ich die letzte Zeile mit WantedBy= auskommentiert habe, da ich den Service auf meinem Laptop nur bei Bedarf starte. Wenn ihr den Dienst auf einem Server laufen lassen möchtet, der automatisch mitstartet, kommentiert die Zeile einfach ein.

Mit den folgenden Befehlen wird aus dem Quadlet ein systemd.service generiert und gestartet.

:~$ systemctl --user daemon-reload
:~$ systemctl --user start rhokp.service
:~$ systemctl --user is-active rhokp.service
active

Zusammenfassung

  • Ich muss mir nicht mehr den CLI-Befehl zum Start des Offline Knowledge Portal merken
  • Ich habe es auf meinem Arbeitslaptop stets dabei und griffbereit
  • Gesteuert wird es über vertraute systemctl-Befehle
  • Automatische Updates sind ebenfalls möglich

Wenn euch die Idee gefällt und ihr die Vorraussetzungen erfüllt, probiert es selbst aus.

PS: Es ist erfreulich schnell!

Linux-Server mit oder ohne Swap-Partition bereitstellen?

Wir schreiben das Jahr 2025. Die Frage, ob man Linux-Server mit oder ohne Swap-Partition betreiben sollte, spaltet die Linux-Gemeinschaft in einer Weise, wie wir es seit dem Editor War nicht mehr gesehen haben…

So könnte ein spannender Film für Sysadmins anfangen, oder? Ich möchte aber keinen Streit vom Zaun brechen, sondern bin an euren Erfahrungen und Gedanken interessiert. Daher freue ich mich, wenn ihr euch die Zeit nehmt, folgende Fragen in den Kommentaren zu diesem Beitrag oder in einem eigenen Blogpost zu beantworten.

  • Stellt ihr Linux-Server mit Swap-Partition bereit und wie begründet ihr eure Entscheidung?
  • Hat euch die Swap-Partition bei sehr hoher Speicherlast schon mal die Haut bzw. Daten gerettet?
  • War der Server während des Swapping noch administrierbar? Falls ja, welche Hardware wurde für die Swap-Partition genutzt?

Eine kleine Mastodon-Umfrage lieferte bisher folgendes Bild:

Schaue ich mir meine eigenen Server an, so ergibt sich ein gemischtes Bild:

  • Debian mit LAMP-Stack und Containern: 16 GB RAM & kein Swap
  • RHEL-KVM-Hypervisor 1: 32 GB RAM & 4 GB Swap
  • RHEL-KVM-Hypervisor 2: 128 GB RAM & kein Swap
  • RHEL-Container-Host (VM): 4 GB RAM & 4 GB Swap

Bis auf den Container-Host handelt es sich um Bare-Metal-Server.

Ich kann mich nicht daran erinnern, dass jemals einem dieser Systeme der Hauptspeicher ausgegangen ist oder der Swapspeicher genutzt worden wäre. Ich erinnere mich, zweimal Swapping auf Kunden-Servern beobachtet zu haben. Die Auswirkungen waren wie folgt.

Im ersten Fall kamen noch SCSI-Festplatten im RAID zum Einsatz. Die Leistung des Gesamtsystems verschlechterte sich durch das Swapping so stark, dass bereitgestellten Dienste praktisch nicht mehr verfügbar waren. Nutzer erhielten Zeitüberschreitungen ihrer Anfragen, Sitzungen brachen ab und das System war nicht mehr administrierbar. Am Ende wurde der Reset-Schalter gedrückt. Das Problem wurde schlussendlich durch eine Vergrößerung des Hauptspeichers gelöst.

Im zweiten Fall, an den ich mich erinnere, führte ein für die Nacht geplanter Task zu einem erhöhten Speicherverbrauch. Hier hat Swapping zunächst geholfen. Tasks liefen zwar länger, wurden aber erfolgreich beendet und verwendeter Hauptspeicher wurde anschließend wieder freigegeben. Hier entstand erst ein Problem, als der Speicherbedarf größer wurde und die Swap-Partition zu klein war. So kam es zum Auftritt des Out-of-Memory-Killer, der mit einer faszinierenden Genauigkeit immer genau den Prozess abgeräumt hat, den man als Sysadmin gern behalten hätte. Auch hier wurde das Problem letztendlich durch eine Erweiterung des Hauptspeichers gelöst.

Ich erinnere mich auch noch an die ein oder andere Anwendung mit einem Speicherleck. Hier hat vorhandener Swap-Speicher das Leid jedoch lediglich kurz verzögert. Das Problem wurde entweder durch einen Bugfix oder den Wechsel der Anwendung behoben.

Nun bin ich auf eure Antworten und Erfahrungsberichte gespannt.

Ein Blog sollte man immer dabei haben — auch offline

Der Name meines Blogs ist Programm. Es dient mir als digitales Gedächtnis für IT-Themen, die mich mich beschäftigt haben und die nochmal interessant werden können. Es ist eine Art Wissensdatenbank, auf die ich auch gerne zugreifen können möchte, wenn ich mal keine Internetverbindung habe.

Inspiriert durch den heutigen Beitrag von Dirk, möchte ich hier kurz beschreiben, was ich tue, um eine statische Version meines Blogs zu erstellen, welche ich einfach auf dem Laptop, Smartphone oder Tablet mitnehmen kann.

Ich verwende das Plugin Simply Static – The WordPress Static Site Generator, um eine statische Version meines Blogs zu erzeugen und als Zip-Archiv zu speichern. Möchte ich auf die statische Version meines Blogs zugreifen, entpacke ich das Zip-Archiv in ein Verzeichnis wie z.B. /tmp/simply-static/ und öffne anschließend in einem Webbrowser die Datei /tmp/simply-static/index.html.

Bildschirmfoto der statischen Version meines Blogs

So kann ich z.B. auch dann auf meine Artikel und Anleitungen zugreifen, wenn mein Webserver oder Internetzugriff nicht verfügbar ist. Die Suche auf der Seite funktioniert nur sehr eingeschränkt. Hier behelfe ich mir mit einer Dateisystemsuche im Terminal.

Ein paar Zahlen:

  • Dauer zur Erstellung des Zip-Archivs: ca. 10 Minuten
  • Größe des Zip-Archivs: 274 MB
  • Entpackte Größe: 355 MB
  • Rythmus der Erstellung: Wenn mir danach ist; in der Regel einmal pro Quartal

Mir gefällt an dieser Lösung, dass ich auf meinem mobilen Gerät keinen Container, ja noch nichmal einen Webserver, sondern nur einen Browser benötige. Das ist einfach, sparsam und robust.

Was haltet ihr davon ein Blog auf diese Weise offline verfügbar zu machen? Tragt ihr eure Blogs auch mit euch herum? Welche Werkzeuge nutzt ihr, um sie stets bei euch zu haben? Teilt euch gerne in den Kommentaren oder einem eigenen Blog mit.

Dieser Artikel ist Teil der #BlogWochen2025. Von Mai bis Oktober schreiben (zumindest) Robert, Dirk und ich über unterschiedliche Themen rund ums Bloggen. Du kannst gerne jederzeit einsteigen und mitmachen – die gesammelten Posts aller Teilnehmer:innen findest du auf dieser Seite und kannst sie auch als Feed abonnieren.

Codeberg.org mit Forgejo Actions, Runner, Workflows und ich

In diesem Artikel halte ich fest, was es mit den genannten Begriffen auf sich hat und was ich in den vergangenen Tagen mit ihnen angestellt habe. Dabei gehe ich auch auf das Warum ein, während Fragen nach dem Wie vorwiegend in den Verweisen im Text beantwortet werden.

Der Artikel dient mir als Dokumentation und meinen Leser:innen zur Unterhaltung und zum Wissenstransfer.

Codeberg.org

Codeberg ist eine demokratische, gemeinschaftsgetriebene, gemeinnützige Softwareentwicklungsplattform, die von Codeberg e.V. betrieben wird und sich um Codeberg.org, eine auf Forgejo basierende Software, dreht. Der Sitz des Vereins ist in Berlin. Hier wird Codeberg.org auch gehosted.

Auf Codeberg könnt ihr eure eigenen Freie Software-Projekte entwickeln, zu anderen Projekten beitragen, inspirierende und nützliche Freie Software durchstöbern, euer Wissen teilen oder euren Projekten mit Codeberg Pages ein Zuhause im Web geben, um nur einige Beispiele zu nennen.

Die beiden vorstehenden Abschnitte wurden übersetzt mit DeepL.com (kostenlose Version) und anschließend leicht angepasst und mit Links angereichert.

Mit Codeberg.org werden keine kommerziellen Interessen verfolgt. Man ist hier (nur) Nutzer und/oder Unterstützer, jedoch nicht selbst ein Produkt. Mir gefällt die Mission des Projekts. Daher bin ich dazu übergegangen, einen Teil meiner Repositories hier zu verwalten. Zwar bin ich kein Mitglied des Vereins, unterstütze diesen jedoch durch gelegentliche Spenden.

Actions, Runner und Workflows

Plattformen wie Codeberg.org, GitHub und GitLab unterstützen Softwareentwicklungsprozesse durch CI/CD-Funktionalität.

Ein Forgejo-Runner ist ein Dienst, der Workflows von einer Forgejo-Instanz abruft, sie ausführt, mit den Protokollen zurücksendet und schließlich den Erfolg oder Misserfolg meldet.

Dabei ist ein Workflow in der Forgejo-Terminologie eine YAML-Datei im Verzeichnis .forgejo/workflows eines Repositories. Workflows umfassen einen oder mehrere Jobs, die wiederum aus einem oder mehreren Steps bestehen. Eine Action ist eine Funktion zur Erfüllung häufig benötigter Aufgaben, bspw. Quelltext auschecken, oder sich bei einer Container-Registry einloggen etc. Siehe für weitere Informationen Abschnitt Hierarchy ff. im Forgejo Actions user guide.

Motiviert, meinen eigenen Forgejo-Runner zu installieren, haben mich zwei Blog-Artikel von meinem Arbeitskollegen Jan Wildeboer:

Durch den Betrieb eigener Forgejo-Runner kann ich bereits vorhandene Rechenkapazität nutzen. Es fallen für mich und den Verein Codeberg e.V. dadurch keine zusätzlichen Kosten an. Für die Installation auf RHEL 9 bin ich dem Forgejo Runner installation guide gefolgt, da das in Jans Artikel erwähnte Repository ne0l/forgejo offensichtlich nicht mehr gepflegt wird und nur eine veraltete Version des Runner enthält.

Ein Dankeschön geht raus an Jan für unseren kurzen und produktiven Austausch dazu auf Mastodon.

Wozu das Ganze?

Ich beschäftige mich beruflich seit einiger Zeit mit dem RHEL image mode und möchte demnächst einen meiner KVM-Hypervisor damit betreiben. Bis es soweit ist, arbeite ich eine Weile im „Jugend forscht“-Modus und baue immer wieder neue Versionen meiner Container-Images. Der Ablauf ist dabei stets derselbe:

  1. Containerfile(5) erstellen bzw. anpassen
  2. Container-Image mit podman-build erstellen
  3. Das erstellte Image mit podman-push in eine Container-Registry hochladen
  4. Das Deployment auf diversen Zielsystemen testen

Dazu verwende ich das RHEL 9 Bootc Base Image aus der Registry registry.redhat.io.

The rhel-bootc and user-created containers based on rhel-bootc container image are subject to the Red Hat Enterprise Linux end user license agreement (EULA). You are not allowed to publicly redistribute these images.

Quelle: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/using_image_mode_for_rhel_to_build_deploy_and_manage_operating_systems/introducing-image-mode-for-rhel_using-image-mode-for-rhel-to-build-deploy-and-manage-operating-systems#introducing-image-mode-for-rhel_using-image-mode-for-rhel-to-build-deploy-and-manage-operating-systems

Um vorstehender Anforderung gerecht zu werden, speichere ich das erzeugte Container-Image in einem privaten Repository auf Quay.io. Sowohl für registry.redhat.io als auch für quay.io ist ein Login erforderlich, bevor es losgehen kann.

Für mich bot sich hier die Gelegenheit, die Nutzung von Forgejo Workflows zu lernen und damit den Ablauf zur Erstellung meines RHEL Bootc Images zu automatisieren.

Forgejo Workflow und Runner-Konfiguration

Im folgenden Codeblock findet ihr meinen Forgejo Workflow aus der Datei .forgejo/workflows/build_image.yaml, gefolgt von einer Beschreibung der einzelnen Schritte. Zur Erklärung der Begriffe name, on, env, jobs, steps, run, etc. siehe Workflow reference guide.

name: build_image

on:
  push:
    branches: main

env:
  REPO_URL: https://codeberg.org/Tronde/rhel-bootc.git
  REPO_NAME: rhel-bootc
  IMAGE_NAME: quay.io/rhn-support-jkastnin/rhel-bootc:9.5

jobs:
  build:
    runs-on: podman
    steps:
      - run: dnf -y install git
      - run: echo ${{ secrets.RH_REGISTRY_TOKEN }} | podman login -u ${{ secrets.RH_REGISTRY_USERNAME }} --password-stdin registry.redhat.io

      - run: echo ${{ secrets.QUAY_ROBOT_TOKEN }} | podman login -u ${{ secrets.QUAY_USERNAME }} --password-stdin quay.io

      - run: git clone ${{ env.REPO_URL }}
      - run: podman build -f /workspace/Tronde/rhel-bootc/rhel-bootc/Containerfile -t ${{ env.IMAGE_NAME }}
      - run: podman push ${{ env.IMAGE_NAME }}
  1. Der Workflow wird jedes Mal ausgeführt, wenn ich einen Commit in den Branch main pushe
  2. Ich definiere einige Umgebungsvariablen, um bei Änderungen nicht alle Schritte im Workflow einzeln auf notwendige Änderungen prüfen zu müssen
  3. Mit `runs-on: podman` bestimme ich, dass der Workflow auf einem Runner mit dem Label podman ausgeführt wird; der entsprechende Runner started dann einen rootless Podman-Container, in dem die folgenden Schritte innerhalb von rootful Podman ausgeführt werden (nested Podman bzw. Podman in Podman)
  4. Git wird installiert
  5. Anmeldung an registry.redhat.io erfolgt
  6. Anmeldung an quay.io erfolgt
  7. Das Git-Repository wird geklont, um es auf dem Runner verfügbar zu haben
  8. Der Runner baut ein Container-Image (Erinnerung an mich selbst: Ersetze den hardcodierten Pfad durch eine Variable)
  9. Das erstellte Image wird in die Registry gepusht

Damit mein Runner den obigen Workflow ausführen kann, existiert auf diesem die Konfigurationsdatei /etc/forgejo-runner/config.yml, welche ich mit dem Kommando forgejo-runner generate-config > config.yml erstellt und anschließend angepasst habe. Der folgende Codeblock zeigt nur die Abschnitte, die ich manuell angepasst habe.

…
  fetch_interval: 20s
…
  labels: [
    "rhel-9-ubi:docker://registry.access.redhat.com/ubi9/ubi",
    "podman:docker://registry.access.redhat.com/ubi9/podman",
    "ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest",
    "act-runner:docker://node:20-bullseye",
    "centos-stream-9:docker://quay.io/centos/centos:stream9"]
…
  privileged: true
…

Ich greife mal die Zeile podman:docker://registry.access.redhat.com/ubi9/podman heraus:

  • podman: am Beginn der Zeile beinhaltet das Label, welches im Worflow mit runs-on verwendet wird
  • Mit dem Rest der Zeile wird bestimmt, in welchem Container-Image der Workflow ausgeführt wird
  • Ich habe mich für ubi9/podman entschieden, weil
    • ich bei Red Hat arbeite und daher
    • mit den Prozessen zur Erstellung unserer Images vertraut bin,
    • wodurch sich ein gewisses Vertrauen gebildet hat.
    • Ich vertraue unseren Images mehr, als jenen, die irgendein Unbekannter gebaut hat und deren Inhalt ich nicht kenne (man kann den Inhalt aber selbstverständlich überprüfen)
    • und ich so prüfen konnte, ob sich ein Image mit „unseren“ Werkzeugen bauen läst (nicht, dass ich daran gezweifelt hätte).

Die Angabe von privileged: true ist erforderlich, wenn man innerhalb des Containers ebenfalls mit podman oder docker arbeiten möchte.

Entscheidungen

Meinem weiter oben abgebildeten Workflow ist zu entnehmen, dass ich auf die Verwendung von Forgejo Actions verzichtet habe. Das hat folgende Gründe:

  • Für die Verwendung ist node auf dem Runner erforderlich
  • node ist im Image ubi9/podman standardmäßig nicht installiert
  • Node.js ist für mich das Tor zur Hölle und ich vermeide dessen Nutzung wenn möglich
  • Die Nutzung ist keine Voraussetzung, da ich mein Ziel auch so ohne Mehraufwand erreicht habe

Sobald die Workflows länger und komplexer werden, mag sich meine Einstellung zu Actions ändern.

Zusammenfassung

Ich habe gelernt:

  • Forgejo Runner zu installieren und zu konfigurieren
  • Wie Forgejo Workflows funktionieren und auf Codeberg.org genutzt werden können
  • Wie ich mir damit zukünftig die Arbeit in anderen Projekten erleichtern kann
  • Was für großartige Open Source Projekte Codeberg.org und Forgejo sind

Was uns antreibt zu bloggen

Vorwort

Die Blogs von Benedikt, Dirk und Robert feiern dieses Jahr Geburtstag. Zu diesem Anlass haben die Drei die #BlogWochen2025 ausgerufen. Jede Bloggerin und jeder Blogger ist eingeladen, dabei mitzumachen. Details könnt ihr in den Blogs der drei nachlesen:

Zum Thema des heutigen Tages steuere ich gerne einen Beitrag bei.

Was mich zum Bloggen antreibt

Ich verfolge mit meinem Blog drei Ziele:

  • Dinge aufschreiben, die mir hilfreich waren bzw. die ich nützlich finde und die ich in Zukunft noch einmal gebrauchen kann – Mein Blog ist mein Gedächtnis für IT-Dinge
  • Mein Wissen mit der Welt teilen, damit andere davon profitieren können
  • Meine Meinung mit der Welt teilen, um mit anderen ins Gespräch zu kommen und andere Meinungen kennenzulernen

Da es im IT-Bereich bereits sehr viele gute Blogs in englischer Sprache gibt, habe ich mich zu Beginn entschieden, in Deutsch zu bloggen, um zur deutschsprachigen Gemeinschaft beizutragen. Meine Idee war und ist, damit denen zu helfen, für die Englisch gegebenenfalls noch eine Hürde darstellt. Diesen Grundsatz behalte ich bis auf ganz wenige Ausnahmen bis heute bei. Meine Artikel in englischer Sprache veröffentliche ich an anderer Stelle.

Ich freue mich, wenn ich Rückmeldungen erhalte, dass jemand meine Texte hilfreich und nützlich fand und meine Leser Gefallen daran finden. Besonders freue ich mich, wenn darunter Perlen aus der Vergangenheit sind. Dies zeigt mir, dass selbst Artikel von vor über 10 Jahren noch eine gewisse Relevanz besitzen.

Diese Rückmeldungen sind es, die mich motivieren, nach immer neuen Themen zu suchen und diese für den Blog zu verschriftlichen.

Zudem muss ich jedes Mal schmunzeln, wenn ich im Internet die Antwort auf eine Frage suche und diese dann in meinem eigenen Blog finde. So stellt mein Blog inzwischen für mich eine wertvolle Wissensdatenbank dar, auf die ich regelmäßig und gerne zurückgreife.

Wie ist das bei euch? Lest und stöbert ihr gerne in Blogs? Favorisiert ihr andere Formate? Bloggt ihr selbst? Ich freue mich über eure Kommentare oder Blogposts zu diesem Thema.

Ansible Collection tronde.opencloud

In diesem Beitrag berichte ich über mein Wochenend-Projekt „Ansible Collection tronde.opencloud“, welche ihr seit dem 4. Mai 2025 in Version 1.0.0 auf Ansible Galaxy sowie bei Codeberg.org findet.

Ich habe die Collection mit den folgenden Zielen erstellt:

  • Deployment von OpenCloud mittels Ansible in einer rootless Podman-Umgebung
  • Backup der OpenCloud und Speicherung des Backups auf dem Ansible Control Node
  • Restore der OpenCloud aus einem zuvor erzeugten Backup

Aktuell läuft eine OpenCloud-Instanz auf einem meiner Server unter Debian Bookworm.

Nicht so schnell! Was sind Ansible, OpenCloud und Podman?

Derjenige, dem diese Begriffe bereits geläufig sind, kann direkt zum Abschnitt Motivation springen. Für alle anderen gibt es hier eine knappe Erklärung mit Verweisen zu weiteren Informationen, um sich mit der Materie vertraut zu machen.

Ansible

Ansible hat sich zu einem beliebten Schweizer Taschenmesser für Automation, Konfigurations-Management, Deployment und Orchestrierung entwickelt. Über folgende Links findet ihr reichlich informationen dazu:

OpenCloud

OpenCloud ist die Filesharing & Kollaborations-Lösung der Heinlein Gruppe.

Durch intelligentes Datei-Management und eine starke Open Source-Community werden Dateien zu wertvollen Ressourcen – effektiv strukturiert und langfristig nutzbar.

Quelle: https://opencloud.eu/de

Links zu weiteren Informationen:

Podman

Podman ist ein Werkzeug zur Erstellung von Linux-Containern und der Verwaltung des gesamten Container-Lebenszyklus. Links mit Informationen zu Podman:

Motivation

Ich betreibe und nutze privat eine Nextcloud, um Dateien über mehrere Geräte zu synchronisieren, mit anderen zu teilen und um Backups verschiedener Geräte und Dienste darin abzulegen. Dazu betreibe ich neben dem Reverse Proxy (NGINX) einen Container mit einer MySQL-Datenbank und einen Anwendungscontainer mit Nextcloud selbst. Nextcloud verfügt über ein reichhaltiges Plugin-Ökosystem zur Erweiterung der Funktionalität, welche ich persönlich allerdings nicht benötige.

OpenCloud ist wie Nextcloud ein Fork von OwnCloud. Siehe dazu den Bericht: Opencloud forkt Owncloud — neue Wendung bei den freien Speichercloud-Versionen im Linux-Magazin vom 22. Januar 2025.

Mir gefällt, dass OpenCloud ganz ohne Datenbank auskommt und sich auf die Synchronisation und das Teilen von Daten fokussiert. Dies entspricht genau meinem Anwendungsfall. Wenn ich dadurch einen Dienst weniger betreiben kann (MySQL), ist das umso besser.

Nur passt der gewählte Technologie-Stack nicht zu meiner persönlichen Vorliebe. Während OpenCloud auf die Verwendung von Docker Compose mit Traefik als Reverse Proxy setzt, bevorzuge ich, Container mit Podman zu betreiben und verwende (noch) NGINX als Reverse Proxy.

Um OpenCloud etwas kennenzulernen, habe ich beschlossen, analog zu meiner Ansible Collection tronde.nextcloud eine Collection tronde.opencloud zu erstellen, um OpenCloud deployen und verwalten zu können.

Ob sich der Aufwand lohnt, werde ich mit der Zeit sehen. Wenn es mir zuviel wird oder ich den Gefallen daran verliere, werde ich dieses Wochenendprojekt wieder einstellen bzw. gern in die Hände motivierter Menschen geben, die es weiterführen möchten.

Informationen zur Collection

Das Wichtigste zu dieser Collection habe ich bereits zu Beginn dieses Textes geschrieben. Neben den für Ansible Collections und Roles typischen README.md-Dateien habe ich auch ein paar Zeilen Dokumentation erstellt:

Die Collection steht unter einer freien Lizenz und ich gebe keinerlei Garantie oder Gewähr, dass euch deren Verwendung nicht direkt in den Untergang führt. ;-)

Die Collection kann (noch) nicht viel. Das Wenige scheint jedoch robust zu funktionieren. Wenn ihr neugierig seid, probiert sie gerne aus. Auch euer konstruktives Feedback ist mir stets willkommen.

Für mich ist dies ein Wochenend-Projekt, das mit etlichen anderen Themen um meine Zeit konkurriert. Erwartet daher keine schnellen Entwicklungsfortschritte. Wenn ihr gern daran mitwirken möchtet, bin ich dafür offen. Werft einen Blick in den kurzen Contribution Guide und legt los. Falls ihr Fragen habt oder euch mit mir über die Collection austauschen möchtet, könnt ihr

  • eure Frage als Issue mit dem Label „Question“ im Repository stellen oder
  • in den Matrix-Raum #My-IT-Brain posten.

Erster Eindruck von OpenCloud

Das noch recht junge Projekt macht einen aufgeräumten Eindruck. Die Benutzeroberfläche ist nicht überladen und ich finde mich schnell darin zurecht. Das Entwicklerteam antwortet bereitwillig auf Fragen und kümmert sich in angemessener Zeit um Issues. Dies ist zumindest mein subjektiver Eindruck.

Einziger Wermudstropfen ist wie so oft die Dokumentation, welche mit der Entwicklung offenbar nicht Schritt halten kann. Diese lässt leider noch viele Fragen offen, welche über GitHub Discussions oder Suche im Quelltext geklärt werden können/müssen. Ich empfinde dies etwas ermüdend und es drückt die Motivation.

Nun werde ich OpenCloud erstmal einige Zeit nutzen und ein paar Versions-Upgrades hinter mich bringen. Anschließend werde ich dann einen Meinungsartikel schreiben, wie es mir gefällt.

Einen Tang-Server auf Debian installieren

In diesem Text dokumentiere ich, wie ein Tang-Server auf Debian installiert werden kann und wie man den Zugriff auf diesen auf eine bestimmte IP-Adresse einschränkt.

Wer mit dem Begriff Tang-Server noch nichts anfangen kann und dies ändern möchte, dem empfehle ich: Network Bound Disk Encryption im Überblick.

Installation und Konfiguration

Installiert wird der Tang-Server mit folgendem Befehl:

sudo apt install tang

Standardmäßig lauscht der Tang-Server auf Port 80. Da dieser Port auf meinem Server bereits belegt ist, erstelle ich mit dem Befehl sudo systemctl edit tangd.socket eine Override-Datei mit folgendem Inhalt:

:~# cat /etc/systemd/system/tangd.socket.d/override.conf 
[Socket]
ListenStream=
ListenStream=7500

Mit den folgenden Kommandos wird die geänderte Konfiguration eingelesen, die Konfiguration kontrolliert und der Dienst gestartet:

:~# systemctl daemon-reload
:~# systemctl show tangd.socket -p Listen
Listen=[::]:7500 (Stream)
:~# systemctl enable tangd.socket --now

Zugriff auf eine IP-Adresse beschränken

Ich möchte den Zugriff auf den Tang-Server auf eine IP-Adresse beschränken, nämlich auf die IP-Adresse des einen Clevis-Clients, der diesen Server verwenden wird. Dazu führe ich die folgenden Schritte durch.

:~# iptables -A INPUT -p tcp -s 203.0.113.1 --dport 7500 -j ACCEPT
:~# iptables -A INPUT -p tcp --dport 7500 -j DROP
:~# mkdir /etc/iptables
:~# iptables-save >/etc/iptables/rules.v4

Damit die in der Datei /etc/iptables/rules.v4 gespeicherten Regeln nach einem Neustart wieder geladen werden, erstelle ich ein Systemd-Service:

:~# cat /etc/systemd/system/load-iptables.service 
[Unit]
Description=Load iptables rules
Before=network.target

[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore < /etc/iptables/rules.v4
#ExecStart=/sbin/ip6tables-restore < /etc/iptables/rules.v6

[Install]
WantedBy=multi-user.target

:~# systemctl daemon-reload
root@vmd54920:~# systemctl enable load-iptables.service
Created symlink /etc/systemd/system/multi-user.target.wants/load-iptables.service → /etc/systemd/system/load-iptables.service.

Test

Um zu überprüfen, ob der Tang-Server wie gewünscht arbeitet, setze ich auf meinem Clevis-Client den folgenden Befehl ab. Dabei muss nach der Ver- und Entschlüsselung der gleiche Text ‚test‘ ausgegeben werden.

~]$ echo test | clevis encrypt tang '{"url":"tang1.example.com:7500"}' -y | clevis decrypt
test

Fertig.

Wie kann ich mit GNU sed innerhalb eines Verzeichnisses rekursiv alle vorkommen eines Strings ersetzen?

Verwende find mit sed für die rekursive Textersetzung in allen Dateien:

find . -type f -exec sed -i 's/foo/bar/g' {} +
  • -type f: Bearbeitet nur Dateien (keine Verzeichnisse)
  • -exec ... +: Führt sed effizient auf mehreren Dateien gleichzeitig aus
  • sed -i: Überschreibt Dateien direkt („in-place“).

Die Antwort auf diese Frage lieferte perplexity.ai.