Normale Ansicht

Es gibt neue verfügbare Artikel. Klicken Sie, um die Seite zu aktualisieren.
Ältere BeiträgeHaupt-Feeds

Wie ich die Chemnitzer Linux-Tage 2024 erlebt habe

25. März 2024 um 06:00

Dies ist mein Erfahrungsbericht der Chemnitzer Linux-Tage 2024. Es war mal wieder eine sehr schöne Veranstaltung.

Die Anreise

Im vergangenen Jahr hatte mich die Deutsche Bahn in Chemnitz sitzengelassen und ich musste mit einem kurzfristig angemieteten Leihwagen heimfahren.

Da die Deutsche Bahn und die Gewerkschaft Deutscher Lokomotivführer sich noch immer nicht auf einen neuen Tarifvertrag einigen können und ich mich nicht erneut über eine schlechte Verbindung ärgern wollte, bin ich dieses Jahr mit dem eigenen Pkw gefahren.

Am Freitag um 13:30 Uhr ging die Reise los. Mit viel Verkehr, Baustellen und Stau waren ich etwa 4,5 Stunden später im Hotel, wo ich direkt über Stoeps gestolpert bin.

Wir spazierten vom Residenz Hotel Chemnitz zum Veranstaltungsgebäude, um uns anzumelden und unsere Badges zu empfangen. Damit ersparten wir uns das Warten in der Schlange am Samstagmorgen.

Am Hörsaalgebäude traf ich schon erste vertraute Gesichter, wie z.B. Andreas, welcher fleißig beim Aufbau geholfen hat. Hier haben wir uns auch mit Michael von der Aspicon GmbH getroffen, mit dem ich für Sonntag einen Vortrag geplant hatte. Wir sind gemeinsam in die Stadt gegangen, um uns bei Speis und Trank kennenzulernen und den Abend zu verplaudern.

Der Samstag

Um 07:00 Uhr begann ich den Tag mit dem Frühstück. So war der erste Hunger bereits gestillt, als der Frühstücksraum sich zu füllen begann. Bekannte Gesichter und nerdige T-Shirts verrieten, dass es sich bei sehr vielen der Gäste um Besucher der Chemnitzer Linux-Tage handelte.

Die 20 Minuten zum Veranstaltungsort wurden auch diesmal wieder zu Fuß zurückgelegt. Und der erste Konferenztag konnte beginnen.

Um 10:00 Uhr war ich an der Reihe und durfte in einem rappelvollen Raum V6 meinen „::1“-Vortrag halten. An dieser Stelle euch allen nochmal vielen Dank für eure Teilnahme. Ich hoffe, ihr hattet so viel Spaß wie ich und konntet ein paar neue Eindrücke gewinnen.

Es hat mich gefreut, auch nach dem Vortrag noch einige Fragen beantworten zu können und über IPv6 zu fachsimpeln. Ganz nebenbei konnte ich auch noch die Frage eines Red Hat-Kunden beantworten. Darüber freute sich dieser sehr, bleibt ihm der Support eine zufriedenstellende Antwort doch seit langer Zeit schuldig. Es ist halt stets eine gute Erfahrung, einen TAM zu treffen.

Die Chemnitzer Linux-Tage gibt es übrigens schon seit 25 Jahren. Da eine Veranstaltung aufgrund der Pandemie ausfallen musste, findet die 25. Veranstaltung allerdings erst im nächsten Jahr am 22. und 23. März statt.

20-jähriges Jubiläum feiert in diesem Jahr Ubuntu, weshalb der Community-Stand dieses Jahr besonders schön geschmückt war und toddy mehrfach mit Luftschlangen gefesselt wurde.

Ich genieße die Zeit unter gleichgesinnten Nerds oder wie Stoeps es ausdrückte: „Endlich wieder unter normalen Menschen“. Mich hat es dieses Jahr sehr gefreut, auch viele jüngere Gesichter zu sehen. So sehr ich mich freue, auch die gleichen alten Nasen immer wiederzutreffen ist es doch schön, dass die Gemeinschaft nicht einfach alt wird, sondern auch junge Menschen mit Interesse, Motivation und Freude an Open Source nachwachsen.

Da die Hörsäle hier bei den Vorträgen meist aus allen Nähten platzen, hatte ich mich im Vorfeld als Sessionleitung für die drei Vorträge

  1. Never ever break userspace – was das in der Praxis bedeutet von Wolfram Sang
  2. DIY Verified Boot in 2024 von Marco Felsch und
  3. VirtualBox Meets KVM von Julian Stecklina

gemeldet. So war mir ein guter Platz im Raum sicher. Ich danke den drei Referenten für ihre interessanten Vorträge.

Am Abend waren alle Aussteller, Helfer und Referenten zum gemütlichen Beisammensein in die Mensa eingeladen, welche schräg gegenüber dem Veranstaltungsgebäude liegt. Hier gab es ein reichhaltiges Angebot an warmem und kaltem Essen sowie eine Auswahl verschiedenster Getränke. Vielleicht ist es in der Zukunft möglich, die Getränke zu kühlen. Dann wird das Bier nicht so schnell warm und schmeckt länger gut.

Ich schätze es sehr, mich auf Konferenzen mit alten und neuen Bekannten auszutauschen, zu fachsimpeln und ganz allgemein angeregte Gespräche zu führen. Das musikalische Rahmenprogramm traf auch in diesem Jahr nicht meinen Geschmack. Ich würde mir etwas Hintergrundberieselung wünschen, um sich gut unterhalten zu können. Doch sind Geschmäcker verschieden und ich erkenne durchaus an, was das Organisations-Team der Chemnitzer Linux-Tage hier Jahr für Jahr auf die Beine stellt. Euch allen vielen Dank für euren unermüdlichen Einsatz.

Der Sonntag

Nach einem frühen Frühstück und Check-out ging es heute mit dem Auto zum Veranstaltungsgelände. Noch vor dem zweiten Kaffee wurden hier die Folien für den nächsten Vortrag nochmal geprüft. Um 10:00 Uhr war es wieder soweit. Diesmal durfte ich zusammen mit Michael den Vortrag „Mit Ansible Collections & Workflows gegen das Playbook-Chaos“ halten.

@Michael: „Es hat mir gut gefallen, mit dir einen Vortrag zu halten. Das können wir gerne wiederholen.“

Beim Mittagessen habe ich dann auch noch Christian getroffen. Für ihn waren es die ersten Chemnitzer Linux-Tage und auch ihm haben sie sehr gut gefallen.

Und wie immer war die Zeit auch viel zu schnell wieder vorbei. So habe ich Henning zwar kurz gesehen, doch für mehr als ein kurzes „Hi und Tschüss, bis zum nächsten Mal“ reichte es diesmal leider nicht.

Die Heimreise

Auch die schönsten Chemnitzer Linux-Tage gehen vorbei. Doch im Auto sitzend freute ich mich auch schon darauf, meine Familie wiederzusehen. Die Straße war frei und nach nur 3 Stunden 20 Minuten war ich wieder daheim. Zum Vergleich, mit der Bahn wäre ich je nach Verbindung erst nach 5,5-6,5 Stunden daheim gewesen, wenn alles nach Plan fährt.

So konnte ich mehr Zeit vor Ort verbringen und war rechtzeitig daheim, um noch etwas Zeit mit meinem Sohn zu verbringen, bevor dieser ins Bett ging.

Fazit

Es war schön. Ich hoffe, ihr seid alle wieder gut heimgekommen und behaltet auch diese Chemnitzer Linux-Tage in guter Erinnerung.

Weitere Berichte über die CLT 2024

Mit einem Dualstack-Reverse-Proxy Internet-Protokolle verbinden

26. Februar 2024 um 06:00

Mit einem Dualstack-Proxy Internet-Protokolle verbinden beschrieb eine Möglichkeit, um von Hosts, welche ausschließlich über IPv6-Adressen verfügen, auf Ziele zugreifen zu können, die ausschließlich über IPv4-Adressen verfügen. In diesem Beitrag betrachte ich die andere Richtung.

Zu diesem Beitrag motiviert hat mich der Kommentar von Matthias. Er schreibt, dass er für den bei einem Cloud-Provider gehosteten Jenkins Build Server IPv4 deaktivieren wollte, um Kosten zu sparen. Dies war jedoch nicht möglich, da Kollegen aus einem Co-Workingspace nur mit IPv4 angebunden sind und den Zugriff verloren hätten.

Doch wie kann man nun ein IPv6-Netzwerk für ausschließlich IPv4-fähige Clients erreichbar machen, ohne für jeden Host eine IPv4-Adresse zu buchen? Dazu möchte ich euch anhand eines einfachen Beispiels eine mögliche Lösung präsentieren.

Vorkenntnisse

Um diesem Text folgen zu können, ist ein grundsätzliches Verständnis von DNS, dessen Resource Records (RR) und des HTTP-Host-Header-Felds erforderlich. Die Kenntnis der verlinkten Wikipedia-Artikel sollte hierfür ausreichend sein.

Umgebung

Zu diesem Proof of Concept gehören:

  • Ein Dualstack-Reverse-Proxy-Server (HAProxy) mit den DNS-RR:
    • haproxy.example.com. IN A 203.0.113.1
    • haproxy.example.com IN AAAA 2001:DB8::1
  • Zwei HTTP-Backend-Server mit den DNS-RR:
    • www1.example.com IN AAAA 2001:DB8::2
    • www2.example.com IN AAAA 2001:DB8::3
  • Zwei DNS-RR:
    • www1.example.com IN A 203.0.113.1
    • www2.example.com IN A 203.0.113.1
  • Ein Client mit einer IPv4-Adresse

Ich habe mich für HAProxy als Reverse-Proxy-Server entschieden, da dieser in allen Linux- und BSD-Distributionen verfügbar sein sollte und mir die HAProxy Maps gefallen, welche ich hier ebenfalls vorstellen möchte.

Der Versuchsaufbau kann wie folgt skizziert werden:

Ein Dualstack-Reverse-Proxy-Server (B) verbindet IPv4-Clients mit IPv6-Backend-Servern

HAProxy-Konfiguration

Für dieses Minimal-Beispiel besteht die HAProxy-Konfiguration aus zwei Dateien, der HAProxy Map hosts.map und der Konfigurationsdatei poc.cfg.

~]$ cat /etc/haproxy/conf.d/hosts.map 
www1.example.com	serversa
www2.example.com	serversb

Eine HAProxy Map besteht aus zwei Spalten. In der ersten Spalte stehen die FQDNs, welche vom HTTP-Client aufgerufen werden können. In der zweiten Spalte steht der Name des Backends aus der HAProxy-Konfiguration, welcher bestimmt, an welche Backend-Server eine eingehende Anfrage weitergeleitet wird. In obigem Beispiel werden Anfragen nach www1.example.com an das Backend serversa und Anfragen nach www2.example.com an das Backend serversb weitergeleitet.

Die HAProxy Maps lassen sich unabhängig von der HAProxy-Konfigurations-Datei pflegen und bereitstellen. Map-Dateien werden in ein Elastic Binary Tree-Format geladen, so dass ein Wert aus einer Map-Datei mit Millionen von Elementen ohne spürbare Leistungseinbußen nachgeschlagen werden kann.

Die HAProxy-Konfigurations-Datei poc.cfg für dieses Minimal-Beispiel ist ähnlich simpel:

~]$ cat /etc/haproxy/conf.d/poc.cfg 
frontend fe_main
	bind :80
	use_backend %[req.hdr(host),lower,map(/etc/haproxy/conf.d/hosts.map)]

backend serversa
	server server1 2001:DB8::1:80
backend serversb
	server server1 2001:DB8::2:80

In der ersten Zeile wird ein Frontend mit Namen fe_main definiert. Zeile 2 bindet Port 80 für den entsprechenden Prozess und Zeile 3 bestimmt, welches Backend für eingehende HTTP-Anfragen zu nutzen ist. Dazu wird der HTTP-Host-Header ausgewertet, falls notwendig, in Kleinbuchstaben umgewandelt. Mithilfe der Datei hosts.map wird nun ermittelt, welches Backend zu verwenden ist.

Die weiteren Zeilen definieren zwei Backends bestehend aus jeweils einem Server, welcher auf Port 80 Anfragen entgegennimmt. In diesem Beispiel sind nur Server mit IPv6-Adressen eingetragen. IPv4-Adressen sind selbstverständlich auch zulässig und beide Versionen können in einem Backend auch gemischt auftreten.

Kann eine HTTP-Anfrage nicht über die hosts.map aufgelöst werden, läuft die Anfrage in diesem Beispiel in einen Fehler. Für diesen Fall kann ein Standard-Backend definiert werden. Siehe hierzu den englischsprachigen Artikel Introduction to HAProxy Maps von Chad Lavoie.

Der Kommunikationsablauf im Überblick und im Detail

Der Kommunikationsablauf im Überblick

Von einem IPv4-Client aus benutze ich curl, um die Seite www1.example.com abzurufen:

~]$ curl -4 -v http://www1.example.com
* processing: http://www1.example.com
*   Trying 203.0.113.1:80...
* Connected to www1.example.com (203.0.113.1) port 80
> GET / HTTP/1.1
> Host: www1.example.com
> User-Agent: curl/8.2.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< server: nginx/1.20.1
< date: Sat, 06 Jan 2024 18:44:22 GMT
< content-type: text/html
< content-length: 5909
< last-modified: Mon, 09 Aug 2021 11:43:42 GMT
< etag: "611114ee-1715"
< accept-ranges: bytes
< 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
	<head>
		<title>Test Page for the HTTP Server on Red Hat Enterprise Linux</title>

Der FQDN www1.example.com wird mit der IPv4-Adresse 203.0.113.1 aufgelöst, welche dem Host haproxy.example.com gehört. Bei der Zeile Host: www1.example.com handelt es sich um den HTTP-Host-Header, welchen der HAProxy benötigt, um das richtige Backend auszuwählen.

Es ist zu sehen, dass wir eine Antwort von einem NGINX-HTTP-Server erhalten. Der HTML-Quelltext wurde gekürzt.

Damit ist es gelungen, von einem IPv4-Client eine Ressource abzurufen, die von einem IPv6-Server bereitgestellt wird.

Im Access-Log des Backend-Servers mit der IPv6-Adresse 2001:DB8::2 sieht man:

2001:DB8::1 - - [06/Jan/2024:19:44:22 +0100] "GET / HTTP/1.1" 200 5909 "-" "curl/8.2.1" "192.0.2.1"

Die Anfrage erreicht den Backend-Server von der IPv6-Adresse des haproxy.example.com (2001:DB8::1). Die am Ende der Zeile zu sehende IPv4-Adresse (192.0.2.1) gehört dem IPv4-Client, von dem ich die Anfrage gesendet habe.

Gedanken zur Skalierung

In diesem Beispiel sind die Server www1.example.com und www2.example.com über ihre IPv6-Adressen direkt erreichbar. Nur die Client-Anfragen von IPv4-Clients laufen über den Reverse-Proxy. Wenn man es wünscht, kann man selbstverständlich sämtliche Anfragen (von IPv4- und IPv6-Clients) über den Reverse-Proxy laufen lassen.

In kleinen Umgebungen kann man einen Reverse-Proxy wie HAProxy zusammen mit Squid (vgl. Artikel Mit einem Dualstack-Proxy Internet-Protokolle verbinden) auf einem Host laufen lassen. Selbstverständlich kann man sie auch auf separate Hosts verteilen.

Hochverfügbarkeit lässt sich auch hier mit keepalived nachrüsten:

Abschließende Gedanken

Die Internet-Protokolle IPv4 und IPv6 werden wohl noch eine ganze Zeit gemeinsam das Internet bestimmen und parallel existieren. Ich bin mir sogar sicher, dass ich das Ende von IPv4 nicht mehr miterleben werde. Dualstack-(Reverse)-Proxy-Server stellen eine solide und robuste Lösung dar, um beide Welten miteinander zu verbinden.

Sicher bleiben noch ausreichend Herausforderungen übrig. Ich denke da nur an Firewalls, Loadbalancer, NAT und Routing. Und es werden sich auch Fälle finden lassen, in denen Proxyserver nicht infrage kommen. Doch mit diesen Herausforderungen beschäftige ich mich dann in anderen Artikeln.

Quellen und weiterführende Links

Zeichen setzen – auf den Chemnitzer Linux-Tagen 2024

24. Februar 2024 um 06:00

In drei Wochen beginnen die Chemnitzer Linux-Tage 2024 mit dem diesjährigen Motto „Zeichen setzen“. Am 16. und 17. März erwartet euch im Hörsaalgebäude an der Richenhainer Straße 90 ein vielfältiges Programm an Vorträgen und Workshops. Hier finden sich Vorträge für interessierte Neueinsteiger wie für alte Hasen.

So geht es am Samstag im Einsteigerforum beispielsweise um die Digitalisierung analoger Fotos, das Erstellen von Urlaubsvideos mit der Software OpenShot oder die Verschlüsselung von E-Mails. In der Rubrik „Schule“ gibt Arto Teräs einen Einblick in den Einsatz der Open-Source-Lösung Puavo an finnischen und deutschen Schulen. Zusätzlich stehen Vorträge aus den Bereichen Finanzen, Medien, Datensicherheit, KI oder Netzwerk auf dem Programm. Am Sonntag gibt das Organisationsteam der Chemnitzer Linux-Tage mit „make CLT“ Einblicke in die Planung und Strukturen der Veranstaltung selbst. In der Rubrik „Soft Skills” wird es um die Schätzung von Aufwänden oder notwendige Fähigkeiten von Software-Entwicklern gehen.

Eintrittskarten können online im Vorverkauf und an der Tageskasse erworben werden. Kinder bis 12 Jahren haben freien Eintritt.

Während viele Besucher bereits Stammgäste sind, werden auch neue Gesichter herzlich willkommen. Lasst euch gern von der hier herrschenden Atmosphäre voller Begeisterung für freie Software und Technik anstecken und begeistern.

Ich selbst freue mich, am Samstag um 10:00 Uhr in V6 den Vortrag mit dem obskuren Namen ::1 beisteuern zu dürfen. Update: Unverhofft kommt oft. Uns so freue ich mich am Sonntag um 10:00 Uhr in Raum V7 noch in einem zweiten Vortrag vertreten zu sein. Zusammen mit Michael Decker von der ASPICON GmbH erfahrt ihr, wie man „Mit Ansible Collections & Workflows gegen das Playbook-Chaos“ angehen kann.

Darüber hinaus beteilige ich mich als Sessionleiter für die folgenden drei Vorträge an der Veranstaltung:

So habe ich auf jeden Fall einen Platz im Raum sicher. ;-)

Wer ebenfalls helfen möchte, kann sich unter Mitmachen! informieren und melden.

Für mich ist dieses Jahr einiges im Programm dabei. Doch freue ich mich ebenso sehr auf ein Wiedersehen mit alten Bekannten aus der Gemeinschaft und darauf, neue Gesichter (Namen kann ich mir meist erst Jahre später merken) kennenzulernen.

Also bis bald in der Karl-Marx-Stadt.

Chemnitzer Linux-Tage Banner

Glücksmomente und Zeiten der Schmerzen mit IPv6

19. Februar 2024 um 06:00

Am 16. und 17. März 2024 werde ich euch auf den Chemnitzer Linux-Tagen um 10:00 Uhr in Raum V6 mit einem Vortrag über IPv6 unterhalten.

Dazu bin ich noch auf der Suche nach ein paar Beispielen aus dem echten Leben. Falls ihr mögt, teilt mir doch eure schönsten und schlimmsten Momente im Zusammenhang mit IPv6 mit und ich prüfe, ob ich sie in meinen Vortrag mit einbauen kann.

  • Wann und wie hat IPv6 euren Tag gerettet?
  • Wieso hat euch das Protokoll Alpträume beschehrt?
  • Was funktioniert wider Erwarten immer noch nicht mit IPv6?
  • Habt ihr lustige Geschichten, die ihr (anonym) mit der Welt teilen möchtet?

Ich freue mich über Einsendungen, Beiträge und Rückmeldungen:

Bitte schreibt dazu, ob ihr eine Namensnennung wünscht oder euer Beispiel anonym einfließen soll.

Um einen runden Vortrag zu erstellen, wird evtl. nicht jeder Beitrag einfließen können. Bitte habt Verständnis dafür und verzeiht, wenn ihr euch nicht im Vortrag wiederfindet. Ich werde eure Geschichten ggf. im Nachgang hier im Blog veröffentlichen.

Bis neulich in Chemnitz. :-)

Mit einem Dualstack-Proxy Internet-Protokolle verbinden

12. Februar 2024 um 06:00

Stellt euch vor, ihr habt eine Menge von Servern, welche ausschließlich über IPv6-Adressen verfügen und deshalb keine Dienste nutzen können, welche nur über IPv4 bereitgestellt werden. Wer sich dies nicht vorstellen mag, findet in „IPv6… Kein Anschluss unter dieser Nummer“ ein paar Beispiele dafür.

Was kann man nun tun, damit diese IPv6-only-Hosts dennoch mit der IPv4-only-Welt kommunizieren können?

Eine mögliche Lösung ist die Nutzung eines Dualstack-Proxy-Servers. Das ist ein Server, welcher über Adressen beider Internet-Protokoll-Versionen verfügt und so stellvertretend für einen IPv6-Host mit einem IPv4-Host kommunizieren kann. Das folgende Bild veranschaulicht den Kommunikationsablauf:

Ablauf der Netzwerkkommunikation eines IPv6-Hosts mit einem IPv4-Host über einen Dualstack-Proxy-Server

Im Bild ist zu sehen:

  1. Wie IPv6-Host A eine Verbindung über IPv6 zum Proxy-Server B aufbaut und diesem bspw. die gewünschte URL mitteilt
  2. Der Proxy-Server B baut nun seinerseits eine IPv4-Verbindung zu IPv4-Host C auf, welcher die gewünschten Inhalte bereitstellt
  3. IPv4-Host C sendet seine Antwort über IPv4 an den Proxy-Server
  4. Der Proxy-Server sendet die gewünschten Inhalte anschließend via IPv6 an den IPv6-Host A zurück
Screencast zur Demonstration der Proxy-Nutzung

Das obige Video demonstriert die Nutzung eines Proxy-Servers durch den Abruf einer Demo-Seite mit curl:

  1. Mit dem host-Kommando wird gezeigt, dass für die Demo-Seite kein AAAA-Record existiert; die Seite ist also nicht via IPv6 erreichbar
  2. Mit dem ip-Kommando wird geprüft, dass der Host auf dem Interface ens18 ausschließlich über IPv6-Adressen verfügt
  3. Ohne Proxy ist die Demo-Seite nicht abrufbar
  4. Erst durch Nutzung des Proxys kann die Seite abgerufen werden

Funktioniert das auch von IPv4 nach IPv6?

Ja. Entscheidend ist, dass der verwendete Proxy beide IP-Versionen unterstützt.

Welcher Proxy ist empfehlenswert?

Der Proxy-Server muss beide IP-Versionen beherrschen. Ich persönlich bevorzuge Squid. Dieser ist in so gut wie allen Linux-Distributionen verfügbar, weit verbreitet, robust und selbstverständlich Freie Software.

Sind damit alle Herausforderungen bewältigt?

Für eine Virtualisierungs-Umgebung mit einer IPv4-Adresse und einem /64-IPv6-Netzsegment funktioniert diese Lösung gut. Sie funktioniert auch in jeder anderen Umgebung, wie gezeigt. Man beachte jedoch, dass man mit nur einem Proxy einen Single-Point-of-Failure hat. Um diesem zu begegnen, kann man Squid mit keepalived hochverfügbar gestalten.

Keepalived ist ebenfalls Freie Software. Sie kostet kein Geld, erhöht jedoch die Komplexität der Umgebung. Verfügbarkeit vs. Komplexität möge jeder Sysadmin selbst gegeneinander abwägen.

Wie mache ich meine IPv6-Dienste für IPv4-User erreichbar, die keinen Proxy haben?

Das Stichwort lautet Reverse-Proxy. Ein Artikel dazu erscheint in Kürze in diesem Blog. ;-)

Weiterführende Quellen und Links

Der My-IT-Brain Jahresrückblick 2023

15. Januar 2024 um 06:00

Das Jahr 2024 ist nun schon zwei Wochen alt. Dennoch möchte ich noch einen Blick zurückwerfen und mich erinnern, wie das Jahr 2023 für meinen Blog verlaufen ist.

In 2023 wurden auf My-IT-Brain insgesamt 45 Artikel veröffentlicht. Dies sind 16 mehr als in 2022 und 14 mehr als in 2021. Jeden Monat sind mindestens zwei Artikel veröffentlicht worden.

Die Themen waren dabei wieder bunt gemischt. Allein Artikel über die Red Hat Enterprise Linux (RHEL) System Roles zogen sich wie ein roter Faden durch den Blog. Welche Artikel haben denn euch am besten gefallen? Lasst es mich gerne in den Kommentaren wissen.

Ich hoffe, es war für jeden von euch etwas Interessantes mit dabei und ihr folgt diesem Blog auch in 2024. Ihr könnt mir auch gerne Anregungen in die Kommentare schreiben, welche Themen ihr hier gerne behandelt sehen wollt. Vielleicht greife ich ja einige davon auf.

Und nun aber auf in ein spannendes Jahr 2024!

IPv6… Kein Anschluss unter dieser Nummer

25. Dezember 2023 um 06:00

Das Jahr 2023 neigt sich langsam dem Ende zu. In diesem Monat for 25 Jahren wurde das IPv6-Protokoll in RFC 2460 beschrieben, bevor es 2017 in RFC 8200 als Internet-Standard von der Internet Engineering Task Force (IETF) veröffentlicht wurde.

Seit immerhin sechs Jahren ist dieses IP-Protokoll also schon standardisiert. Da sollte man doch meinen, dass man im Jahr 2023 problemlos ein vernetztes System betreiben kann, welches nur mit einer IPv6-Adresse mit dem Internet verbunden ist. Leider ist dem nicht so.

In den folgenden kurzen Abschnitten schreibe ich mir meinen Frust von der Seele und dokumentiere, was heute alles mit IPv6 noch nicht geht. Falls ihr weitere Fälle ergänzen möchtet, nutzt gerne die Kommentare, um eurem IPv6-Frust Luft zu machen.

Red Hat Satellite 6.14

Bei der Planung einer Red Hat Satellite 6.14 Installation bin ich über folgenden Satz in der Dokumentation gestolpert:

You can install Satellite and Capsules in IPv6-only systems, dual-stack installation is not supported.

URL: https://access.redhat.com/documentation/en-us/red_hat_satellite/6.14/html/installing_satellite_server_in_a_connected_network_environment/preparing-environment-for-installation-in-ipv6-network_satellite

Das ist schade. Betreibt man Server in IPv4- und IPv6-Netzwerken und möchte eine vollständig unterstützte Lösung, muss man aktuell zwei Satellite installieren.

Ich wollte jedoch einen Satellite in einer reinen IPv6-Umgebung installieren, daher sollte mich diese Anmerkung nicht weiter stören. Da störten mich folgende Stellen im gleichen Kapitel der Dokumentation schon mehr:

You must deploy an external IPv4 HTTP proxy server. This is required because Red Hat Content Delivery Network distributes content only over IPv4 networks, therefore you must use this proxy to pull content into the Satellite on your IPv6 network.

You must configure Satellite to use this IPv4 HTTP proxy server as the default proxy. For more information, see Adding a Default HTTP Proxy to Satellite.

URL: https://access.redhat.com/documentation/en-us/red_hat_satellite/6.14/html/installing_satellite_server_in_a_connected_network_environment/preparing-environment-for-installation-in-ipv6-network_satellite#requirements-for-installation-in-an-ipv6-network_satellite

Zuerst wollte ich dies nicht glauben, habe einen Fehler in der Dokumentation vermutet. Es ist 2023 und Content Delivery Network (CDN) von Red Hat unterstützt kein IPv6? Das kann doch nicht sein! Kann es doch:

Der zweite Link in obiger Liste führt ausschließlich IPv4-Adressen auf. Einzelne Kommentare lassen darauf schließen, dass es jedoch durchaus Interesse an IPv6-Konnektivität gibt. Also installiere ich erstmal einen Proxy-Server mit Dual-Stack, damit ich Hosts aus einem reinen IPv6-Netzwerk via subscription-manager register beim Red Hat Subscription Management (RHSM) registrieren kann.

subscription-manager cli command does not support IPv6 proxy

Nachzulesen in:

Die gute Nachricht, es sind gefixte Versionen für RHEL 9 und RHEL 8 in Aussicht. Auf einen Fix für RHEL 7 würde ich nicht warten und diese Systeme lieber migrieren oder aktualisieren, ist das Support-Ende doch bereits nah.

Also lege ich mein Vorhaben erstmal beiseite und wende mich anderen Wochenendprojekten zu, die vielleicht mehr Erfolg versprechen.

ansible-galaxy does not work on IPv6 only hosts

Nun guck an, da ist mein Kollege Andreas also schon im Jahr 2022 in den Ansible-Issue #77308 gelaufen. Ihr interessiert euch für den aktuellen Stand dieser Geschichte? Siehe:

So langsam komme ich mir vor wie ein bekannter spanischer Junker, welcher gegen Windmühlen pardon Riesen anritt. Aber es ist ja nicht so, dass mir die Themen ausgehen. Klone ich mir halt ein Repo von Github und trage ein bisschen zu Open Source bei…

IPv6 support for cloning Git repositories #10539

Ich spare mir viele Worte und präsentiere nur folgenden Code-Block:

$ host -t AAAA github.com
github.com has no AAAA record

URL zur Diskussion: https://github.com/orgs/community/discussions/10539

Auch hier kein Anschluss unter dieser Nummer.

Fazit

Ich möchte meine jüngsten Erfahrungen umschreiben mit: „An manchen Tagen hat man kein Glück und an anderen kommt auch noch Pech dazu.“

Für Red Hat möchte ich sagen, ist es ein Priorisierungs-Thema. Wenn der Wunsch nach IPv6 auf Kundenseite hinreichend groß wird, wird man hier handeln. Bei Github wird es ähnlich sein. Ich muss vielleicht nur nochmal 25 Jahre warten.

  • Welche Erfahrungen habt ihr mit IPv6 gemacht?
  • Habt ihr es schon an den Nagel gehängt; oder bleibt ihr hartnäckig und gebt nicht auf?
  • Ich freue mich auf eure schönsten Fehlschläge und Erfolgsmomente.

RHEL System Roles: nbde_client

04. Dezember 2023 um 06:00

In diesem Artikel stelle ich euch die RHEL System Role nbde_client vor, mit welcher sich Hosts für Network Bound Disk Encryption (NBDE) installieren lassen. Er ist Bestandteil einer losen Serie, in der ich eine Reihe von System Roles vorstelle, mit denen häufig anfallende Aufgaben in der Systemadministration erledigt werden können.

Wer sich zuerst über die genannten Begriffe informieren möchte, lese:

Umgebung

Für das folgende Beispiel verwende ich eine Umgebung, bestehend aus:

  • Einem Ansible-Controller (RHEL 9) mit den Paketen
    • ansible-core
    • rhel-system-roles
  • Jeweils einem RHEL 8 und RHEL 9 Server mit Minimalinstallation und einem LUKS-Gerät (/dev/sdc in den Beispielen in diesem Text)

Die Installation von RHEL sowie der genannten Pakete sind nicht Bestandteil dieses Artikels. Wer hierzu einen Einstieg sucht, findet entsprechende Dokumentation unter:

Die Rolle

Durch die Installation des Pakets rhel-system-roles existiert diese Rolle bereits auf meinem System und muss nur noch konfiguriert werden. Die Rolle selbst findet man im Pfad /usr/share/ansible/roles/rhel-system-roles.nbde_client/ und die Dokumentation in /usr/share/doc/rhel-system-roles/nbde_client/README.md. Letztere enthält verschiedene Beispiele für häufige Anwendungsfälle.

Anwendungsfall

In meinem Labor betreibe ich zwei NBDE-Server (TANG-Server) rhel-hetz-tang1 und rhel-hetz-tang2 sowie zwei NBDE-Clients (Clevis-Clients) rhel-hetz-clevis1 und rhel-hetz-clevis2. Die beiden NBDE-Clients besitzen jeweils ein LUKS-Device /dev/sdc, welches aktuell durch eine LUKS-Passphrase gesichert ist.

Zukünftig sollen diese LUKS-Devices durch die Kommunikation mit einem NBDE-Server entschlüsselt werden. Die LUKS-Passphrase soll entfernt werden.

Damit wird zukünftig ein Neustart der Clients aus der Ferne ermöglicht. Gleichzeitig bleibt das verschlüsselte Gerät bei Diebstahl vor unbefugtem Zugriff geschützt.

Das Playbook

Hinweis: Das folgende Playbook ist nicht idempotent. Um dies zu ändern, ist dem ersten Task eine Bedingung hinzuzufügen, damit dieser nur dann ausgeführt werden, wenn die Bedingung erfüllt ist.

Für dieses Beispiel ist die fehlende Idempotenz des Playbooks jedoch kein Problem, da grubby das Argument nur dann hinzufügt, wenn es nicht bereits vorhanden ist.

---
- hosts: clevis
  tasks:
  - name: Configure ip address for interface during early boot
    ansible.builtin.command:
      cmd: grubby --update-kernel=ALL --args='GRUB_CMDLINE_LINUX_DEFAULT="net.ifnames=0 biosdevname=0 ip={{ ansible_default_ipv4.address }}::{{ ansible_default_ipv4.gateway }}:{{ ansible_default_ipv4.netmask }}::{{ ansible_default_ipv4.alias }}:none"'

  - name: Enroll Clevis clients
    include_role:
      name: rhel-system-roles.nbde_client
    vars:
      nbde_client_bindings:
        - device: /dev/sdc
          encryption_password: "{{ luks_password }}"
          password_temporary: true
          slot: 2
          servers:
            - http://rhel-hetz-tang1.example.com
            - http://rhel-hetz-tang2.example.com
  • Der erste Task stellt sicher, dass das Netzwerkinterface aktiviert und mit einer IP-Adresse konfiguriert wird; dies ist notwendig, um den Tang-Server kontaktieren zu können, da in dem genutzten Netzwerk-Segment kein DHCP verfügbar ist; Solltet ihr ein Netzwerk-Segment nutzen, in dem DHCP zur Verfügung steht, kann der erste Task entfallen
  • Um das LUKS-Device für NBDE zu konfigurieren wird die LUKS-Passphrase benötigt, welche in der Variablen luks_password steckt
  • Ich empfehle die Variable luks_password mit ansible-vault vor neugierigen Blicken zu schützen
  • Durch password_temporary: true wird die LUKS-Passphrase aus dem jeweiligen Key-Slot gelöscht, nachdem das LUKS-Device für NBDE konfiguriert wurde

Achtung (I know, the warning comes after the spell): Wenn zur Laufzeit ein Fehler auftritt und der Key-Slot mit der LUKS-Passphrase bereits gelöscht wurde, die NBDE-Konfiguration jedoch nicht erfolgreich war, verliert man Zugriff auf das LUKS-Device. In meiner Labor-Umgebung bin ich das Risiko eingegangen. In der echten Welt, müsst ihr selbst entscheiden, ob ihr mehr Vorsicht walten lasst.

Fazit

Zur Erstellung des Playbooks habe ich die Informationen aus /usr/share/doc/rhel-system-roles/nbde_client/README.md und dem Kapitel 12.18. Using the nbde_client System Role for setting up multiple Clevis clients genutzt. Bis ich festgestellt habe, dass ich auch noch den Task „Configure ip address for interface during early boot“ benötige, hat es ein wenig gedauert. Nun habe ich allerdings ein Playbook, dass ich zukünftig wiederverwenden kann.

In der erstellten Konfiguration, können die LUKS-Devices nur entschlüsselt werden, wenn mindestens einer der beiden Tang-Server im Netzwerk erreichbar ist. Wird ein so gesicherter Server gestohlen und sind die Tang-Server nicht aus dem Internet erreichbar, bleiben die Daten in der verschlüsselten Partition wie gewohnt geschützt. Es ist jedoch möglich den Server neuzustarten, ohne manuell die LUKS-Passphrase an der Konsole eingeben zu müssen.

Quellen und weiterführende Links

  1. Red Hat Enterprise Linux (RHEL) System Roles {en}
  2. Ansible Documentation: Role Directory Structure {en}
  3. Red Hat Software and Download Center {en}
  4. Die Vorteile einer Red Hat Subskription
  5. RHEL System Roles: selinux
  6. RHEL System Roles: timesync
  7. RHEL System Roles: sshd
  8. RHEL System Roles: firewall
  9. RHEL System Roles: rhc
  10. RHEL System Roles: nbde_server

RHEL System Roles: nbde_server

27. November 2023 um 05:00

In diesem Artikel stelle ich euch die RHEL System Role nbde_server vor, mit welcher sich Tang-Server für Network Bound Disk Encryption (NBDE) installieren lassen. Er ist Bestandteil einer losen Serie, in der ich eine Reihe von System Roles vorstelle, mit denen häufig anfallende Aufgaben in der Systemadministration erledigt werden können.

Wer sich zuerst über die genannten Begriffe informieren möchte, lese zuerst:

Im folgenden Text verwende ich die Begriffe NBDE-Server und Tang-Server synonym. Bitte lasst euch dadurch nicht verwirren.

Umgebung

Für das folgende Beispiel verwende ich eine Umgebung, bestehend aus:

  • Einem Ansible-Controller mit den Paketen (RHEL 9)
    • ansible-core
    • rhel-system-roles
  • Jeweils einem RHEL 8 und RHEL 9 Server mit Minimalinstallation

Die Installation von RHEL sowie der genannten Pakete sind nicht Bestandteil dieses Artikels. Wer hierzu einen Einstieg sucht, findet entsprechende Dokumentation unter:

Die Rolle

Durch die Installation des Pakets rhel-system-roles existiert diese Rolle bereits auf meinem System und muss nur noch konfiguriert werden. Die Rolle selbst findet man im Pfad /usr/share/ansible/roles/rhel-system-roles.nbde_server/ und die Dokumentation in /usr/share/doc/rhel-system-roles/nbde_server/README.md. Letztere enthält verschiedene Beispiele für häufige Anwendungsfälle.

Ich möchte mit dieser Rolle Folgendes erreichen:

  • Installation von Tang auf den beiden Zielsystemen
  • Konfiguration von SELinux im Modus enforcing
  • Konfiguration der Host-Firewall

Das Playbook

Das Playbook ist recht übersichtlich. tang bezeichnet eine Gruppe aus meinem Ansible-Inventory, welche die Systeme enthält, die ich als NBDE-Server konfigurieren möchte.

---
- name: Manage nbde server with selinux and firewall
  hosts: tang
  vars:
    nbde_server_manage_firewall: true
    nbde_server_manage_selinux: true
  roles:
    - rhel-system-roles.nbde_server

Nach der Anwendung der Rolle lauscht der Tang-Service auf Port 80/tcp der Zielsysteme und ist aus dem Netzwerk erreichbar.

Probleme

Leider läuft es dieses Mal nicht ganz so rund wie üblich. Der Task [redhat.rhel_system_roles.selinux : Set an SELinux label on a port] schlägt auf dem RHEL 8 Host mit folgender Fehlermeldung fehl: „Failed to import the required Python library (libselinux-python)“

Das Problem und die Lösung beschreibt Red Hat in dem Solution Article: Ansible playbook fails with libselinux-python aren’t installed on RHEL8 (Login required)

Fazit

Diesmal lief es nicht ganz so reibungslos wie gewohnt.

Letztendlich konnten die beiden NBDE-Server dennoch schneller konfiguriert werden, als wäre ich der manuellen Prozedur in Chapter 12. Configuring automated unlocking of encrypted volumes using policy-based decryption gefolgt.

Die Server sind damit aufgesetzt, nächste Woche beschreibe ich, wie die Clients konfiguriert werden.

Quellen und weiterführende Links

  1. Red Hat Enterprise Linux (RHEL) System Roles {en}
  2. Ansible Documentation: Role Directory Structure {en}
  3. Red Hat Software and Download Center {en}
  4. Die Vorteile einer Red Hat Subskription
  5. RHEL System Roles: selinux
  6. RHEL System Roles: timesync
  7. RHEL System Roles: sshd
  8. RHEL System Roles: firewall
  9. RHEL System Roles: rhc

Einführung in das Advanced Intrusion Detection Environment (AIDE)

06. November 2023 um 05:00

Diese Einführung gibt Antworten auf die folgenden Fragen:

  • Was ist ein Intrusion Detection System?
  • Was ist AIDE?
  • Wie installiert und konfiguriert man es?
  • Wie nutzt man AIDE?

In dieser Einführung verwendete Betriebssysteme:

  • Debian 12 (Bookworm)
  • Red Hat Enterprise Linux (RHEL) 9

Um dieser Einleitung folgen zu können, solltet ihr mit den Grundlagen der Linux-Systemadministration vertraut sein und zumindest mit den folgenden Begriffen etwas anfangen können:

Einleitung

Ein Intrusion Detection System (englisch intrusion „Eindringen“, IDS) bzw. Angriffserkennungssystem ist ein System zur Erkennung von Angriffen, die gegen ein Computersystem oder Rechnernetz gerichtet sind. Das IDS kann eine Firewall ergänzen oder auch direkt auf dem zu überwachenden Computersystem laufen und so die Sicherheit von Netzwerken und Computersystemen erhöhen. Erkannte Angriffe werden meistens in Log-Dateien gesammelt und Benutzern oder Administratoren mitgeteilt; hier grenzt sich der Begriff von Intrusion Prevention System (englisch prevention „Verhindern“, IPS) ab, welches ein System beschreibt, das Angriffe automatisiert und aktiv verhindert.

Quelle: https://de.wikipedia.org/wiki/Intrusion_Detection_System (Letzter Abruf: 2023-09-08)

Die Gruppe der Intrusion Detection Systems (IDS) untergliedert sich in:

  • Host-basierte IDS, welche auf einem Host installiert und betrieben werden
  • Netz-basierte IDS, welche auf Netzwerkkomponenten installiert werden und die Kommunikation auf Netz-Ebene überwachen
  • Hybride IDS, welche die Komponenten aus den vorstehend genannten Gruppen kombinieren

Beim AIDE handelt es sich um ein Host-basiertes IDS. Es ist unter der GPL-2.0 lizenziert.

Zweck und Nutzen des AIDE

Aus dem vorhergehenden Abschnitt ist bekannt, dass es sich bei AIDE um ein Host-basiertes System zur Angriffs- bzw. Einbruchserkennung für Linux-Systeme handelt. Es stellt ein kostengünstiges Werkzeug dar, mit dem die Integrität eines Systems überprüft werden kann.

Es soll dem Administrator helfen, zu erkennen, ob Dateien oder Verzeichnisse eines Systems hinsichtlich ihres Inhalts und bzw. oder ihrer Eigenschaften wie z.B. Berechtigungen, SELinx-Kontext, erweiterte Attribute, etc. verändert wurden.

Grundlegende Funktionsweise des AIDE

  • Die zu überwachenden Dateien und Verzeichnisse werden durch reguläre Ausdrücke in der Konfigurationsdatei bestimmt
  • Basierend auf diesen Regeln wird eine Datenbank erstellt
  • Nach dem Initialisieren der Datenbank kann AIDE dazuverwendet werden, die Integrität der Dateien und Verzeichnisse zu überprüfen
    • Die initial erstellte Datenbank dient dabei als Referenz
    • Bei folgenen Überprüfungen wird eine neue Datenbank erstellt und mit der Referenzdatenbank verglichen
  • Änderungen an überwachten Dateien und Verzeichnissen werden in der Logdatei /var/log/aide/aide.log protokolliert

Schwäche von AIDE und Host-basierter IDS im Allgemeinen

  • Programm, Konfigurationsdatei(en), Datenbank und Logdatei liegen lokal auf dem jeweiligen Host
  • Angreifer, welche lokale Dateien verändern können, können potenziell auch die zu AIDE gehörenden Dateien verändern
  • Dadurch muss die Integrität der zur Integritätsprüfung eingesetzten IDS bezweifelt werden

Um diese Schwäche zu minimieren, sind folgende Maßnahmen durch Administratoren in Erwägung zu ziehen:

  • Logdateien an einen zentralen Loghost senden
  • Die AIDE-Referenzdatenbank außerhalb des zu überwachenden Hosts speichern
  • Den Abgleich gegen die AIDE-Referenzdatenbank außerhalb des zu überwachenden Hosts durchführen

Wie diese Maßnahmen umgesetzt werden können, beschreibe ich in einem folgenden Beitrag.

Auswirkungen auf die eigene Arbeitsweise

Werden beispielsweise Konfigurationsdateien unterhalb von /etc auf Änderungen hin überwacht, wird auch jede beabsichtige Änderung protokolliert. Das Programm kann zwischen legitimen und unautorisierten Änderungen nicht unterscheiden.

Daher ist nach jeder legitimen Änderungen die Referenzdatenbank zu aktualisieren. Ich empfehle, dies als einen Schritt in den Konfiguration-Management-Workflow zu integrieren und diese Aufgabe einen Automaten wie Ansible, Chef, Puppet o.ä. erledigen zu lassen. Dies erscheint mir weniger fehleranfällig zu sein als bei einer manuellen Durchführung, wo dieser Schritt sicher gern einmal vergessen wird.

Die Installation von AIDE

AIDE ist in den Paketquellen der meisten Distributionen vorhanden und kann wie folgt installiert werden.

RHEL 9

$ sudo dnf in aide
[sudo] password for tronde: 
Updating Subscription Management repositories.
Last metadata expiration check: 2:26:44 ago on Fri 08 Sep 2023 08:16:28 PM CEST.
Dependencies resolved.
================================================================================
 Package Arch      Version            Repository                           Size
================================================================================
Installing:
 aide    x86_64    0.16-100.el9       rhel-9-for-x86_64-appstream-rpms    154 k

Transaction Summary
================================================================================
Install  1 Package

Total download size: 154 k
Installed size: 354 k
Is this ok [y/N]: 
  • Obiger Code-Block zeigt die Installationsanweisung für RHEL 9
  • Die Konfigurationdatei /etc/aide.conf besitzt im Auslieferungszustand bereits 303 Zeilen; ohne Kommentare und Leerzeilen sind es immerhin noch 161
  • Den Aufbau der Datei erklärt die Manpage aide.conf(5)
  • Um AIDE sinnvoll nutzen zu können, sollte sich jeder Administrator mit dem Inhalt von /etc/aide.conf vertraut machen; oder würdet ihr einem Firewall-Regelwerk vertrauen, das ihr nicht kennt?
  • Im Abschnitt „Gedanken zur Konfiguration von AIDE“ findet ihr meine Gedanken und Hinweise zur Konfiguration

Debian 12 (Bookworm)

$ sudo apt install aide
[sudo] password for jkastning: 
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  aide-common liblockfile-bin liblockfile1 libmhash2
Suggested packages:
  figlet
The following NEW packages will be installed:
  aide aide-common liblockfile-bin liblockfile1 libmhash2
0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
Need to get 372 kB of archives.
After this operation, 1064 kB of additional disk space will be used.
Do you want to continue? [Y/n]
  • Obiger Code-Block zeigt die Installationsanweisung für Debian 12
  • Neben aide werden noch die Pakete aide-common, liblockfile-bin, liblockfile1 und `libmhash2` installiert
    • Neben der Konfigurationdatei /etc/aide/aide.conf installiert Debian auch das Verzeichnis /etc/aide/aide.conf.d, in welchem sich direkt nach der Installation schon etliche Konfigurationsdateien befinden:
$ ls -l /etc/aide/aide.conf.d/ | wc -l
212
  • Auch hier empfehle ich Administratoren, sich mit der Konfiguration zu beschäftigen und sich damit vertraut zu machen (siehe dazu auch aide.conf(5))
  • Im folgenden Abschnitt „Zur Konfiguration von AIDE“ findet ihr meine Gedanken und Hinweise zur Konfiguration

Zur Konfiguration von AIDE

Während AIDE in RHEL über eine einzige Datei (/etc/aide.conf) konfiguriert wird, gibt es in Debian eine Konfigurationsdatei (/etc/aide/aide.conf) und die Verzeichnisse /etc/aide/aide.conf.d sowie /etc/aide/aide.settings.d, welche weitere Dateien zur Konfiguration und Einstellungen beinhalten.

Eine AIDE-Konfigurationsdatei aide.conf besteht aus drei verschiedenen Arten von Zeilen:

  • Optionen, welche die Konfigurationsparameter und Gruppen definieren; aufgebaut sind diese nach dem Muster Parameter = Wert bzw. Gruppenname = Wert
  • Regeln, welche bestimmen, welche Dateien und Verzeichnisse in die Datenbank aufzunehmen sind und welche Attribute überwacht werden sollen
  • Macros, mit denen sich Variablen definieren lassen; z.B. definierte @@define foo bar die Variable foo mit dem Wert bar

AIDE kann die folgenden Attribute bzw. Elemente von Dateien auf Änderungen hin überwachen:

#p:      permissions
#i:      inode
#n:      number of links
#u:      user
#g:      group
#s:      size
#b:      block count
#m:      mtime
#a:      atime
#c:      ctime
#S:      check for growing size
#acl:           Access Control Lists
#selinux        SELinux security context
#xattrs:        Extended file attributes
#md5:    md5 checksum
#sha1:   sha1 checksum
#sha256:        sha256 checksum
#sha512:        sha512 checksum
#rmd160: rmd160 checksum
#tiger:  tiger checksum

Der folgende Code-Block zeigt die Definition der beiden Gruppen NORMAL und DIR (aus der /etc/aide.conf in RHEL 9), welche spezifizieren, welche Attribute überwacht werden sollen, wenn die jeweilige Gruppe in einer Regel verwendet wird.

NORMAL = p+i+n+u+g+s+m+c+acl+selinux+xattrs+sha512

# For directories, don't bother doing hashes
DIR = p+i+n+u+g+acl+selinux+xattrs

Welche Dateien und Verzeichnisse in die AIDE-Datenbank aufzunehmen bzw. auszuschließen sind durch reguläre Ausdrücke bestimmt. Der nächste Code-Block zeigt drei Beispiele, die anschließend erläutert werden:

/etc NORMAL
=/var/log/ DIR
=/home DIR
!/dev
  • Das Verzeichnis /etc und alle darunterliegenden Dateien und Verzeichnisse werden in die AIDE-Datenbank aufgenommen und mit den Regeln aus der Gruppe NORMAL verknüpft
  • Nur das Verzeichnis /var/log/ und die direkt darunter befindlichen Dateien und Verzeichnisse werden in die AIDE-Datenbank aufgenommen und mit der Gruppe DIR verknüpft; der Inhalt der Unterverzeichnisse wird nicht in die Datenbank aufgenommen
  • Ausschließlich /home wird aufgenommen; nicht jedoch der Inhalt davon
  • Das Verzeichnis /dev und alle darunterliegenden Dateien und Verzeichnisse werden nicht in die AIDE-Datenbank aufgenommen

Initialisierung der AIDE-Datenbank

Mit Sicherheit und Vertrauen ist das immer so eine Sache. Am besten ist es stets, wenn Vertrauen für Sicherheit nicht erforderlich ist. Daher rate ich an dieser Stelle nochmals ausdrücklich, die AIDE-Konfiguration zu überprüfen und ggf. den eigenen Bedürfnissen anzupassen… Nur um direkt gegen meinen eigenen Rat zu verstoßen.

Der Umfang an Regeln ist in beiden Systemen so groß, dass ich in dieser Einführung nicht alle einzeln erläutern kann. Ich vertraue für diese Einführung daher darauf, dass die Distributionen eine sinnvolle Konfiguration ausliefern.

Initialisiert wird die Datenbank je nach Distribution mit einem leicht abgewandelten Befehl.

Beispiel mit RHEL 9

$ sudo time aide --init
Start timestamp: 2023-09-18 20:50:06 +0200 (AIDE 0.16)
AIDE initialized database at /var/lib/aide/aide.db.new.gz

Number of entries:      54290

---------------------------------------------------
The attributes of the (uncompressed) database(s):
---------------------------------------------------

/var/lib/aide/aide.db.new.gz
  MD5      : xOf5Bs/Hb2Caa5i2K41fbg==
  SHA1     : KoCkqwfe+oZ2rlQTAU+AWQBrt2I=
  RMD160   : eM6IC68wq1VRhDbyHhRqy+63ldI=
  TIGER    : lQC+UTBqUm0iEDdKA0u7THqAPLNQxegH
  SHA256   : vdzjqIr/m7FgjXdZLQG+D1Pvf75WlF17
             WYiA6gU+4Pg=
  SHA512   : EdMB0I92j05zlfjXHcJFasZCAvkrK9br
             6zQEcDfD4IDM8D9c1Sz0r7A5tJTKGXVZ
             AFCOJR65j66ihKB0suFS6w==


End timestamp: 2023-09-18 20:50:19 +0200 (run time: 0m 13s)

Die erzeugte Datenbank wird umbenannt, indem das new aus dem Dateinamen entfernt wird.

$ sudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz

Die umbenannte Datei stellt die Referenzdatenbank dar, gegen die mit dem Befehl aide --check geprüft werden kann, ob es Änderungen im Dateisystem gab.

In diesem Artikel gebe ich mich damit zufrieden, dass die Datenbank auf dem zu überwachenden Host liegt und damit dem Risiko unterliegt, von einem Angreifer manipuliert zu werden (siehe zu den Schwächen oben). Ich gehe in einem Folgeartikel darauf ein.

Beispiel mit Debian 12

Unter Debian wird die AIDE-Datenbank mit dem Wrapper-Script aideinit (siehe aideinit(8)) initialisiert. Das README unter /usr/share/doc/aide-common/README.Debian.gz warnt bereits davor, dass Debian mit zu restriktiven Einstellungen daherkommt:

Configuring AIDE the Debian way
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AIDE’s Debian default configuration takes a very paranoid stance and
is likely to report more changes than you will need to focus your
attention on.

/usr/share/doc/aide-common/README.Debian.gz

Lassen wir uns überraschen…

$ sudo time aideinit
Running aide --init...
7044.57user 54.97system 2:00:40elapsed 98%CPU (0avgtext+0avgdata 132408maxresident)k
231120192inputs+88320outputs (12major+66397minor)pagefaults 0swaps

Das hat deutlich länger gedauert und endete mit einer deutlich kürzeren Ausgabe. Die erzeugte Datenbank ist jedoch wie bei RHEL im Verzeichnis /var/lib/aide/ zu finden.

:~# ls -l /var/lib/aide/
total 43536
-rw------- 1 root  root  22286930 Sep 19 15:13 aide.db
-rw------- 1 _aide _aide 22286930 Sep 19 15:13 aide.db.new
:~# qm start 102
:~# file /var/lib/aide/aide.db.new 
/var/lib/aide/aide.db.new: gzip compressed data, max compression, from Unix, original size modulo 2^32 44239215
:~# file /var/lib/aide/aide.db
/var/lib/aide/aide.db: gzip compressed data, max compression, from Unix, original size modulo 2^32 44239215

Warum die Erstellung so viel länger gedauert hat, weiß ich nicht. Ich habe keine Idee dazu. Auch Debian erzeugt eine gzip-komprimierte Datenbank, auch wenn hier keine Dateiendung darauf hinweist. Ich finde das etwas seltsam, behalte die Standardeinstellung für diese Einführung jedoch bei. Dafür muss die Datei nicht manuell umbenannt werden, da direkt eine Kopie erstellt wird, die als Referenzdatenbank genutzt werden kann.

Im Gegensatz zu RHEL wird unter Debian auch ein Timer namens dailyaidecheck.timer installiert, welcher täglich einen automatischen Check auf Veränderungen durchführt. Allerdings ist es für einen Angreifer ein Leichtes, diese Timer-Unit zu deaktivieren.

Auf Änderungen prüfen

Unter Debian und RHEL werden die in der Referenzdatenbank enthaltenen Elemente mit folgendem Befehl auf Änderungen überprüft:

:~# aide --check                                    # unter RHEL
:~# aide --check --config /etc/aide/aide.conf       # unter Debian

Ich habe meine Testsysteme ein paar Tage laufen lassen und einen AIDE-Integritätscheck durchgeführt. Hier das Ergebnis für ein RHEL 9 System:

$ sudo aide --check
Start timestamp: 2023-09-26 19:54:59 +0200 (AIDE 0.16)                          
AIDE found differences between database and filesystem!!                        
                                                                                
Summary:                                                                        
  Total number of entries:      54290   
  Added entries:                0                                               
  Removed entries:              0                                               
  Changed entries:              3                                               
                                                                                
---------------------------------------------------                             
Changed entries:                                                                
---------------------------------------------------               
                                                                                
f = ...    . ..S : /var/log/insights-client/insights-client.log.3               
f < ...    . ... : /var/log/rhsm/rhsmcertd.log                                  
f < ...    . ... : /var/log/squid/cache.log                                     
                                                                                
---------------------------------------------------              
Detailed information about changes:
---------------------------------------------------                             
                                                                                
File: /var/log/insights-client/insights-client.log.3                            
  SELinux  : system_u:object_r:insights_clien | unconfined_u:object_r:insights_c
             t_var_log_t:s0                   | lient_var_log_t:s0
                                                                                
File: /var/log/rhsm/rhsmcertd.log                                               
  Size     : 1426                             | 1343                            
                                                                                
File: /var/log/squid/cache.log                                                  
  Size     : 6230                             | 334              
                                                                                
                                                                                
---------------------------------------------------
The attributes of the (uncompressed) database(s):                               
---------------------------------------------------                             
                                                                                
/var/lib/aide/aide.db.gz                                                        
  MD5      : xOf5Bs/Hb2Caa5i2K41fbg==   
  SHA1     : KoCkqwfe+oZ2rlQTAU+AWQBrt2I=                                       
  RMD160   : eM6IC68wq1VRhDbyHhRqy+63ldI=                                       
  TIGER    : lQC+UTBqUm0iEDdKA0u7THqAPLNQxegH                                   
  SHA256   : vdzjqIr/m7FgjXdZLQG+D1Pvf75WlF17                                   
             WYiA6gU+4Pg=                                                       
  SHA512   : EdMB0I92j05zlfjXHcJFasZCAvkrK9br                                   
             6zQEcDfD4IDM8D9c1Sz0r7A5tJTKGXVZ                     
             AFCOJR65j66ihKB0suFS6w==                                           
                                                                                
                                                                                
End timestamp: 2023-09-26 19:55:12 +0200 (run time: 0m 13s)

Die Integritätsprüfung in obigen Code-Block führt Änderungen an drei Dateien auf:

  • Das SELinux-Label einer Log-Datei hat sich geändert
  • Die Größe von zwei weiteren Log-Dateien hat sich geändert
  • Die Änderungen werden in einer Zusammenfassung und im Detail ausgegeben
  • Eine Erläuterung zur Ausgabe unter „Changed entries“ findet sich im Absatz summarize_changes in aide.conf(5).
  • Man erhält Informationen darüber, was sich geändert hat, nicht warum sich diese Änderungen ergeben haben

Abbruch meiner Tests unter Debian 12 (Bookworm)

Unter Debian hat die Integritätsprüfung über Stunden einen CPU-Kern blockiert. Der Prozess ist in einem futex Syscall hängen geblieben.

Ob es an meinem System liegt oder AIDE unter Debian generell ein Problem hat, kann ich nicht sagen. Ich bin der Sache nicht weiter nachgegangen.

Falls jemand von euch AIDE unter Debian einsetzt und dies liest, freue ich mich, wenn ihr eure Erfahrungen mit mir teilt.

Die Referenzdatenbank aktualisieren

Mit dem Befehl aide --update wird die Datenbank-Integrität geprüft und eine neue Datenbank /var/lib/aide/aide.db.new.gz erzeugt. Die bestehende Referenzdatenbank /var/lib/aide/aide.db.gz wird dabei nicht überschrieben und bleibt zunächst erhalten. Möchte man diese länger aufbewahren, kann man sie umbenennen und bspw. einen Zeitstempel anhängen. Anschließend erzeugt man mit mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz eine neue Referenzdatenbank.

Der folgende Code-Block zeigt die Ausgabe von aide --update unter RHEL 9.

~]# aide --update                                            
Start timestamp: 2023-09-26 20:13:52 +0200 (AIDE 0.16)
AIDE found differences between database and filesystem!!
New AIDE database written to /var/lib/aide/aide.db.new.gz
                                                                                
Summary:                                
  Total number of entries:      54290
  Added entries:                0
  Removed entries:              0    
  Changed entries:              3                                               
                                                                                
---------------------------------------------------
Changed entries:                                                                
---------------------------------------------------
                                                                                
f = ...    . ..S : /var/log/insights-client/insights-client.log.3
f < ...    . ... : /var/log/rhsm/rhsmcertd.log
f < ...    . ... : /var/log/squid/cache.log

---------------------------------------------------        
Detailed information about changes:                                             
---------------------------------------------------

File: /var/log/insights-client/insights-client.log.3                     [0/100]
  SELinux  : system_u:object_r:insights_clien | unconfined_u:object_r:insights_c
             t_var_log_t:s0                   | lient_var_log_t:s0
                                                                                
File: /var/log/rhsm/rhsmcertd.log                                               
  Size     : 1426                             | 1343                            
                                                                                
File: /var/log/squid/cache.log                                                  
  Size     : 6230                             | 334                             
                                        
                                                                                
---------------------------------------------------                             
The attributes of the (uncompressed) database(s):
---------------------------------------------------         
                                        
/var/lib/aide/aide.db.gz       
  MD5      : xOf5Bs/Hb2Caa5i2K41fbg==                                           
  SHA1     : KoCkqwfe+oZ2rlQTAU+AWQBrt2I=                                       
  RMD160   : eM6IC68wq1VRhDbyHhRqy+63ldI=              
  TIGER    : lQC+UTBqUm0iEDdKA0u7THqAPLNQxegH                                   
  SHA256   : vdzjqIr/m7FgjXdZLQG+D1Pvf75WlF17         
             WYiA6gU+4Pg=                                                       
  SHA512   : EdMB0I92j05zlfjXHcJFasZCAvkrK9br            
             6zQEcDfD4IDM8D9c1Sz0r7A5tJTKGXVZ                                   
             AFCOJR65j66ihKB0suFS6w==   
                                        
/var/lib/aide/aide.db.new.gz     
  MD5      : Dgoc1/L5F1UfXPAQRvMdTg==
  SHA1     : 23RFwEBIh0kw/3TiiVAh39Fzx0Q=                                       
  RMD160   : 1szie2CW1dyLmaKFg01j48Fr+Us=                                       
  TIGER    : TgdG3zNAOSZH2D9jkyvBves8PtjC0lCR      
  SHA256   : hjn9vxFxg4KoVwT3YvgU347EhvTCg5ey                                   
             lfktpr/OrcA=                                                       
  SHA512   : x6E3YPa0eILD3nZqDt6N755KSmPRFOz8                                   
             lhKD9CimYScSpxyoVxJAVWiozR8KUwkt                    
             Ao7mgy3BgtUA0MZuNMv43w==                                           
                                                                                

End timestamp: 2023-09-26 20:14:03 +0200 (run time: 0m 11s)
~]# ls -l /var/lib/aide                                      
total 6184                                                                      
-rw-------. 1 root root 3163359 Sep 18 20:50 aide.db.gz                         
-rw-------. 1 root root 3163384 Sep 26 20:14 aide.db.new.gz

Ende

An dieser Stelle endet die Einführung in das Advanced Intrusion Detection Environment (AIDE). Kommt das Ende für euch abrupt? Ist es ein Ende mit Schrecken? Lasst es mich gern wissen.

In dieser Einführung habe ich beschrieben, was Intrusion-Detection-Systeme im Allgemeinen und AIDE im Speziellen sind. Ich bin auf deren Nutzen eingegangen und habe die Schwächen von AIDE als Host-basiertem IDS benannt. Installation, Konfiguration, Integritäts-Check und Aktualisierung der Datenbank wurden erklärt und mit Beispielen belegt.

Was ist nun von AIDE zu halten?

Nun, es ist besser als nichts. Man besitzt damit ein Werkzeug, mit dem sich Änderungen im Dateisystem erkennen lassen. Man muss sich jedoch der Schwächen Host-basierter IDS bewusst sein. Ein Angreifer mit lokalen root-Rechten kann dieses Werkzeug mit wenig Aufwand unschädlich machen bzw. die eigenen Änderungen verschleiern.

Sicher kann man einen Integritätscheck automatisiert alle 5 Minuten durchführen und für Änderungen eine E-Mail-Benachrichtigung einrichten. Doch wirkt dies etwas hemdsärmelig. Daher werde ich dieses Thema in einem späteren Artikel aufgreifen und zeigen, wie man AIDE in einen Automations- bzw. Konfigurations-Management-Prozess einbinden kann.

RHEL System Roles: rhc

11. September 2023 um 05:00

Im siebten Teil meiner losen Reihe über die RHEL System Roles stelle ich die Rolle rhc vor, mit welcher sich RHEL-Systeme (Version >= 8.6) in der Hybrid Cloud Console, Insights und dem RHSM registrieren lassen.

Das Tool rhc selbst habe ich bereits im Artikel Red Hat Remote Host Configuration ausführlich vorgestellt.

Anwendungsfall

Möchte man ein oder mehrere RHEL-Systeme in der Hybrid Cloud Console registrieren, kann man dazu die RHEL System Role rhc verwenden.

Die Rolle

Durch die Installation des Pakets rhel-system-roles existiert die Rolle rhc bereits auf meinem System und muss nur noch konfiguriert werden. Die Rolle selbst findet man im Pfad /usr/share/ansible/roles/rhel-system-roles.rhc/ und die Dokumentation in /usr/share/doc/rhel-system-roles/rhc/README.md.

Das Playbook

- name: Register systems
  hosts: all
  vars:
    rhc_auth:
      activation_keys:
        keys: ["key-1", ...]
    rhc_organization: "your-organization"
  roles:
    - rhel-system-roles.rhc
  • key-1 ist durch den eigenen Activation Key zu ersetzen
  • your-organization ist durch die eigene Org-ID zu ersetzen
  • Mit diesem Playbook werden die Hosts im RHSM und der Hybrid Cloud Console registriert
  • Die Systeme werden bei Insights registriert und laden regelmäßig aktuelle Daten hoch
  • Die Systeme werden für die Ausführung von Remediation Playbooks konfiguriert

Fazit

Mit dieser System Role ist es einfach möglich, eine große Anzahl Systeme in die Hybrid Cloud Console aufzunehmen. Dabei lässt sich konfigurieren, ob Funktionen wie Insights und Remediation Playbooks genutzt werden können.

Eine weitere tolle Rolle aus dem Paket rhel-system-roles, die sich einfach zur Anwendung bringen lässt.

Weiterführende Quellen und Links

  1. Red Hat Enterprise Linux (RHEL) System Roles {en}
  2. Ansible Documentation: Role Directory Structure {en}
  3. Red Hat Software and Download Center {en}
  4. Die Vorteile einer Red Hat Subskription
  5. RHEL System Roles: selinux
  6. RHEL System Roles: timesync
  7. RHEL System Roles: sshd
  8. RHEL System Roles: firewall
  9. RHEL System Roles: storage

Wie ich mich 2023 vor Datenverlust schütze

04. September 2023 um 05:00

Auf Mobiltelefonen, Tablets, Laptops, Netzwerkspeichern und in diversen Anwendungen in unserem Heimnetzwerk befinden sich Daten, welche wir schmerzlich vermissen würden, wenn sie dauerhaft verloren gingen.

Im Folgenden beschreibe ich, wie ich z.B. Fotos, Videos, Zeugnisse, Verträge, Urkunden, Versicherungspolicen, etc. vor Verlust schütze.

Der Artikel behandelt nicht:

Daten von Mobiltelefonen und Tablets

Sie sind unsere ständigen Begleiter, verfügen über große Speicher und beinhalten häufig jede Menge an Fotos und Videos. Diese werden mit DS-Apps auf eine Synology Diskstation im heimischen Netzwerk gesichert.

Für Threema benutze ich Threema Safe. Ein Datenbackup führe ich nicht durch. Der Inhalt der Nachrichten ist mir nicht so wichtig, als dass mich ein Verlust schmerzen würde.

E-Mails, Kalender und Kontakte werden zwischen Mailbox.org und diversen Geräten synchronisiert, jedoch nicht gesichert. Wenn jemand z.B. das Adressbuch löscht, müsste ich das Netzwerk vom PC trennen, um das Adressbuch ohne Netzwerkverbindung zu starten, um den letzten Stand von dort wiederherstellen zu können. Für mich ist das ausreichend, da ich bei einem GAU meine wichtigsten Kontakte auch ohne Adressbuch zu erreichen weiß und sich Kontaktinformationen von Handwerkern und sonstigen Unternehmen wieder recherchieren lassen.

Sollte ich Zugriff auf die App Aegis Authenticater verlieren, muss ich auf die Backup-Codes zurückgreifen, welche in einer KeePass-Datenbank lagern.

Falls ihr einfache Lösungen kennt, um sämtliche Apps samt deren Inhalte sichern und auf abweichenden Telefonen wiederherstellen zu können, freue ich mich, wenn ihr mir davon berichtet.

Network Attached Storage (NAS)

Meine Synology Diskstation ist:

  • Das Ziel für automatisierte Datensicherungen von Mobiltelefonen und Tablets
  • Datensicherungsziel für die Backups meiner virtuellen Server im LAN und in der Cloud
  • Primärer Speicherort für Fotos, Videos, eine Musiksammlung, Git-Repos
  • Primärspeicher für archivierte Daten, die ich vermutlich nie wieder benötige

Ausgewählte Daten werden wöchentlich mit Hyper Backup (Backup-Anwendung der Diskstation) auf eine angeschlossene USB-Festplatte gesichert. Darüber hinaus habe ich mir ein Offsite-Backup gebastelt, welches ich in diesem Artikel beschrieben habe.

Über Erfolg und Misserfolg der Sicherungen werde ich per E-Mail benachrichtigt.

Die größte Herausforderung für mich ist es, die Wiederherstellbarkeit der gesicherten Daten zu kontrollieren. Dies mache ich bisher sporadisch und manuell. Und vermutlich viel zu selten.

Daten von Laptops

Daten meiner Laptops synchronisiere ich teilweise mit Nextcloud, welche ich auf einem virtuellen Server betreibe. Gehostet wird dieser bei Contabo in Deutschland.

Darüber hinaus nutze ich Déjà Dup Backups für eine wöchentliche Datensicherung meines HOME-Verzeichnisses in die Nextcloud mit 180 Tagen Vorhaltezeit. Auch hier teste dich die Wiederherstellbarkeit sporadisch.

Das HOME-Verzeichnis meines Dienstlaptops wird täglich mit Déjà Dup in das Google Drive meines Arbeitgebers gesichert.

Urkunden, Verträge, Zeugnisse und weiterer Papierkram

Auch wir haben jede Menge totes Holz im Schrank stehen, dessen Wiederbeschaffung bei Verlust mit viel Zeit und Mühe verbunden ist.

Meine Lösung für diese Herausforderung habe ich in Mein Paperless-NGX-Mini-Konzept niedergeschrieben.

Hier möchte ich die Wiederherstellung noch verbessern, indem ich auf meinem Laptop ein Ansible-Playbook ablege, welches die Paperless-NGX-Instanz auf meinem Laptop wiederherstellt. So teste ich die Wiederherstellbarkeit und habe immer eine relativ aktuelle Kopie auf der verschlüsselten Festplatte meines Laptops bei mir.

Auf einem virtuellen Server in der Cloud möchte ich diese Daten aktuell nicht so gerne hosten. Dazu muss ich mir zuvor in Ruhe Gedanken über mögliche Risiken für die Integrität und Vertraulichkeit der Daten machen.

Meine produktive Paperless-NGX-Instanz steht mit dem Papier im gleichen Haus. Das Backup beinhaltet alle PDF-Dateien und liegt verschlüsselt in der Cloud. Da die Dateinamen halbwegs sinnvoll benannt sind, scheint im Falle eines GAU die Suche im Heuhaufen nicht hoffnungslos.

Blog und Nextcloud

Für beide Dienste, welche auf einem virtuellen Server bei Contabo laufen, wird zur Datensicherung wöchentlich ein Datenbank-Dump und ein Archiv der Verzeichnisstruktur mit Ordnern und Dateien erstellt. Dieses Backup wird lokal auf dem Server abgelegt und für 30 Tage vorgehalten. Ich nutze dafür selbstgeschriebene Bash-Skripte, welche durch Cron ausgeführt werden.

Auf meinem NAS läuft ein Skript, welches die Backups vom Server auf das NAS synchronisiert.

Über Erfolg und Misserfolg der einzelnen Jobs werde ich per E-Mail benachrichtigt.

Die Wiederherstellbarkeit teste ich sporadisch und sollte dies mutmaßlich häufiger tun. Ein Automat dafür befindet sich aktuell in Arbeit. Den aktuellen Stand kann man in folgenden Artikeln nachlesen:

Virtuelle Server und Dienste in der Cloud

Ruhende Daten werden verschlüsselt, bevor sie in die Cloud hochgeladen werden. Das Restrisiko, dass der fremde Betreiber prinzipiell die Kontrolle über meinen virtuellen Server übernehmen kann, bleibt.

Betreibe ich Server oder Dienst nicht im eigenen Heimnetzwerk, nutze ich für den Betrieb deutsche Anbieter mit Standorten in Deutschland. Zu diesen habe ich einfach das größte Vertrauen, dass sie sich an geltende Gesetze halten, die Hoffnung, dass sie den Datenschutz ernst nehmen und meine Daten dort gut aufbewahrt sind.

Wie sichert ihr eure Daten außer Haus? Welche Dienste verwendet ihr dazu? Ich freue mich, wenn ihr eure Erfahrungen in den Kommentaren teilt.

Zusammenfassung

Ich habe mir zumindest mal Gedanken gemacht, welche Daten so wichtig sind, dass ich sie vor Verlust schützen möchte. Zum Schutz vor Verlust kommen verschiedene Verfahren zum Einsatz, die auf der Schaffung von Redundanz durch Synchronisierung oder der Datensicherung mit Versionierung beruhen.

Die Wiederherstellbarkeit wird zumindest sporadisch getestet. Dieser Punkt ist sicherlich ausbaufähig.

Wer die einzelnen Abschnitte gelesen hat, stellt jedoch auch fest, dass es schnell ein wenig unübersichtlich wird. Zumindest hilft dieser Artikel etwas, den Überblick zu behalten.

Für die Zukunft wünsche ich mir eine dedizierte Backup-Senke im Keller, in der sich ausschließlich Backups befinden und eine Offsite-Senke, auf welche die Daten der Backup-Senke gesichert werden. Bis ich da hinkomme, wird sicherlich noch etwas Zeit vergehen.

Container mit podman-auto-update automatisch aktualisieren

28. August 2023 um 05:00

In diesem Tutorial zeige ich euch, wie ihr eine automatische Aktualisierung für Container in rootless-Podman-Umgebungen konfigurieren und diese Container als systemd-Services verwalten könnt.

Das Tutorial gliedert sich in folgende Abschnitte:

  1. Anwendungsfälle
  2. Voraussetzungen
  3. Umgebung und verwendetes Container-Image
  4. Konfiguration des systemd-Service mit Auto-Update-Funktion
  5. Container (automatisch) aktualisieren

Wer sich nicht für die möglichen Anwendungsfälle interessiert und lieber gleich starten möchte, kann den ersten Abschnitt überspringen. Die übrigen Abschnitte sollten in der angegebenen Reihenfolge gelesen werden.

Anwendungsfälle

  • Container werden auf einem Single-Container-Host ausgeführt und nicht in K8s-Umgebungen
  • Man vertraut dem Anbieter, dass dieser stabile und nutzbare Container-Images bereitstellt
  • Es soll regelmäßig geprüft werden, ob aktualisierte Container-Images vorhanden sind
  • Sind aktuellere Images vorhanden, sollen laufende Container entfernt und unter Verwendung der aktuellen Images neu erstellt werden

Voraussetzungen

Um diesem Tutorial folgen zu können, benötigt ihr einen Host mit einer rootless-Podman-Umgebung. Podman muss dabei in der Version >= 3.3 verfügbar sein. In der folgenden Liste findet ihr einige Links, die euch helfen, eine solche Umgebung aufzusetzen.

Darüber hinaus solltet ihr Manpages lesen können.

Umgebung und verwendetes Container-Image

Das Betriebssystem spielt eine untergeordnete Rolle, da wir durch die Verwendung von Containern die Anwendung vom Betriebssystem entkoppeln. Alle zur Ausführung der Anwendung notwendigen Abhängigkeiten sind im Container-Image enthalten.

Uptime Kuma ist eine schlanke und schnelle Monitoring-Anwendung, welche unter anderem als Container-Image bereitgestellt wird. Ich habe die Anwendung als Beispiel für dieses Tutorial ausgewählt, da ich die Anwendung selbst nutzen möchte und so Synergieeffekte nutzen kann.

Wer ein anderes Container-Image nutzen möchte, muss in den folgenden Beispielen louislam/uptime-kuma:latest durch den fully qualified container name des zu nutzenden Images ersetzen.

Für die Konfiguration werden die auf dem System verfügbaren Podman-Manpages benutzt.

Konfiguration des Systemd-Service mit Auto-Update-Funktion

Bei den folgenden Schritten habe ich mich am Beispiel aus podman-auto-update(1) orientiert. Ich zeige zuerst den jeweils auszuführenden Befehl in einem Code-Block, gefolgt von einer Erläuterung der genutzten Optionen.

Podman-Volume erzeugen

$ podman volume create uptime-kuma
uptime-kuma

Um Daten persistent speichern zu können, müssen diese außerhalb des Containers abgelegt werden. Der dargestellte Befehl erzeugt ein Podman-Volume mit dem Namen „uptime-kuma“.

Mit dem folgenden Befehl lassen sich detaillierte Informationen zum gerade erstellten Volume anzeigen:

$ podman volume inspect uptime-kuma
[
     {
          "Name": "uptime-kuma",
          "Driver": "local",
          "Mountpoint": "/home/tronde/.local/share/containers/storage/volumes/uptime-kuma/_data",
          "CreatedAt": "2023-08-22T20:52:06.477341481+02:00",
          "Labels": {},
          "Scope": "local",
          "Options": {},
          "MountCount": 0,
          "NeedsCopyUp": true,
          "NeedsChown": true
     }
]

Der Schlüssel Mountpoint enthält den Pfad im lokalen Dateisystem, in dem das Volume erstellt wurde.

Manpages zum Nachschlagen:

  • podman-volume(1)
  • podman-volume-create(1)
  • podman-volume-inspect(1)

Container starten

$ podman run --label "io.containers.autoupdate=registry" -d -p 3001:3001 -v uptime-kuma:/app/data:Z --name=uptime-kuma docker.io/louislam/uptime-kuma:latest
Trying to pull docker.io/louislam/uptime-kuma:latest...
Getting image source signatures
Copying blob d7ca72974892 done  
Copying blob 475646a04a73 done  
Copying blob 1d496c24aec8 done  
Copying blob 6a3727d8681d done  
Copying blob b00c91ba9805 done  
Copying blob ddade83992f9 done  
Copying blob b8454ed537a7 done  
Copying blob 849e609eff67 done  
Copying blob f861188db6a1 done  
Copying blob 5f3c3e6d7f1c done  
Copying blob 4f4fb700ef54 skipped: already exists  
Copying blob 68b7bcf7c878 done  
Copying config fb3a3565b2 done  
Writing manifest to image destination
Storing signatures
ad7b049d9b84962311f5bafb5329f59961d8a031e54a571f079b8243ea8059ee
  • podman run ist das Kommando, mit dem ein neuer Container gestartet wird
  • Die Option --label "io.containers.autoupdate=registry" gibt an, dass Podman die Remote-Registry prüft, ob dort ein aktualisiertes Image vorhanden ist; dieses Label ist Voraussetzung, um die Auto-Update-Funktion nutzen zu können
  • Mit der Option -d wird der Container im Hintergrund gestartet und die Container-ID auf STDOUT ausgegeben
  • Durch -p 3001:3001 wird der Host-Port 3001 mit dem Port der Anwendung (ebenfalls 3001) im Container verbunden
  • Die Option -v uptime-kuma:/app/data:Z hängt das im vorhergehenden Schritt erstellte Podman-Volume in das Verzeichnis /app/data innerhalb des Containers ein; :Z sorgt dafür, dass der SELinux-Kontext korrekt gesetzt wird
  • --name=uptime-kuma spezifiziert den Namen des Containers; dieser ist etwas leichter zu merken als die Container-ID
  • Der Befehl endet mit dem fully qualified container name docker.io/louslam/uptime-kuma:latest
  • Die letzte Zeile des Code-Blocks enthält die Container-ID

Manpages zum Nachschlagen:

  • podman-run(1)
  • podman-auto-update(1)

Systemd-Service-Unit mit podman-generate-systemd erstellen

$ podman generate systemd --name --new uptime-kuma
# container-uptime-kuma.service
# autogenerated by Podman 4.4.1
# Tue Aug 22 21:29:46 CEST 2023

[Unit]
Description=Podman container-uptime-kuma.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStart=/usr/bin/podman run \
	--cidfile=%t/%n.ctr-id \
	--cgroups=no-conmon \
	--rm \
	--sdnotify=conmon \
	--replace \
	--label io.containers.autoupdate=registry \
	-d \
	-p 3001:3001 \
	-v uptime-kuma:/app/data:Z \
	--name=uptime-kuma docker.io/louislam/uptime-kuma:latest
ExecStop=/usr/bin/podman stop \
	--ignore -t 10 \
	--cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm \
	-f \
	--ignore -t 10 \
	--cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all

[Install]
WantedBy=default.target
  • Der Befehl gibt den Inhalt der generierten Service-Unit auf STDOUT aus
  • Die Option --name verwendet den Namen des Containers anstelle der Container-ID im Dateinamen der Service-Unit (hier: container-uptime-kuma.service)
  • Wichtig ist die Option --new, um Container von aktualisierten Images erstellen zu können; ohne diese Option können Systemd-Units Container nur unter Verwendung des ursprünglichen Images starten und stoppen und ein Auto-Update ist nicht möglich
  • Der folgende Code-Block fügt dem Befehl die Option --files hinzu, um eine Service-Unit-Datei zu erstellen
$ podman generate systemd --name --new --files uptime-kuma
/home/tronde/container-uptime-kuma.service

Manpages zum Nachschlagen:

  • podman-auto-update(1)
  • podman-generate-systemd(1)

Die erstellte Systemd-Unit aktivieren und starten

$ mv -Z container-uptime-kuma.service ~/.config/systemd/user/container-uptime-kuma.service
$ systemctl --user daemon-reload
  • Der erste Befehl verschiebt die Service-Unit in einen Pfad, wo systemd sie findet und einlesen kann
  • Die Option -Z stellt sicher, dass die Datei den SELinux-Kontext des Zielverzeichnisses zugewiesen bekommt, andernfalls kann systemd die Datei ggf. nicht verarbeiten
  • Durch den zweiten Befehl wird die Unit-Datei systemd bekannt gemacht
  • An dieser Stelle ist der neue Systemd-Service geladen, jedoch inaktiv
$ systemctl --user status container-uptime-kuma.service
○ container-uptime-kuma.service - Podman container-uptime-kuma.service
     Loaded: loaded (/home/tronde/.config/systemd/user/container-uptime-kuma>
     Active: inactive (dead)
       Docs: man:podman-generate-systemd(1)
$ podman stop uptime-kumauptime-kuma
$ podman rm uptime-kumauptime-kuma
$ systemctl --user start container-uptime-kuma.service
$ systemctl --user status container-uptime-kuma.service
● container-uptime-kuma.service - Podman container-uptime-kuma.service     Loaded: loaded (/home/tronde/.config/systemd/user/container-uptime-kuma>     Active: active (running) since Tue 2023-08-22 21:59:56 CEST; 14s ago
…
  • Der erste Befehl in obigen Code-Block prüft den aktuellen Status des Service
  • Der zweite und dritte Befehl stoppen und entfernen den laufenden Container, den wir weiter oben gestartet haben
  • Befehl Nummer 4 startet den Uptime-Kuma-Service
  • Befehl Nummer 5 prüft den neuen Status des Service; dieser ist nun up-and-running

Manpages zum Nachschlagen:

  • mv(1)
  • systemd.unit(5)
  • systemctl(1)

Auf neue Container-Images prüfen

$ podman auto-update --dry-run --format "{{.Image}} {{.Updated}}"
docker.io/louislam/uptime-kuma:latest false
  • Durch die Option --dry-run wird sichergestellt, dass nur auf die Verfügbarkeit neuer Images geprüft wird, es werden jedoch keine Pull-Operationen ausgeführt und keine Container neu erstellt
  • Es wird eine Liste von Container-Images ausgegeben, die mit dem Label io.containers.autoupdate=registry gestartet wurden
  • Die erste Spalte enthält den Image-Namen
  • Die zweite Splate zeigt an, ob ein Update verfügbar ist; in diesem Fall ist kein Update verfügbar (false)

Container (automatisch) aktualisieren

Wurde die Konfiguration erfolgreich abgeschlossen, können die entsprechenden Container durch folgenden Befehl manuell aktualisiert werden:

$ podman auto-update
            UNIT                           CONTAINER                   IMAGE                                  POLICY      UPDATED
            container-uptime-kuma.service  df21116f2573 (uptime-kuma)  docker.io/louislam/uptime-kuma:latest  registry    false

Leider ist aktuell kein Update verfügbar, weshalb es hier nichts zu tun gibt und der Status von Updated gleich false ist.

Podman bringt bei der Installation die beiden systemd units podman-auto-update.timer und podman-auto-update.service mit, welche zumindest unter RHEL 9 manuell aktiviert werden müssen:

$ systemctl --user enable podman-auto-update.{service,timer}
Created symlink /home/tronde/.config/systemd/user/default.target.wants/podman-auto-update.service → /usr/lib/systemd/user/podman-auto-update.service.
Created symlink /home/tronde/.config/systemd/user/timers.target.wants/podman-auto-update.timer → /usr/lib/systemd/user/podman-auto-update.timer.

$ systemctl --user start podman-auto-update.timer
$ systemctl --user status podman-auto-update.{service,timer}
○ podman-auto-update.service - Podman auto-update service
     Loaded: loaded (/usr/lib/systemd/user/podman-auto-update.service; enabled; preset: disabled)
     Active: inactive (dead)
TriggeredBy: ● podman-auto-update.timer
       Docs: man:podman-auto-update(1)

● podman-auto-update.timer - Podman auto-update timer
     Loaded: loaded (/usr/lib/systemd/user/podman-auto-update.timer; enabled; preset: disabled)
     Active: active (waiting) since Sat 2023-09-02 20:56:09 CEST; 1s ago
      Until: Sat 2023-09-02 20:56:09 CEST; 1s ago
    Trigger: Sun 2023-09-03 00:12:22 CEST; 3h 16min left
   Triggers: ● podman-auto-update.service
  • Der Timer startet jeden Tag um Mitternacht den Auto-Update-Service
  • Der Service prüft, ob aktualisierte Container-Images verfügbar sind und führt ggf. ein Update der Container durch
  • Schlägt ein Start nach Aktualisierung des Container-Images fehl, wird der Dienst automatisch von der vorherigen Image-Version gestartet; siehe --rollback in podman-auto-update(1)
  • Der folgende Code-Block zeigt den Status, nachdem ein Update durchgeführt wurde
$ systemctl --user --no-pager -l status podman-auto-update
○ podman-auto-update.service - Podman auto-update service
     Loaded: loaded (/usr/lib/systemd/user/podman-auto-update.service; enabled; preset: disabled)
     Active: inactive (dead) since Sun 2023-09-03 00:12:56 CEST; 7h ago
TriggeredBy: ● podman-auto-update.timer
       Docs: man:podman-auto-update(1)
    Process: 309875 ExecStart=/usr/bin/podman auto-update (code=exited, status=0/SUCCESS)
    Process: 310009 ExecStartPost=/usr/bin/podman image prune -f (code=exited, status=0/SUCCESS)
   Main PID: 309875 (code=exited, status=0/SUCCESS)
        CPU: 5.128s

Sep 03 00:12:50 example.com podman[309875]: Copying config sha256:d56b643e048f2d351ed536ec9a588555dfd4c70de3c8d510ed61078a499ba464
Sep 03 00:12:50 example.com podman[309875]: Writing manifest to image destination
Sep 03 00:12:50 example.com podman[309875]: Storing signatures
Sep 03 00:12:51 example.com podman[309875]: 2023-09-03 00:12:41.98296115 +0200 CEST m=+1.880671312 image pull  docker.io/louislam/uptime-kuma:latest
Sep 03 00:12:55 example.com podman[309875]:             UNIT                           CONTAINER                   IMAGE                                  POLICY      UPDATED
Sep 03 00:12:55 example.com podman[309875]:             container-uptime-kuma.service  814407c7312c (uptime-kuma)  docker.io/louislam/uptime-kuma:latest  registry    true
Sep 03 00:12:56 example.com podman[310009]: fb3a3565b2da641402e99594e09b3cdadd1b9aa84f59e7960b9961662da5ff65
Sep 03 00:12:56 example.com podman[310009]: 2023-09-03 00:12:55.421998943 +0200 CEST m=+0.020260134 image remove fb3a3565b2da641402e99594e09b3cdadd1b9aa84f59e7960b9961662da5ff65 
Sep 03 00:12:56 example.com systemd[686]: Finished Podman auto-update service.
Sep 03 00:12:56 example.com systemd[686]: podman-auto-update.service: Consumed 5.128s CPU time.

Ich hoffe, das Tutorial hat euch gefallen und konnte euch einen Eindruck vermitteln, wie man automatische Updates für Container konfigurieren kann.

Red Hat Remote Host Configuration

21. August 2023 um 05:00

Im folgenden Text gebe ich eine Einführung in Red Hat Remote Host Configuration (rhc). Dabei handelt es sich um ein Werkzeug, um Red Hat Enterprise Linux (RHEL) System mit der Hybrid Cloud Console zu verbinden und aus dieser heraus verwalten zu können.

Der Artikel soll interessierten RHEL-Nutzern zur Information und Wissensvermittlung dienen. Dazu wird rhc auch im Kontext subscription-manager und insights-client eingeordnet.

Aus Gründen der Transparenz weise ich hiermit darauf hin, dass ich Angestellter der Firma Red Hat bin.

Hintergrund

Als ich persönlich angefangen habe, mich für RHEL zu interessieren, war die Version 7 aktuell und von Simple Content Access (SCA) noch keine Rede. Um RHEL-Systeme betreiben zu können, waren diese beim Red Hat Subscription Management (RHSM), einem Satellite-Server oder offline zu registrieren, um Subscription Entitlements zuweisen zu können. Hierfür gab und gibt es das Kommando subscription-manager.

Im Laufe der Zeit kam der Dienst Red Hat Insights hinzu, zu welchem es hier im Blog bereits eine Einführung gab. Um Systeme hierfür zu registrieren, gibt es das Kommando insights-client. Die Console, die einst nur Red Hat Insights beheimatete, hat sich zur Hybrid Cloud Console entwickelt, welche heute Heimat für viele weitere Dienste rund um RHEL, OpenShift und die Ansible Automation Platform (AAP) ist.

Es hat sich viel getan. Dank SCA [1] entfällt die Notwendigkeit, Entitlements zuweisen zu müssen und das Subscription Management befindet sich im Übergang zur Hybrid Cloud Console. Übergang bedeutet hier insbesondere, dass viele Teile in Bewegung sind und sich in Zukunft noch ändern werden. Der Artikel unter [6] gibt einen Überblick dazu.

Hybrid Cloud Console mit Insights und Ansible Remediation Playbooks

Die folgenden vier Absätze wurden der Dokumentation entnommen und mit www.DeepL.com/Translator (kostenlose Version) übersetzt.

Die Red Hat Hybrid Cloud Console ist eine webbasierte, einheitliche Verwaltungsoberfläche für Red Hat-Lösungen. Mit der Hybrid Cloud Console können Sie eine Verbindung zu Ihren verschiedenen Plattformen herstellen und dann Ihre Hybrid Cloud und die darin enthaltenen Systeme zentral verwalten und automatisieren.

Verwenden Sie die Hybrid Cloud Console, um Ihre RHEL-Infrastruktur, Red Hat OpenShift-Cluster, AAP-Infrastruktur und Anwendungsdienste zu verwalten.

Die Red Hat Hybrid Cloud Console bietet einen zentralen Einblick in Betrieb, Sicherheit und Subscriptions für Red Hat Enterprise Linux (RHEL).

Mithilfe von Tools, regelbasierten Analysemodellen und der Unterstützung von Red Hat können Sie die Konsole nutzen, um viele der Aufgaben und Analysen zu optimieren, die für den Aufbau und die Bereitstellung einer stabilen und sicheren Umgebung für Anwendungen auf RHEL erforderlich sind.

Dem Marketing-Text der vorstehenden Absätze möchte ich einen Hinweis hinterherschicken. Mit der Hybrid Cloud Console verhält es sich wie mit allen extern gehosteten Cloud-Diensten. Hat der Anbieter ein Problem oder ist die Cloud bzw. das Internet nicht verfügbar, ist auch der Cloud-Dienst nicht verfügbar. Bei der Fähigkeit, meine Infrastruktur zu administrieren, möchte ich mich persönlich daher nicht allein auf einen externen Dienst verlassen und empfehle dies auch niemanden. In meinen Augen ist die Hybrid Cloud Console ein zusätzliches Werkzeug, welches mit Red Hat Insights einen hohen Mehrwert bietet.

In den nun folgenden Abschnitten beschreibe ich, wie in der Hybrid Cloud Console ein Activation Key erstellt wird und wie man diesen nutzt, um Systeme mittels rhc in der Console zu registrieren. Anschließend zeige ich, wie dank rhc Ansible Remediation Playbooks direkt aus der Console heraus auf verbundenen RHEL-Systemen ausgeführt werden können.

Ob man einem extern durch Dritte gehosteten Dienst das Recht einräumen möchte, Änderungen an den eigenen Server-Systemen durchführen zu können, muss jeder für sich selbst und seine Umgebung bewerten. Ich möchte hier lediglich die Funktionalität in meiner Lab-Umgebung demonstrieren.

Activation Key erstellen

Um einen Activation Key zu erstellen [10], meldet man sich an der Hybrid Cloud Console (https://console.redhat.com) an und tippt in das Suchfeld im oberen Bereich „create activation key“ ein.

Startseite der Hybrid Cloud Console. In das Suchfeld im oberen Bereich der Seite wurde der Text "create activation key" eingegeben. Es werden zwei Suchergebnisse angezeigt.
Ausgefüllte Suchmaske in der Hybrid Cloud Console

Der erste Treffer führt uns zu folgender Maske, in der ein Activation Key erstellt werden kann:

Menü zur Erstellung von Activation Keys
Dialog zum Erstellen von Activation Keys. Hier werden die Parameter Name, Role, SLA und Usage definiert.
Dialog zur Erstellung des Activation Keys

Nach einem Klick auf die Schaltfläche Create activation key erscheint der oben dargestellte Dialog. Die Optionen, die unter Role, Service Level Agreement (SLA) und Usage zur Auswahl stehen, hängen von den im Account vorhandenen Subscriptions ab. Mit ihnen wird der sogenannte System Purpose bestimmt. Der Name kann frei gewählt werden. Er erscheint anschließend in der Übersicht.

Übersicht existierender Activation Keys
Übersicht der existierenden Activation Keys

Hinweis: Die Organization ID und der Name des Activation Key sind vertraulich zu behandeln, da mit diesen Informationen Systeme für die Hybrid Cloud Console registriert werden können.

System mit rhc registrieren

Mit dem Befehl rhc -h erhält man eine Beschreibung, wie Organization ID und Activation Key genutzt werden, um das System bei Red Hat zu registrieren:

DESCRIPTION:
   The rhc command controls the system's connection to Red Hat.
   
   To connect the system using an activation key:
     rhc connect --organization ID --activation-key KEY

Führt man den Befehl wie angegeben aus und ist die Registrierung erfolgreich, erhält man folgende Ausgabe:

Connecting host.example.com to Red Hat.
This might take a few seconds.

● Connected to Red Hat Subscription Management
● Connected to Red Hat Insights
● Activated the Remote Host Configuration daemon
● Enabled console.redhat.com services: remote configuration, insights, remediations, compliance

Successfully connected to Red Hat!

Manage your connected systems: https://red.ht/connector

Unter der URL https://red.ht/connector ist der Remote Host Configuration Manager erreichbar. Hier werden die aktuellen Einstellungen angezeigt und können bei Bedarf geändert werden.

Das Bild zeigt die Konfigurationsseite des Remote Host Configuration Manager. Hier werden die Einstellungen für Insights Remediations, rhc Einstellungen und OpenSCAP Policies vorgenommen.
Darstellung der Seite Remote Host Configuration Manager

Der rhc Client konfiguriert auf dem RHEL host den rhcd service, welcher die Verbindung zur Hybrid Cloud Console initiiert und über eine MQTT-Verbindung auf Instruktionen lauscht [14].

Möchte man mehrere Systeme registrieren, empfehle ich die Verwendung der RHEL System Role rhc. Auf diese werde ich in einem folgenden Beitrag noch genauer eingehen.

Die Registrierung und Einbindung in die Hybrid Cloud Console ist damit abgeschlossen.

Ansible Remediation Playbook erstellen und ausführen

Die offizielle Dokumentation für die folgenden Schritte befindet sich unter [12]. Ich habe ein System gewählt, welches noch nicht aktualisiert wurde und daher einige Schwachstellen aufweist.

Das Bild zeigt eine Übersicht von CVEs. Zwei CVEs wurden für die Remediation mit Ansible ausgewählt.
Übersicht der vorhandenen CVE. Zwei Einträge wurden für die Remediation mit Ansible ausgewählt.

In der Übersicht können CVE ausgewählt werden, welche mit Hilfe eines Ansible Remediation Playbook geschlossen werden sollen. Mit einem Klick auf die Schaltfläche Remediate gelangt man in den Assistenten zur Erstellung des Playbooks.

Das Bild zeigt einen Dialog, in dem ein Name für ein neues Playbook vergeben wird.
Der Name des Playbooks kann frei gewählt werden.
Im dargestellten Dialog werden die ausgewählten Systeme angezeigt. Eine Bearbeitung ist hier nochmals möglich.
In Schritt zwei können verwundbare Systeme ausgewählt werden.
Das Bild zeigt den letzten Dialog des Remediate-Assistenten. Es wird auf einen automatischen Neustart hingewiesen.
Review der Einstellungen mit dem Hinweis, dass das Zielsystem durch das Playbook automatisch neugestartet wird.
Das Bild zeigt einen Screenshot von der erfolgreichen Erstellung eines Playbooks.
Bis hierher wurde nur ein Playbook erstellt. Es wurde noch keine Remediation durchgeführt.

Die erstellten Playbooks findet man im Menü unter Red Hat Insights –> Automation Toolkit –> Remediations. Bisher kann das Playbook hier allerdings nur heruntergeladen werden, um es auf einem Ansible Controller in der eigenen Infrastruktur auszuführen. Um diese Playbooks direkt aus der Hybrid Cloud Console heraus ausführen zu können, muss der verwendete User Mitglied einer Gruppe mit der Rolle Remediations administrator sein.

Ein Exkurs in die Rollen- und Rechteverwaltung der Hybrid Cloud Console würde an dieser Stelle zu weit führen. Nachdem die Voraussetzungen für die Ausführung von Remediation Playbooks geschafften wurden, stehen folgende Schritte zur Verfügung.

In der Ansicht des Remediation Jobs kann das Playbook nun direkt ausgeführt werden.
Eine letzte Bestätigung, dann geht es los.

Im Hintergrund passiert nun folgendes:

  1. Das Playbook wird auf den oder die Hosts übertragen
  2. Auf den Hosts wird es durch die dort lokal installierte Ansible Engine (Paket ansible-core) ausgeführt
  3. Der Host wird anschließend automatisch neugestartet
  4. In der Console wird anschließend sichbar, dass die Remediation abgeschlossen wurde

Ob man einem SaaS-Dienst, der von einem US-Unternehmen in den USA gehostet wird, Zugriff auf die eigenen Server gewähren möchte bzw. darf, muss individuell bewertet werden.

Ich gestehe dem Service allerdings zu, dass er die Verwaltung und Remediation von Sicherheitslücken, fehlenden Advisories und Konfigurationsanpassungen durch den Advisor denkbar einfach gestaltet.

Ein Werkzeug für alles?

Für die in diesem Text aufgeführten Anwendungsfälle

  • Registrieren eines RHEL-Hosts an der Hybrid Cloud Console
  • Ausführen von Ansible Remediation Playbooks

ist die Verwendung des rhc-Clients ausreichend; ein Ersatz für den insights-client ist er allerdings nicht. Letzterer wird im Hintergrund weiterhin verwendet, um Insights-Reports an die Hybrid Cloud Console zu senden.

Auch die vielfältigen Optionen des subscription-manager werden nicht abgebildet. Der rhc-Client ist daher mehr eine Ergänzung als ein Ersatz für die bekannten Kommandos.

Fazit

Der rhc-Client ist in meinen Augen das Mittel der Wahl, möchte man RHEL-Systeme für die Verwaltung durch Insights und die Ausführung von Ansible Remediation Playbooks an die Hybrid Cloud Console anbinden.

Ich hoffe euch interessierten Lesern, die bishierhin ausgehalten haben, hat diese Einführung gefallen. In der folgenden Liste findet ihr einige Links, hinter denen ihr euer Wissen noch vertiefen könnt.

Quellen und weiterführende Links

  1. Remote Host Configuration and Management – Using the remote host configuration and management features for Red Hat Insights
  2. Simple Content Access
  3. Red Hat Subscription Management
  4. Red Hat Insights
  5. Einführung in Red Hat Insights
  6. Transition of Red Hat’s subscription services to console.redhat.com
  7. Red Hat Hybrid Cloud Console
  8. Product Documentation for Red Hat Hybrid Cloud Console 2023
  9. Subscription-Manager for the former RHN user, part 13: System Purpose
  10. Remote Host Configuration and Management: Chapter 6. Creating and managing activation keys in the Red Hat Hybrid Cloud Console
  11. Automating system administration by using RHEL System Roles: Chapter 7. Using the rhc System Role to register the system
  12. Creating and managing remediation playbooks in Insights
  13. Executing remediation playbooks
  14. Remote Host Configuration (rhc)

Warum entwickelt/testet ihr (nicht) auf CentOS Stream, Fedora oder RHEL?

07. August 2023 um 05:00

Hi, mein Name ist Jörg. Ich arbeite seit März 2023 als Senior Technical Account Manager für Red Hat und mir schwirren derzeit folgende Fragen im Kopf herum:

  • Wer sind die Menschen, die Open Source Software auf bzw. für CentOS Stream, Fedora und/oder RHEL entwickeln?
    • Sind es Menschen, die dies ausschließlich in ihrer Freizeit tun?
    • Arbeiten sie in Unternehmen, welche nach dem Open Source Entwicklungsmodell arbeiten?
  • Warum habt ihr euch für oder gegen die eine oder andere Distribution entschieden?
  • Was hindert euch daran, eine der genannten Distributionen zu verwenden?
  • Aus welchem Grund bevorzugt ihr andere Distributionen und welche sind dies?

Hinsichtlich dieser Fragen habe ich selbst offensichtlich einen Interessenskonflikt und bin darüber hinaus zu einem hohen Grad betriebsblind. Deshalb bin ich umso mehr daran interessiert, eure Antworten auf diese Fragen zu lesen.

Ich freue mich, wenn ihr euch die Zeit nehmt, um mir zu antworten und mir zu erläutern, wie ihr dazu steht. Eure Nachrichten nehme ich gern auf folgenden Kanälen entgegen:

  • Als Kommentar unter diesem Artikel
  • Als E-Mail an jkastning+distribution (at) my-it-brain (dot) de
  • Als Chat-Nachricht in #my-it-brain:matrix.org

Es freut mich, wenn daraus eine freundliche und konstruktive Diskussion entsteht. Sollte es dabei allerdings zu Trolling oder unangemessenen Äußerungen kommen, werde ich die Kommentare schließen und die Kommunikation einstellen. Bitte geht daher höflich miteinander um und behandelt einander so, wie ihr selbst auch behandelt werden möchtet.

Mein Paperless-NGX-Mini-Konzept

31. Juli 2023 um 05:00

Paperless-NGX ist ein bekanntes und beliebtes Open Source Dokumenten-Management-System (DMS). Auch ich möchte zukünftig meinen „Papierkram“ darin verwalten.

In diesem Artikel halte ich meine Gedanken fest, wie ich plane, paperless-ngx in meiner Umgebung aufzusetzen und zu betreiben.

Dies hilft mir, zu prüfen, ob ich auch an alles Wichtige gedacht habe. Falls euch das Konzept gefällt, dürft ihr es selbstverständlich gerne nachahmen. Und wenn ihr schwerwiegende Fehler darin entdeckt, freue ich mich über einen Hinweis.

Es ist kein Tutorial und keine Schritt-für-Schritt-Anleitung. Zwar mag dieser Text dazu dienen, sich eine eigene Umgebung aufzubauen, Mitdenken ist dabei jedoch zwingend erforderlich.

Ziele

  • Betrieb von Paperless-NGX als rootless-Podman-Container
  • Consumption-Ordner als Samba-Share freigegeben, um via Netzwerk Dateien hineinkopieren zu können
  • Getrennte Benutzerkonten für meine Frau und mich
  • Freigabe gewisser Dokumente für weitere Benutzer(gruppen)
  • Erfolgreicher Restore-Test

Infrastruktur

In meinem Heimnetzwerk betreibe ich einen Desktop-/Server-PC. Auf diesem läuft aktuell RHEL 9 als KVM/QEMU-Hypervisor. Er dient mir ebenfalls als Ansible Control Node. Hierauf betreibe ich eine RHEL-9-VM mit einer rootless-Podman-Installation. Diese VM wird auch meine Paperless-NGX-Instanz hosten.

In der VM wird das EPEL-Repository aktiviert, um daraus die Pakete podman-compose und python3-pexpect installieren zu können.

Falls ich mal nicht mehr weiß, wie dieses Setup aufgebaut wird, finden sich dazu Hinweise in folgenden Links:

Installation mit Ansible

Für die Installation der Anwendung wird die Container Route verwendet. Die Installation wird dabei unter Nutzung der Ansible-Rolle tronde.paperless_ngx_with_rootless_podman automatisiert.

Das Playbook deploy_paperless_ngx.yml, welches auf meiner Synology Diskstation abgelegt ist, führt die Installation und Konfiguration der Anwendung durch. Es installiert und konfiguriert zudem Samba und die Datei-Freigabe des Consumption-Verzeichnisses.

In dem Playbook werden folgende Rollen verwendet:

Die Rollen sind mit dem Playbook in meinem Ansible-Projekt-Verzeichnis auf meiner Synology Diskstation installiert.

Alle Playbooks und Rollen werden mit Git versioniert. Die Repositories werden auf entfernte Rechner synchronisiert.

Vorbereitung

Die Dateien docker-compose.postgres-tika.yml, docker-compose.env und .env werden aus dem Projekt-Repository in das Rollen-Verzeichnis files meiner Ansible-Rolle heruntergeladen. Die Datei docker-compose.postgres-tika.yml wird dabei zu docker-compose.yml umbenannt und bearbeitet.

Um Datenverlust vorzubeugen, wird die Ansible-Rolle mit den angepassten Dateien in die regelmäßige Datensicherung aufgenommen.

Folgende Variablen werden in meinem Ansible-Vault hinterlegt:

# Paperless-ngx with podman-compose
pnwrp_podman_user: alice
pnwrp_podman_group: alice
pnwrp_compose_dir: /home/{{ pnwrp_podman_user }}/paperless-ngx
pnwrp_paperless_superuser: alice
pnwrp_paperless_superuser_email: alice@example.com
pnwrp_paperless_superuser_password: ImWunderland
## Username and password for document scanner
brother_scanner_user: scanner
brother_scanner_pass: ImWunderland

Die Werte der Variablen werden selbstverständlich angepasst.

Das Playbook

Folgender Code-Block zeigt das fertige Playbook mit Beispielwerten:

---
- hosts: host.example.com
  remote_user: alice
  debugger: never
  vars_files:
    - files/alice.vault
  tasks:
    - name: Setup Paperless-NGX with podman-compose in rootless Podman
      include_role:
        name: ansible_role_paperless-ngx_with_rootless_podman

    - name: Enable Port 8000/tcp in host firewall
      ansible.posix.firewalld:
        port: 8000/tcp
        immediate: true
        permanent: true
        state: enabled
      become: true

    - name: >-
        Create and add {{ brother_scanner_user }} to
        {{ pnwrp_podman_group }}
      ansible.builtin.user:
        name: "{{ brother_scanner_user }}"
        comment: "Brother Dokumenten-Scanner"
        create_home: false
        groups: "{{ pnwrp_podman_group }}"
        append: true
        shell: /usr/sbin/nologin
        state: present
        system: true
      become: true

    - name: Include role vladgh.samba.server
      include_role:
        name: vladgh.samba.server
      vars:
        ansible_become: true
        samba_users:
          - name: "{{ pnwrp_podman_user }}"
            password: "{{ alice_password }}"
          - name: "{{ brother_scanner_user }}"
            password: "{{ brother_scanner_pass }}"
        samba_shares:
          - name: consumption
            comment: 'paperless consumption directory'
            path: "{{ pnwrp_compose_dir }}/consume"
            read_only: false
            guest_ok: false
            browseable: true
            owner: "{{ pnwrp_podman_user }}"
            group: "{{ pnwrp_podman_group }}"
            write_list: +{{ pnwrp_podman_group }}

    - name: Enable samba in host firewall
      ansible.posix.firewalld:
        service: samba
        immediate: true
        permanent: true
        state: enabled
      become: true

Das Playbook gewinnt sicher keinen Schönheitswettbewerb, doch arbeitet es bisher robust und tut, was es soll. In Tests habe ich meine Wunschumgebung damit mehrmals provisioniert.

Backup & Restore

Wie es sich gehört, wird erst ein Backup erstellt, dann die Anwendung inkl. aller Daten gelöscht und wiederhergestellt.

Backup

Für das Backup verwende ich ein Ansible-Playbook, welches sich zum Podman-Host verbindet und dort folgende Aufgaben ausführt:

  1. Stelle sicher, dass das Backup-Verzeichnis auf dem Remote-Host existiert
  2. Stoppe alle Paperless-NGX-Container
  3. Exportiere Podman-Volumes in TAR-Archive; hänge das aktuelle Datum an die Dateinamen an
  4. Archiviere und komprimiere paperless-ngx-Verzeichnis auf Remote-Host; hänge das aktuelle Datum an die Dateinamen an
  5. Starte alle Paperless-NGX-Container
  6. Komprimiere die Exporte der Podman-Volumes
  7. Synchronisiere das Backup-Verzeichnis auf dem Remote-Host mit einem Verzeichnis auf meiner Diskstation
  8. Synchronisiere das Diskstation-Verzeichnis mit einem verschlüsselten S3-Bucket

Es fehlt die Aufgabe, alte Backups aufzuräumen. Darum werde ich mich kümmern, wenn 70% des verfügbaren Speicherplatzes belegt sind.

Der folgende Code-Block zeigt ein Muster des verwendeten Playbooks:

---
- name: Backup podman volumes
  hosts: host.example.com
  gather_facts: true
  vars:
    paperless_ngx_dir: /home/alice/paperless-ngx
    docker_compose_file: docker-compose.yml
    remote_backup_dir: /home/alice/backups
    diskstation_backup_dir: /home/alice/diskstation/home/backups/host.example.com

  tasks:
    - name: Ensure backup directory exists
      ansible.builtin.file:
        path: "{{ remote_backup_dir }}"
        state: directory
        owner: alice
        group: alice
        mode: 0777

    - name: Stop paperless-ngx containers
      ansible.builtin.command: >
        podman-compose -f {{ paperless_ngx_dir }}/{{ docker_compose_file }} stop

    - name: List podman volumes
      ansible.builtin.command: podman volume ls --quiet
      register: __podman_volumes
      tags:
        - volumes

    - name: Output __podman_volumes
      ansible.builtin.debug:
        msg: "{{ item }}"
      loop: "{{ __podman_volumes['stdout_lines'] }}"
      tags:
        - volumes

    - name: Export podman volumes
      ansible.builtin.command: >
        podman volume export {{ item }} --output {{ remote_backup_dir }}/{{ item }}_{{ ansible_facts['date_time']['date'] }}.tar
      loop: "{{ __podman_volumes['stdout_lines'] }}"

    - name: Compact {{ paperless_ngx_dir }}
      community.general.archive:
        path: "{{ paperless_ngx_dir }}"
        dest: "{{ remote_backup_dir }}/paperless-ngx_{{ ansible_facts['date_time']['date'] }}.tar.gz"
        format: gz

    - name: Start paperless-ngx containers
      ansible.builtin.command: >
        podman-compose -f {{ paperless_ngx_dir }}/{{ docker_compose_file }} start

    - name: Compress volume exports
      community.general.archive:
        path: "{{ remote_backup_dir }}/{{ item }}_{{ ansible_facts['date_time']['date'] }}.tar"
        format: gz
        remove: true
      loop: "{{ __podman_volumes['stdout_lines'] }}"
      tags:
        - compress

    - name: Sync backups to diskstation
      ansible.posix.synchronize:
        archive: true
        compress: false
        delete: false
        dest: "{{ diskstation_backup_dir }}"
        mode: pull
        private_key: /home/alice/.ssh/ansible_id_rsa
        src: "{{ remote_backup_dir }}/"
      delegate_to: localhost
      tags:
        - rsync

    - name: Sync backups from diskstation to contabo S3
      ansible.builtin.command: rclone sync -P ../backups/ secure:backups
      delegate_to: localhost
      tags:
        - rsync

Das Playbook wird einmal wöchentlich ausgeführt. Ob ich für die geplante Ausführung cron oder systemd timer units verwende, habe ich noch nicht entschieden. Ich tendiere aus Neugier zu letzterem.

Um ein Offsite-Backup zu haben, werden die Dateien von der Diskstation einmal wöchentlich verschlüsselt und in einen S3-Speicher synchronisiert. Ich nutze dafür das Programm rclone und S3-kompatiblen Speicher von Contabo. Die folgenden Links bieten weiterführende Informationen dazu:

Restore

Der Ablaufplan für die Wiederherstellung der Anwendung mit ihren Daten sieht wie folgt aus:

  1. Eine rootless-Podman-Umgebung bereitstellen
  2. podman-compose bereitstellen
  3. TAR-Archive auf Zielsystem übertragen
  4. Paperless-NGX mit Playbook installieren
  5. Alle Container stoppen
  6. Inhalt der TAR-Archive in die Podman-Volumes importieren (siehe podman-volume-import(1)): gunzip -c hello.tar.gz | podman volume import myvol -
  7. Alle Container starten

Fazit

Bereitstellung, Sicherung und Wiederherstellung funktionieren wie beschrieben. Damit kann ich nun beginnen und die Anwendung konfigurieren und mit meinem Papierkram füttern.

Die Samba-Freigabe habe ich ebenfalls getestet. Sie funktioniert wie erwartet. PDF-Dateien mit dem Befehl find Documents -type f -iname "*.pdf" -exec cp {} /consume \; hineinzukopieren ist übrigens besonders dann eine gute Idee, wenn man sehen möchte, welche Dateien so in den Tiefen des eigenen Dateisystems schlummern.

Gold-Images für KVM/QEMU erstellen

08. Mai 2023 um 05:00

Nachdem ich bereits beschrieben habe, wie ich Labor-Umgebungen mit Ansible in KVM erstelle, beschreibe ich in diesem Artikel, wie ich die dort verwendeten Gold-Images erstelle.

Ich erkläre kurz, was ein Gold-Image ist und wofür man es verwendet. Anschließend zeige ich, wie man mit dem Programm qemu-img eine Image-Datei auf der Kommandozeile erzeugt und diese im Installationsprozess für die Partitionierung und Erzeugung des LVM nutzt. Im Anschluss daran dokumentiere ich, welche Laufwerke und Dateisysteme ich für welchen Zweck erstelle und warum ich mich so entschieden habe. Der Text endet mit einer Sammlung von Quellen und weiterführenden Links zum Thema.

Der Text soll mir helfen, in Zukunft nachvollziehen zu können, warum ich mich so entschieden habe. Für euch mag er als Information dienen, wie ich im Unterschied zu euch an das Thema herangehe. Wer noch nie etwas von Gold-Images gehört hat, findet in diesem Text eine Erklärung und passende Quellen dazu.

Was ist ein Gold-Image?

Ein Gold-Image, auch Golden Image oder Baseline-Image genannt, bezeichnet eine Vorlage (engl. template) in virtuellen Umgebungen, woraus sich virtuelle Maschinen (VMs) klonen lassen (siehe [1-5]).

In ein Gold-Image werden all die Softwarekomponenten, Anwendungen und Konfigurationsoptionen aufgenommen, welche Bestandteil aller davon abgeleiteten VMs sein sollen. Klonen ermöglicht die schnelle Bereitstellung neuer Systeme. Dies ist besonders dann nützlich, wenn sich die VMs sehr ähnlich sind und man nur eine geringe Anzahl von Gold-Images pflegen muss.

Ich nutze Gold-Images, um für die von mir verwendeten Linux-Distributionen jeweils eine Installation manuell durchzuführen, welche die minimal erforderlichen Pakete enthält, um die abgeleiteten Klone mit Ansible fertig konfigurieren zu können. Wie ich dabei vorgehe, beschreibe ich in den folgenden Abschnitten.

Erstellung der Image-Datei

Im ersten Schritt erstelle ich Image-Dateien im qcow2-Format. Bei diesem Format handelt es sich um das heute gebräuchliche Format in KVM-/QEMU-Umgebungen. Zur Erstellung verwende ich das QEMU disk image utility qemu-img.

Die allgemeine Form des Befehls lautet (Details siehe Manpage qemu-img(1)):

qemu-img create -f FORMAT DATEINAME GRÖßE

Der folgende Befehl erstellt eine Image-Datei im qcow2-Format, mit 20 Gigabyte Größe und dem Dateinamen debian11-template.qcow2 im Pfad /var/lib/libvirt/images/:

$ qemu-img create -f qcow2 /var/lib/libvirt/images/debian11-template.qcow2 20G
Formatting '/var/lib/libvirt/images/debian11-template.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=21474836480 lazy_refcounts=off refcount_bits=16

Dabei werden die 20 GB nicht sofort alloziert. Zu Beginn belegt die Datei lediglich einige Kilobyte und kann je nach Nutzung auf die maximale Größe von 20 GB anwachsen. Diese Bereitstellungsform ist auch als Thin provisioning bekannt.

ls -sh /var/lib/libvirt/images/debian11-template.qcow2
193K /var/lib/libvirt/images/debian11-template.qcow2

Es lässt sich auf diese Weise mehr Speicherplatz provisionieren, als tatsächlich im System zur Verfügung steht. Dabei gilt jedoch zu beachten, dass sich die Physik nicht betrügen lässt. Man ist gut beraten, den realen Speicherverbrauch zu überwachen, um volllaufende Dateisysteme zu vermeiden.

Installation und Partitionierung

Bei der Installation des Gold-Images für Labor-Umgebungen mache ich es mir relativ einfach. Ich erstelle z.B. im virt-manager oder cockpit eine VM, die ich von einem Installations-ISO-Image der jeweiligen Distribution installiere.

Bei Debian installiere ich für gewöhnlich ein System ohne grafische Oberfläche, welches zusätzlich zur Basis-Installation lediglich die Paketgruppen SSH-Server und System-Werkzeuge umfasst. Bei Fedora oder RHEL führe ich die Minimal-Installation durch.

Ob bzw. welches Passwort für den Benutzer root vergeben wird, ist an dieser Stelle nicht wichtig, da dies beim Klonen in eine neue VM durch die Ansible-Rolle kvm_provision_lab geändert wird.

Der Installer erkennt eine Festplatte, die in diesem Text exemplarisch als /dev/vda bezeichnet wird. Diese wird nun wie folgt konfiguriert.

Vorwort zur Partitionierung

Das optimale Partitionslayout hängt vom konkreten Anwendungsfall ab und kann sich je nach Umgebung stark unterscheiden. Das von mir verwendete Layout passt aktuell am besten zu meinen Anforderungen. Es mag in Zukunft völlig anders aussehen.

Ich beschreibe, welche Partitionen ich erstelle und erläutere, warum ich mich zum Zeitpunkt der Erstellung dieses Textes dafür entschieden habe. Bitte übernehmt dieses Layout nicht stumpf, sondern überlegt, ob es zu euren Anforderungen passt.

Primäre Partition /dev/vda1 für /boot

In dieser Partition werden die Kernel und das initramfs abgelegt. Nach meiner Erfahrung reicht eine Größe von 1 GiB aus, um auch einige ältere Kernel vorzuhalten. Formatiert habe ich diese Partition mit dem Dateisystem ext4.

Ich bevorzuge ext4 gegenüber XFS, da es sich im Gegensatz zu letzterem auch verkleinern lässt. Zugegeben, dass dies notwendig ist, ist mir in 20 Jahren nur einmal untergekommen. Doch in diesem einen Moment war ich froh, dass es möglich war.

LVM, PV, VG, LV, Dateisysteme und Einhängepunkte

Der Logical Volume Manager (LVM) (siehe [11-13]) bietet die Möglichkeit, Partitionen (genaugenommen Logical Volumes) für weitere Einhängepunkte zu erstellen, welche sich später noch flexibel in der Größe anpassen lassen (Vergrößern und Verkleinern). Und dies, ohne die verwendeten Dateisysteme aushängen zu müssen.

Wer mit den für LVM relevanten Begriffen Physical Volume, Volume Group und Logical Volume nicht vertraut ist, findet weiterführende Hinweise in [12] für Debian bzw. [13] für RHEL. Ich werde die Erstellung hier nicht im Detail beschreiben.

Ich erstelle eine zweite primäre Partition /dev/vda2 mit Typ LVM, welcher ich die verbleibende Speicherkapazität von 19 GiB zuweise. Mein fertiges Partitionslayout sieht wie folgt aus:

lsblk -o +FSTYPE
NAME                  MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT FSTYPE
sr0                    11:0    1 1024M  0 rom             
vda                   254:0    0   20G  0 disk            
├─vda1                254:1    0  953M  0 part /boot      ext4
└─vda2                254:2    0 19.1G  0 part            LVM2_member
  ├─vg_system-root    253:0    0  9.3G  0 lvm  /          ext4
  ├─vg_system-var_log 253:1    0  4.7G  0 lvm  /var/log   ext4
  └─vg_system-home    253:2    0  1.9G  0 lvm  /home      ext4

Vorstehendem Code-Block ist zu entnehmen, dass ich drei Logical Volumes für die Einhängepunkte /, /var/log und /home verwende. Ich verwende auch hier durchgängig das ext4-Dateisystem.

Log-Dateien und unkontrolliert wachsende Daten in HOME-Verzeichnissen führen schnell dazu, dass das Root-Dateisystem (/) vollläuft. Dies lässt sich mit der Verwendung separater Einhängepunkte sicher verhindern.

Eurem aufmerksamen Auge ist sicher aufgefallen, dass ich keine Swap-Partition verwende. Da ich sie für die meist kurzlebigen Labor-VMs nicht benötige, lasse ich diese in der Regel weg. Für Systeme, die ich für langfristigen Betrieb installiere, füge ich diese nachträglich hinzu. Dank LVM ist dies kein Problem.

Darüber, ob man eine Swap-Partition braucht und wie groß diese sein sollte, werden teils esoterische Diskussionen geführt. Ich selbst orientiere mich an Table B.1. Recommended system swap space aus [14].

Damit habe ich ein Gold-Image erstellt, welches mir als Vorlage für weitere VMs dient und dabei nur wenig Platz auf der Festplatte des Hypervisor belegt:

ls -sh /var/lib/libvirt/images/debian11-template.qcow2
2.3G /var/lib/libvirt/images/debian11-template.qcow2

Sysprep

Sysprep ist ursprünglich ein Programm von Microsoft, mit welchem Gold-Images für die automatische Verteilung von Microsoft Windows vorbereitet werden. Heute taucht dieser Begriff in den Programmbezeichnungen weiterer Projekte auf und beschreibt gleichzeitig die Tätigkeit, ein Gold-Image für die weitere Verwendung vorzubereiten. Ich selbst verwende das Programm virt-sysprep von Richard W.M. Jones (Red Hat) und Wanglong Gao (Fujitsu Ltd.).

Virt-sysprep entfernt Einstellungen, User, Host-spezifische Dateien und leert Protokolldateien in dem erzeugten Image. Damit soll sichergestellt werden, dass die von dem Gold-Image abgeleiteten VMs keine Eigenschaften besitzen, die spezifisch für das Original sind, wie z.B. der Hostname, MAC-Adressen oder die SSH-Host-Keys, um nur drei Beispiele zu nennen. Die Anwendung ist daher dringend empfohlen.

Mit dem Befehl virt-sysprep --list-operations kann man sich die Aktionen anzeigen lassen, die virt-sysprep ausführen kann. Die Standard-Aktionen sind in der Ausgabe mit einem ‚*‘ markiert. Unter RHEL 9 sieht die Ausgabe wie folgt aus:

$ virt-sysprep --list-operations
abrt-data * Remove the crash data generated by ABRT
backup-files * Remove editor backup files from the guest
bash-history * Remove the bash history in the guest
blkid-tab * Remove blkid tab in the guest
ca-certificates   Remove CA certificates in the guest
crash-data * Remove the crash data generated by kexec-tools
cron-spool * Remove user at-jobs and cron-jobs
customize * Customize the guest
dhcp-client-state * Remove DHCP client leases
dhcp-server-state * Remove DHCP server leases
dovecot-data * Remove Dovecot (mail server) data
firewall-rules   Remove the firewall rules
flag-reconfiguration   Flag the system for reconfiguration
fs-uuids   Change filesystem UUIDs
ipa-client * Remove the IPA files
kerberos-data   Remove Kerberos data in the guest
kerberos-hostkeytab * Remove the Kerberos host keytab file in the guest
logfiles * Remove many log files from the guest
lvm-system-devices * Remove LVM2 system.devices file
lvm-uuids * Change LVM2 PV and VG UUIDs
machine-id * Remove the local machine ID
mail-spool * Remove email from the local mail spool directory
net-hostname * Remove HOSTNAME and DHCP_HOSTNAME in network interface configuration
net-hwaddr * Remove HWADDR (hard-coded MAC address) configuration
net-nmconn * Remove system-local NetworkManager connection profiles (keyfiles)
pacct-log * Remove the process accounting log files
package-manager-cache * Remove package manager cache
pam-data * Remove the PAM data in the guest
passwd-backups * Remove /etc/passwd- and similar backup files
puppet-data-log * Remove the data and log files of puppet
rh-subscription-manager * Remove the RH subscription manager files
rhn-systemid * Remove the RHN system ID
rpm-db * Remove host-specific RPM database files
samba-db-log * Remove the database and log files of Samba
script * Run arbitrary scripts against the guest
smolt-uuid * Remove the Smolt hardware UUID
ssh-hostkeys * Remove the SSH host keys in the guest
ssh-userdir * Remove ".ssh" directories in the guest
sssd-db-log * Remove the database and log files of sssd
tmp-files * Remove temporary files
udev-persistent-net * Remove udev persistent net rules
user-account   Remove the user accounts in the guest
utmp * Remove the utmp file
yum-uuid * Remove the yum UUID
customize * Customize the guest
dhcp-client-state * Remove DHCP client leases
dhcp-server-state * Remove DHCP server leases
dovecot-data * Remove Dovecot (mail server) data
firewall-rules   Remove the firewall rules
flag-reconfiguration   Flag the system for reconfiguration
fs-uuids   Change filesystem UUIDs
ipa-client * Remove the IPA files
kerberos-data   Remove Kerberos data in the guest
kerberos-hostkeytab * Remove the Kerberos host keytab file in the guest
logfiles * Remove many log files from the guest
lvm-system-devices * Remove LVM2 system.devices file
lvm-uuids * Change LVM2 PV and VG UUIDs
machine-id * Remove the local machine ID
mail-spool * Remove email from the local mail spool directory
net-hostname * Remove HOSTNAME and DHCP_HOSTNAME in network interface configuration
net-hwaddr * Remove HWADDR (hard-coded MAC address) configuration
net-nmconn * Remove system-local NetworkManager connection profiles (keyfiles)
pacct-log * Remove the process accounting log files
package-manager-cache * Remove package manager cache
pam-data * Remove the PAM data in the guest
passwd-backups * Remove /etc/passwd- and similar backup files
puppet-data-log * Remove the data and log files of puppet
rh-subscription-manager * Remove the RH subscription manager files
rhn-systemid * Remove the RHN system ID
rpm-db * Remove host-specific RPM database files
samba-db-log * Remove the database and log files of Samba
script * Run arbitrary scripts against the guest
smolt-uuid * Remove the Smolt hardware UUID
ssh-hostkeys * Remove the SSH host keys in the guest
ssh-userdir * Remove ".ssh" directories in the guest
sssd-db-log * Remove the database and log files of sssd
tmp-files * Remove temporary files
udev-persistent-net * Remove udev persistent net rules
user-account   Remove the user accounts in the guest
utmp * Remove the utmp file
yum-uuid * Remove the yum UUID

Selbstverständlich gibt es mit virt-sysprep(1) auch eine Manpage, welche die Nutzung des Programms und sämtliche Optionen erläutert.

Es ist sehr wichtig, dass die zu behandelnde Domain (VM) ausgeschaltet ist, bevor virt-sysprep gestartet wird, um eine Korruption der Image-Datei zu vermeiden.

Der nun folgende Code-Block zeigt die Anwendung von virt-sysprep auf die qcow2-Datei meines debian11-templates. Die dabei verwendeten Option --operations defaults,-ssh-userdir sorgt dafür, dass alle Standard-Operationen mit der Ausnahme durchgeführt werden, dass die .ssh-Verzeichnisse der User erhalten bleiben. Die Option --firstboot-command 'dpkg-reconfigure openssh-server' stellt sicher, dass beim ersten Start des Klons neue SSH-Hostkeys generiert werden. Andernfalls kann der SSH-Dienst nicht starten und ich wäre nicht in der Lage mich via SSH anzumelden. Anschließend ist das Image bereit, um geklont bzw. kopiert zu werden.

$ virt-sysprep -a /var/lib/libvirt/images/debian11-template.qcow2 --operations defaults,-ssh-userdir --firstboot-command 'dpkg-reconfigure openssh-server'
[   0.0] Examining the guest ...
[   2.0] Performing "abrt-data" ...
[   2.0] Performing "backup-files" ...
[   2.1] Performing "bash-history" ...
[   2.1] Performing "blkid-tab" ...
[   2.1] Performing "crash-data" ...
[   2.1] Performing "cron-spool" ...
[   2.1] Performing "dhcp-client-state" ...
[   2.1] Performing "dhcp-server-state" ...
[   2.1] Performing "dovecot-data" ...
[   2.1] Performing "ipa-client" ...
[   2.1] Performing "kerberos-hostkeytab" ...
[   2.2] Performing "logfiles" ...
[   2.2] Performing "lvm-system-devices" ...
[   2.2] Performing "machine-id" ...
[   2.2] Performing "mail-spool" ...
[   2.2] Performing "net-hostname" ...
[   2.2] Performing "net-hwaddr" ...
[   2.3] Performing "net-nmconn" ...
[   2.3] Performing "pacct-log" ...
[   2.3] Performing "package-manager-cache" ...
[   2.3] Performing "pam-data" ...
[   2.3] Performing "passwd-backups" ...
[   2.3] Performing "puppet-data-log" ...
[   2.3] Performing "rh-subscription-manager" ...
[   2.3] Performing "rhn-systemid" ...
[   2.4] Performing "rpm-db" ...
[   2.4] Performing "samba-db-log" ...
[   2.4] Performing "script" ...
[   2.4] Performing "smolt-uuid" ...
[   2.4] Performing "ssh-hostkeys" ...
[   2.4] Performing "sssd-db-log" ...
[   2.4] Performing "tmp-files" ...
[   2.4] Performing "udev-persistent-net" ...
[   2.4] Performing "utmp" ...
[   2.4] Performing "yum-uuid" ...
[   2.4] Performing "customize" ...
[   2.4] Setting a random seed
[   2.5] Setting the machine ID in /etc/machine-id
[   2.5] Installing firstboot command: dpkg-reconfigure openssh-server
[   2.5] SELinux relabelling
[   2.5] Performing "lvm-uuids" ...

Das Programm ist nicht auf qcow2-Images beschränkt. Einen weiteren Anwendungsfall habe ich bereits hier im Blog beschrieben: VMware ESXi: VMDK-Datei einer Gast-VM mit virt-sysprep bereinigen.

Verwendung der Gold-Images

Die Gold-Images werden verwendet, um durch Klonen neue VMs zu erstellen. Ich verwende dazu die Eingangs erwähnte Ansible-Rolle kvm_provision_lab.

Was tun, wenn der Platz knapp wird?

Wird im Laufe des Lebenszyklus einer VM mehr Speicherplatz benötigt, so lässt sich das Vorgehen wie folgt skizzieren:

  1. Neue virtuelle Festplatte mit ausreichend Speicherkapazität der VM hinzufügen.
  2. Eine Partition auf der neuen virtuellen Festplatte erstellen (optional).
  3. Mit pvcreate ein neues Physical Volume erstellen.
  4. Das Physical Volume mit vgextend der Volume Group hinzufügen.
  5. Das Logical Volume mit lvextend vergrößern.

Die Schritte 3-5 werden ausführlich in der RHEL-9-Dokumentation in Chapter 5. Modifying the size of a logical volume beschrieben. Dort wird auch beschrieben, wie ein Logical Volume verkleinert werden kann.

Falls ihr euch hierzu ein Tutorial wünscht, lasst es mich bitte in den Kommentaren wissen. Dann liefere ich ein entsprechendes Beispiel nach.

Quellen und weiterführende Links

  1. Was ist ein Golden Image? URL: https://www.redhat.com/de/topics/linux/what-is-a-golden-image.
  2. What is a golden image? On opensource.com by Seth Kenlon (Team, Red Hat). URL: https://opensource.com/article/19/7/what-golden-image.
  3. What is a golden image? Definition by Nick Martin on TechTarget. URL: https://www.techtarget.com/searchitoperations/definition/golden-image
  4. Definition Golden Image (auch Master Image oder Goldenes Abbild). ComputerWeekly.de. URL: https://www.computerweekly.com/de/definition/Golden-Image-auch-Master-Image-oder-Goldenes-Abbild
  5. Was ist ein Golden Image? 21.11.2018: Autor / Redakteur: Dipl. Betriebswirt Otto Geißler / Ulrike Ostler. URL: https://www.datacenter-insider.de/was-ist-ein-golden-image-a-775197/
  6. Wikipedia-Artikel zu qcow {EN}
  7. QEMU disk image utility
  8. Wikepdia-Artikel Thin zu provisioning {EN}
  9. Performing a standard RHEL 9 installation; Appendix B. Partitioning reference; URL: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/performing_a_standard_rhel_9_installation/partitioning-reference_installing-rhel#recommended-partitioning-scheme_partitioning-reference
  10. Debian: Empfohlene Partitionsschemata. URL: https://www.debian.org/releases/bullseye/amd64/apcs03.de.html
  11. Wikipedia-Artikel zu LVM
  12. LVM – Debian Wiki {EN}
  13. Configuring and managing logical volumes. Red Hat Enterprise Linux 9. A guide to the configuration and management of LVM logical volumes. {EN}
  14. Appendix B. Partitioning reference. Performing a standard RHEL 9 installation. {EN}
  15. VMware ESXi: VMDK-Datei einer Gast-VM mit virt-sysprep bereinigen

RHEL System Roles: sshd

13. März 2023 um 06:00

In Teil 4 meiner losen Reihe über die RHEL System Roles stelle ich die Ansible-Rolle sshd vor. Diese dient der Konfiguration des OpenSSH-Servers, einem der wichtigsten Dienste in Linux- und UNIX-Systemen.

Wer die ersten Teile dieser Reihe gelesen hat, ist inzwischen mit der grundsätzlichen Anwendung dieser Ansible-Rollen vertraut. Die Rolle sshd bildet hier keine Ausnahme. Wendet man die Rolle ohne weitere Konfiguration auf Ziel-Systeme an, konfiguriert sie den OpenSSH-Server entsprechend der Standard-Konfiguration des jeweiligen Betriebssystems. Es werden alle Optionen der sshd_config(5) unterstützt.

Ein Wort der Warnung: Mit dieser Rolle konfiguriert ihr den SSH-Dienst der Zielsysteme. Wenn dabei ein Fehler passiert, könnt ihr euch und euren Ansible-Controller aussperren und verliert ggf. den Zugriff auf die Systeme. Behaltet dies bitte im Hinterkopf und sorgt ggf. für alternative Zugänge, wie z.B. über eine lokale Konsole.

Bei der Konfiguration meiner Server ist mir persönlich wichtig, dass

  • der Benutzer root sich nur mittels SSH-Public-Key-Verfahren anmelden kann,
  • die Public-Key-Authentifizierung aktiviert ist,
  • die Passwort-Authentifizierung deaktiviert ist und
  • in der Datei .ssh/authorized_keys des jeweiligen Benutzers nach dem SSH-Public-Key gesucht wird.

Darüber hinaus möchte ich alle Git-bezogenen Umgebungsvariablen (GIT_*) nutzen. Die übrigen Einstellungen möchte ich auf den Standard-Werten des jeweiligen Betriebssystems belassen.

Im Folgenden beschreibe ich, wie sich diese mit der RHEL System Role sshd umsetzen lässt.

Voraussetzungen

Wie bei allen RHEL System Roles müssen auch hier die Pakete ansible-core und rhel-system-roles inkl. ihrer Abhängigkeiten auf dem Ansible-Controller installiert sein. Der Ansible-Controller muss die Ziel-Hosts über SSH erreichen können und über einen Benutzer mit sudo-Berechtigungen verfügen.

Das Playbook

Es werden bereits zwei Beispiel-Playbooks mitgeliefert, die sich im Pfad /usr/share/doc/rhel-system-roles/sshd/ befinden. Diese heißen:

  • example-accept-env-playbook.yml und
  • example-root-login-playbook.yml.

Aus diesen beiden Beispieldateien habe ich das folgende Playbook für meine Labor-Umgebung erstellt:

---
- hosts: all
  tasks:
  - name: Configure sshd to accept some useful environment variables
    include_role:
      name: rhel-system-roles.sshd
    vars:
      sshd:
        PermitRootLogin: without-password
        PasswordAuthentication: no
        PubkeyAuthentication: yes
        AuthorizedKeysFile: .ssh/authorized_keys
        # there are some handy environment variables to accept
        AcceptEnv:
          LANG
          LS_COLORS
          EDITOR
          GIT_*

Wie zu sehen ist, habe ich mich entschieden, noch ein paar weitere Umgebungsvariablen zu konfigurieren. Diese habe ich aus dem Beispiel example-accept-env-playbook.yml übernommen.

Testlauf in Labor-Umgebung

Auch dieses Playbook habe ich in meiner Labor-Umgebung, bestehend aus einem RHEL8-Ansible-Controller und jeweils einem rhel{7..9}-Client laufen lassen. Mit den Optionen -C -D ist die Ausgabe 707 Zeilen lang, weswegen der folgende Code-Block nur den Aufruf und das Ergebnis zeigt.

[root@ansible-ctrl ansible]# ansible-playbook sshd_config.yml -C -D

PLAY [all] ************************************************************************************************************
[...]
PLAY RECAP *******************************************************************************************************************************
ansible-pctrl              : ok=20   changed=2    unreachable=0    failed=0    skipped=13   rescued=0    ignored=0   
rhel7                      : ok=20   changed=2    unreachable=0    failed=0    skipped=13   rescued=0    ignored=0   
rhel8                      : ok=20   changed=2    unreachable=0    failed=0    skipped=13   rescued=0    ignored=0   
rhel9                      : ok=21   changed=2    unreachable=0    failed=0    skipped=12   rescued=0    ignored=0

Zusammenfassung

Die RHEL System Role sshd wurde kurz vorgestellt und genutzt, um meine bevorzugten Einstellungen für den OpenSSH-Dienst in meiner Labor-Umgebung zu konfigurieren. Alle Optionen in der sshd_config(5), welche ich nicht explizit über die Ansible-Rolle konfiguriert habe, werden auf die Standardwerte des Betriebssystems eingestellt. Es ist also ggf. Vorsicht geboten, wenn Systeme mit bestehender Konfiguration bearbeitet werden.

Selbstverständlich schützt ein einmaliger Playbook-Lauf nicht davor, dass ein Benutzer mit root-Berechtigungen lokale Änderungen an der Datei /etc/ssh/sshd_config vornimmt. Dies mag vorübergehend für Tests auch so gewollt sein. Damit die Konfiguration nicht dauerhaft vom SOLL-Zustand abweicht, kann man das Playbook regelmäßig durch cron(8) ausführen lassen, um evtl. Abweichungen zu korrigieren.

Quellen und weiterführende Links

  1. Red Hat Enterprise Linux (RHEL) System Roles {en}
  2. Ansible Documentation: Role Directory Structure {en}
  3. Red Hat Software and Download Center {en}
  4. Die Vorteile einer Red Hat Subskription
  5. RHEL System Roles: selinux
  6. RHEL System Roles: timesync
  7. RHEL System Roles: firewall

RHEL System Roles: timesync

20. Februar 2023 um 06:00

In diesem dritten Teil meiner Serie über RHEL System Roles nutze ich die Rolle timesync, um die NTP-Pool-Zone de.pool.ntp.org für meine Hosts zu konfigurieren.

Ich möchte mit diesem Artikel zeigen, wie einfach die Nutzung der RHEL System Roles ist, um eine Gruppe von RHEL-Servern zu konfigurieren. Dabei muss ich mich nicht um Details wie die Frage kümmern, ob auf meinen Zielhosts ntpd oder chronyd für die Zeitsynchronisierung genutzt wird. Diese Aufgabe löst die Ansible-Rolle für mich.

Bevor ich fortfahre, habe ich eine Warnung: Diese Rolle ersetzt die Konfiguration auf den Zielsystemen. Alle zuvor dort getroffenen Einstellungen werden verloren gehen.

Man muss sich also entscheiden, ob man die Zeitsynchronisation komplett über diese Rolle steuern möchte oder gar nicht.

Voraussetzungen

Auf dem Ansible-Controller müssen die Pakete ansible-core und rhel-system-roles installiert sein.

Das Playbook

Ich möchte mehrere NTP-Server konfigurieren. Für diesen Anwendungsfall liefert die Rolle timesync bereits ein Beispiel mit, welches ich mittels Copy-Paste-and-Modify in mein Playbook übernehme.

[root@ansible-ctrl ]# cp /usr/share/doc/rhel-system-roles/timesync/example-multiple-ntp-servers-playbook.yml ansible/use_de_ntp_servers.yml

Das Playbook sieht nach der Anpassung wie folgt aus:

- hosts: all
  vars:
    timesync_ntp_servers:
      - hostname: 0.de.pool.ntp.org
        iburst: yes
      - hostname: 1.de.pool.ntp.org
        iburst: yes
      - hostname: 2.de.pool.ntp.org
        iburst: yes
      - hostname: 3.de.pool.ntp.org
        iburst: yes
  roles:
    - rhel-system-roles.timesync

Testlauf in Labor-Umgebung

Um zu sehen, wie die Datei /etc/chrony.conf vor und nach dem Playbook-Lauf aussieht, lasse ich das Playbook zuerst mit den Optionen -C (aktiviert Check-Mode) und -D (zeigt die Änderungen an) laufen. So kann ich vorab prüfen, welche Änderungen vorgenommen werden, bevor es ernst wird. Die Ausgabe ist über 500 Zeilen lang. Ich habe sie auf Gist gepostet und hier eingebunden. Wer sich für die Ausgabe nicht interessiert, kann direkt zur Zusammenfassung springen.

Anschließend habe ich das Playbook ohne die Optionen -C und -D ausgeführt und meine Hosts wie gewünscht konfiguriert.

Zusammenfassung

Mit der RHEL System Role timesync kann die Zeitsynchronisation verschiedener RHEL-Releases schnell und einfach konfiguriert werden, ohne Kenntnis über die konkrete Implementierung auf den Zielsystemen zu besitzen.

Gleichzeitig kann ein Blick in die Struktur der Rolle und den Inhalt der dazugehörigen Dateien Aufschluss darüber geben, wie Ansible-Rollen für mehrere RHEL-Major-Releases erstellt werden können. Man kann dies für die Erstellung eigener Rollen mit ein wenig Transferleistung wiederverwenden.

Weiterführende Quellen und Links

  1. Red Hat Enterprise Linux (RHEL) System Roles {en}
  2. Ansible Documentation: Role Directory Structure {en}
  3. Red Hat Software and Download Center {en}
  4. Die Vorteile einer Red Hat Subskription
  5. RHEL System Roles: selinux
  6. RHEL System Roles: sshd
  7. RHEL System Roles: firewall

Vorfreude auf die Chemnitzer Linux-Tage 2023

13. Februar 2023 um 06:00

Im März ist es endlich wieder soweit. Die Chemnitzer Linux-Tage laden am 11. und 12. März in das Hörsaal- und Seminar-Gebäude der Technischen Universität Chemnitz ein.

Nach den Online-Konferenzen der letzten Jahre, mit denen ich nicht wirklich warm geworden bin, freue ich mich sehr darauf, Open Source begeisterte Menschen wieder vor Ort treffen zu können.

Das Programm bietet dieses Jahr 90 Vorträge in sechs parallelen Tracks, neun Workshops und ein spezielles Junior-Programm.

Ich selbst bin dieses Jahr mit zwei Vorträgen am Sonntag vertreten. Dirk, Sujeevan und ich werden euch gemeinsam bewusst machen „Warum man nicht in der IT arbeiten sollte und warum wir es trotzdem tun.“ In meinem Vortrag „Einstieg in die Automatisierung mit Ansible“ geht es darum, dass Konzepte wie Automatisierung und Konfigurationsmanagement nicht nur in die Werkzeugkästen für Hyperscaler gehören, sondern wie sie jedem Sysadmin die tägliche Arbeit erleichtern und der gesamten Organisation von Nutzen sein können.

Als passionierter Autofahrer setze ich dieses Jahr mein Vertrauen in die Bahn, welche mich am Freitag nach Chemnitz und am Sonntag wieder heim bringen soll. Ihr werdet in meinem Konferenzbericht lesen, wie mir diese Erfahrung gefallen haben wird.

So alles klappt, sehen wir uns in Karl-Marx-Stadt.

Wird 2023 das Jahr der E-Mail-Verschlüsselung?

18. Januar 2023 um 07:34

Ich entschuldige mich direkt für den reißerischen Titel. Ich persönlich glaube nicht, dass sich in dieser Hinsicht 2023 viel verändern wird.

Ich möchte an dieser Stelle lediglich darauf hinweisen, dass ihr meinen aktuellen GnuPG-Public-Key an dieser Stelle zum Download und per Web Key Directory findet.

Meine privaten Arbeitsmittel 2023

16. Januar 2023 um 06:00

Dies ist ein Update des Artikels aus dem letzten Jahr.

Smartphone

Mein Sony Xperia XZ2 Compact musste aufgrund mehrerer Macken ersetzt werden. Mein neuer Begleiter ist nun ein Samsung Galaxy S22. Zwar habe ich mir auch ein Fairphone angesehen, doch ist mir dieses einfach viel zu groß. Nutzungsänderungen ergaben sich lediglich bei den Messenger-Diensten und den sozialen Netzwerken:

  • Für Chat und Kurznachrichten mit Matrix über Element (dienstlich)/neu: FluffyChat (privat), SMS und Threema (bevorzugt).
  • Nutzung diverser sozialer Netzwerkwerke wie Facebook, LinkedIn, Mastodon, Twitter und XING; meine Accounts in den gestrichenen Netzwerken habe ich gelöscht.

Tablet

Hier hat sich gegenüber dem Vorjahr nichts verändert.

Laptop

Hier gab es lediglich ein Upgrade auf Fedora 37 und Rambox ist hamsket gewichen.

Desktop-/Server-PC

Auch hier gibt es keine Änderungen gegenüber dem Vorjahr.

Sonstige Geräte im Netzwerk

Unverwüstlich verrichtet mein Brother DCP-540CN weiterhin zuverlässig seinen Dienst. Meine FHEM-Installation hingegen habe ich eingestampft und meinen Pi-Hole auf den Raspberry Pi 1 Rev. B migriert. Damit habe ich wieder einen Pi für neue Basteleien frei.

Zusammenfassung

Viel hat sich hier nicht verändert und ich bin mit dem aktuellen Setup zufrieden. Ob es im Jahr 2023 etwas mehr Veränderungen geben wird, wird sich zeigen.

IPFire oder nicht?

09. Januar 2023 um 06:00

Hallo liebe Leserinnen und Leser,

in diesem Beitrag möchte ich um eure Meinungen und Gedanken zur Distribution IPFire 2.x und einer dafür erhältlichen Hardware-Appliance bitten.

IST-Zustand

Vereinfachte Struktur des betrachteten Netzwerks

Es existiert ein einfaches Heimnetzwerk, welches über eine Vodafone ConnectBox mit dem Internet verbunden ist. Die Firewall der ConnectBox ist aktiviert und es sind aktuell keinerlei eingehende Verbindungen zugelassen.

Im LAN existieren eine Vielzahl unterschiedlicher Geräte, wie z.B. Access-Points, Pi-Hole, PCs, Laptops, PV-Anlage, Netzwerkdrucker, etc. pp.

SOLL-Zustand

Das bestehende Heimnetzwerk soll in verschiedene Netzwerkzonen unterteilt werden können, welche durch eine Firewall voneinander getrennt sind. Es soll eine Möglichkeit zur VPN-Einwahl geschaffen werden, um von außerhalb des Netzwerks auf Dienste im Heimnetzwerk zugreifen zu können. Der vorhandene Kabelrouter soll nicht ersetzt werden.

Vereinfachte Netzwerkstruktur mit IPFire

Bei der Internet-Recherche bin ich auf IPFire gestoßen, für welche ich als ehemaliger IPCop-Nutzer eine gewisse Sympathie hege. Zudem habe ich mit der IPFire Mini Appliance (EU) ein Gerät im Blick, welches am Aufstellungsort eine gute Figur machen sollte. Mir ist dabei wichtig, dass das Gerät möglichst sparsam bei der Energieaufnahme ist und passiv gekühlt wird, damit im Betrieb keine Geräusche verursacht werden.

Ich möchte die IPFire als Paketfilter, OpenVPN-Gateway und ggf. IPS nutzen.

Ihr seid gefragt

Bevor ich nun ca. 450 Euro investiere, möchte ich die Chance nutzen und nach euren Erfahrungen mit IPFire und den verfügbaren Appliances fragen.

Habt ihr IPFire genutzt oder nutzt sie noch? Seid ihr damit zufrieden, oder würdet ihr zu einer Alternative raten? Wenn Alternative, welche und warum?

Worauf betreibt ihr IPFire? Auf einer Appliance wie der oben verlinkten, einem Raspberry Pi, in einer VM oder auf etwas ganz anderem? Lasst es mich gerne wissen, warum ihr euch für welche Lösung entschieden habt.

Falls ihr jetzt die Hände über dem Kopf zusammenschlagt und ruft: „Nein alles, nur das nicht!“ Dann bin ich natürlich umso mehr an eurer Erfahrung interessiert.

Bitte nutzt die Kommentare oder schreibt mir an „ipfire (aett) my-it-brain (Punkt) de“, wenn ihr eure Gedanken mit mir teilen möchtet.

Quellen und weiterführende Links

❌
❌