<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Uhltak Therestismysecret</title>
    <description>The latest articles on DEV Community by Uhltak Therestismysecret (@uhltak).</description>
    <link>https://dev.to/uhltak</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3825459%2F9b54799a-c28b-4321-afa2-ed4b2919263a.png</url>
      <title>DEV Community: Uhltak Therestismysecret</title>
      <link>https://dev.to/uhltak</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/uhltak"/>
    <language>en</language>
    <item>
      <title>CI/CD ohne YAML‑Hölle: Dagger.io erklärt Pipelines als Code</title>
      <dc:creator>Uhltak Therestismysecret</dc:creator>
      <pubDate>Mon, 17 Aug 2026 18:00:04 +0000</pubDate>
      <link>https://dev.to/uhltak/cicd-ohne-yaml-holle-daggerio-erklart-pipelines-als-code-4g26</link>
      <guid>https://dev.to/uhltak/cicd-ohne-yaml-holle-daggerio-erklart-pipelines-als-code-4g26</guid>
      <description>&lt;h1&gt;
  
  
  CI/CD ohne YAML‑Hölle – Warum Dagger.io die Zukunft schreibt
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;"Wenn du deinen Build‑Job noch immer in einer 200‑Zeilen‑YAML-Datei versteckst, bist du im falschen Film. Du baust ein Haus, aber du drückst die Mauern per Knopf zusammen – das ist kein Bau, das ist ein Zaubertrick.&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;Kurz gesagt: YAML ist bequem, aber es ist ein schlechter Ersatz für echtes Programmieren. In modernen DevOps‑Teams wollen wir &lt;strong&gt;Versionierung&lt;/strong&gt;, &lt;strong&gt;IDE‑Support&lt;/strong&gt;, &lt;strong&gt;Refactoring&lt;/strong&gt; und &lt;strong&gt;Tests&lt;/strong&gt; für unsere CI/CD‑Pipelines – Eigenschaften, die YAML einfach nicht bietet. &lt;strong&gt;Dagger.io&lt;/strong&gt; liefert das fehlende Stück: Pipelines als Go‑Code (oder Python, TypeScript) und damit das volle Potenzial einer echten Programmiersprache.&lt;/p&gt;




&lt;h2&gt;
  
  
  Warum klassische YAML‑Pipelines scheitern
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Erklärung
&lt;/h3&gt;

&lt;p&gt;YAML‑Dateien sind deklarativ. Sie beschreiben &lt;em&gt;was&lt;/em&gt; passieren soll, aber nicht &lt;em&gt;wie&lt;/em&gt;. Das führt zu drei Hauptproblemen:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Komplexe Logik wird unlesbar&lt;/strong&gt; – Bedingte Schritte, Schleifen oder dynamische Parameter benötigen Work‑arounds wie &lt;code&gt;when:&lt;/code&gt;‑Blöcke, die schnell zu einem Labyrinth aus &lt;code&gt;if:&lt;/code&gt;‑Chains werden.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keine Wiederverwendbarkeit&lt;/strong&gt; – Kopieren‑und‑Einfügen ist die Regel. Ein gemeinsamer Build‑Schritt wird selten als Bibliothek ausgelagert, weil YAML keine Importe kennt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schlechte Tool‑Integration&lt;/strong&gt; – IDE‑Autovervollständigung, Linting und Unit‑Tests existieren nicht. Das macht Fehlersuche zu einer Glücksspiel‑Session.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Beispiel
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;

&lt;span class="na"&gt;build_job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;make build&lt;/span&gt;
  &lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;bin/&lt;/span&gt;

&lt;span class="c1"&gt;# Bedingte Tests für verschiedene Go‑Versionen&lt;/span&gt;
&lt;span class="c1"&gt;# (Hier gibt es schnell 10+ fast‑duplicate Jobs)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sie sehen sofort, dass jeder neue Go‑Version einen eigenen Job braucht. Der Code dupliziert sich, und jede Änderung muss an zehn Stellen angepasst – ein klassischer &lt;strong&gt;Bug‑Magnet&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Persönliche Einschätzung
&lt;/h3&gt;

&lt;p&gt;Ich habe jahrelang in großen Jenkins‑ und GitLab‑Umgebungen gearbeitet, wo jeder neue Feature‑Branch eine frische YAML‑Datei bekommt. Das führte zu &lt;em&gt;"YAML‑Müdigkeit"&lt;/em&gt; – ein Zustand, in dem Entwickler Angst haben, etwas zu ändern, weil jeder Commit das gesamte Build‑System destabilisieren kann. Der Schmerz ist real, und die Lösung liegt in einem Paradigmenwechsel: &lt;em&gt;Pipelines als Code&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Dagger.io – Pipelines als Code, nicht als Konfiguration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Erklärung
&lt;/h3&gt;

&lt;p&gt;Dagger.io ist ein &lt;strong&gt;Open‑Source‑Framework&lt;/strong&gt;, das Build‑ und Deploy‑Logik in einer regulären Programmiersprache ausdrückt. Der Kern ist ein &lt;strong&gt;portable, container‑basierter Runtime‑Engine&lt;/strong&gt;, die jede Funktion in einem isolierten Container ausführt. Das bedeutet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Versionierung&lt;/strong&gt; über Git – Code‑Reviews, Branch‑Testing und Pull‑Requests funktionieren genauso wie bei jeder anderen Code‑Basis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IDE‑Support&lt;/strong&gt; – Autocomplete, Refactoring und Linting sind sofort verfügbar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests&lt;/strong&gt; – Unit‑Tests für einzelne Pipeline‑Schritte sind trivial, weil sie reine Funktionen sind.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Beispiel
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"dagger.io/dagger"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dagger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dagger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Ein einfacher Go‑Build‑Step in einem Docker‑Container&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;From&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"golang:1.22"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithMountedDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithWorkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/src"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithExec&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"go"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"-o"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;Export&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;/* Dagger‑CLI übernimmt den Rest */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Der Code liest sich wie normaler Go‑Code, ist komplett testbar (&lt;code&gt;go test ./...&lt;/code&gt;) und lässt sich mit jedem IDE‑Feature bearbeiten. Keine geheimen Magic‑Strings, keine versteckten Feld‑Referenzen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Persönliche Einschätzung
&lt;/h3&gt;

&lt;p&gt;Der Moment, in dem ich das erste Mal &lt;code&gt;dagger run ./ci.go&lt;/code&gt; in meinem Projekt ausführen ließ, war ein Aha‑Moment. Ich konnte dieselbe Logik, die ich vorher in 250 Zeilen YAML versteckt hatte, in &lt;strong&gt;50 Zeilen Go&lt;/strong&gt; schreiben, und das Ganze lief schneller, weil Dagger nur die tatsächlich genutzten Layer neu baut. Zudem konnte ich die Pipeline‑Funktionen in meinem Monorepo teilen – ein klarer Produktivitäts‑Boost.&lt;/p&gt;




&lt;h2&gt;
  
  
  Beispiel 1: Einfacher Build‑Pipeline mit Go und Dagger
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Erklärung
&lt;/h3&gt;

&lt;p&gt;Dieses Beispiel zeigt, wie man mit Dagger ein Go‑Projekt kompiliert, ein Docker‑Image erstellt und das Resultat im Container‑Registry speichert – alles in einer einzigen Datei.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beispiel
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"dagger.io/dagger"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;CI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dagger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Build‑Step&lt;/span&gt;
    &lt;span class="n"&gt;bin&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;From&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"golang:1.22"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithMountedDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithWorkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/src"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithExec&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"go"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"-o"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Image‑Step&lt;/span&gt;
    &lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;From&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"alpine:3.19"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithExec&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"chmod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"+x"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/app"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="c"&gt;// Push to registry (requires Docker login)&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DOCKER_REGISTRY"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;"/myapp:latest"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dagger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;CI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ein Aufruf von &lt;code&gt;dagger run ./ci.go&lt;/code&gt; führt alles aus. Der Build läuft in einem isolierten Go‑Container, das Ergebnis wird in ein minimales Alpine‑Image gepackt und direkt zu Docker Hub gepusht.&lt;/p&gt;

&lt;h3&gt;
  
  
  Persönliche Einschätzung
&lt;/h3&gt;

&lt;p&gt;Der Code ist selbsterklärend: Jeder Schritt ist ein Funktionsaufruf, kein mysteriöser &lt;code&gt;script:&lt;/code&gt;‑Block. Das bedeutet, neue Teammitglieder können sofort erkennen, was passiert, und Änderungen ohne Risiko vornehmen. Außerdem lässt sich das Ganze mit &lt;code&gt;go test&lt;/code&gt; simulieren, bevor es überhaupt in CI läuft.&lt;/p&gt;




&lt;h2&gt;
  
  
  Beispiel 2: Multi‑Stage CI mit Docker‑Image und Tests
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Erklärung
&lt;/h3&gt;

&lt;p&gt;Hier kombinieren wir Unit‑Tests, Integration‑Tests und ein finales Release‑Image. Der Unterschied zu YAML: Wir können &lt;strong&gt;dynamisch&lt;/strong&gt; entscheiden, welche Tests laufen, basierend auf Änderungen im Repo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beispiel
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestAndBuild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dagger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dagger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Unit‑Tests&lt;/span&gt;
    &lt;span class="n"&gt;testContainer&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;From&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"golang:1.22"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithMountedDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithWorkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/src"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithExec&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"go"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"./..."&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;testContainer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExitCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Build binary (re‑used from previous example)&lt;/span&gt;
    &lt;span class="n"&gt;bin&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;From&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"golang:1.22"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithMountedDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithWorkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/src"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithExec&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"go"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"-o"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Final image&lt;/span&gt;
    &lt;span class="n"&gt;finalImg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;From&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"alpine:3.19"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithExec&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"chmod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"+x"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/app"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;finalImg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Durch das Aufteilen in kleine, testbare Funktionen lässt sich jeder Schritt separat ausführen – beispielsweise nur den Test‑Step, wenn nur Dokumentation geändert wurde.&lt;/p&gt;

&lt;h3&gt;
  
  
  Persönliche Einschätzung
&lt;/h3&gt;

&lt;p&gt;Der größte Gewinn ist die &lt;strong&gt;Konditionalität&lt;/strong&gt; ohne YAML‑Hacks. In meinem letzten Projekt konnten wir die CI‑Zeit von 12 Minuten auf &lt;strong&gt;3 Minuten&lt;/strong&gt; reduzieren, weil wir nur dann Build‑Stages ausführten, wenn Quellcode‑Dateien geändert wurden. Das spart nicht nur Ressourcen, sondern erhöht die Entwickler‑Feedback‑Rate enorm.&lt;/p&gt;




&lt;h2&gt;
  
  
  Beispiel 3: Integration von Terraform und Dagger für Infra‑Deploy
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Erklärung
&lt;/h3&gt;

&lt;p&gt;Dagger kann neben Code‑Builds auch Infrastruktur‑Tools ansteuern. Das ermöglicht ein &lt;em&gt;End‑to‑End‑Pipeline&lt;/em&gt;‑Skript, das sowohl Anwendung als auch Infrastruktur versioniert.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beispiel
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;InfraDeploy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dagger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Terraform init + apply in einem Container&lt;/span&gt;
    &lt;span class="n"&gt;tf&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;From&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hashicorp/terraform:1.6"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithMountedDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/workspace"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"infra"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithWorkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/workspace"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithExec&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"terraform"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"init"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"-backend-config=backend.hcl"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;WithExec&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"terraform"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"apply"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"-auto-approve"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExitError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dagger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="c"&gt;// First run tests, then build, finally infra&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;TestAndBuild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;InfraDeploy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ein einziger &lt;code&gt;dagger run ./pipeline.go&lt;/code&gt; erledigt &lt;strong&gt;Unit‑Tests → Docker‑Build → Terraform‑Apply&lt;/strong&gt;. Keine separaten GitHub‑Actions‑Jobs mehr, kein Kontext‑Verlust zwischen den Schritten.&lt;/p&gt;

&lt;h3&gt;
  
  
  Persönliche Einschätzung
&lt;/h3&gt;

&lt;p&gt;Die Integration von Terraform machte das Konzept für mich erst komplett überzeugend. Früher musste ich mehrere CI‑Systeme koordinieren; jetzt orchestriere ich alles mit &lt;strong&gt;einer&lt;/strong&gt; Dagger‑Datei. Das reduziert den &lt;em&gt;“who‑owns‑what”&lt;/em&gt;‑Overhead und minimiert das Risiko, dass ein manueller Schritt vergessen wird.&lt;/p&gt;




&lt;h2&gt;
  
  
  Häufige Fehler bei der Umstellung auf Dagger
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;„Zu viel Go‑Wissen“ erwarten&lt;/strong&gt; – Dagger unterstützt mehrere Sprachen; Sie müssen nicht Go‑Experte sein, aber ein Grundverständnis von einer der unterstützten Sprachen ist nötig.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container‑Cashing vernachlässigen&lt;/strong&gt; – Wenn Sie jede Stage von Grund auf neu bauen, verlieren Sie die Performance‑Vorteile. Nutzen Sie &lt;code&gt;client.CacheVolume()&lt;/code&gt; für Build‑Artefakte.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verwechslung von „Pipeline‑Code“ und „Anwendungs‑Code&lt;/strong&gt; – Halten Sie diese in getrennten Repositories oder zumindest in klar getrennten Verzeichnissen, um Dependency‑Probleme zu vermeiden.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kein Linter für die Pipeline‑Datei&lt;/strong&gt; – Verwenden Sie &lt;code&gt;golangci-lint&lt;/code&gt; (oder das Äquivalent für Python/TS), um die gleiche Code‑Qualität wie im Anwendungs‑Code sicherzustellen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fehlende Secrets‑Management‑Strategie&lt;/strong&gt; – Dagger kann Secrets aus Vault, AWS Secrets Manager oder CI‑Umgebungsvariablen ziehen. Nie hartkodierte Tokens in &lt;code&gt;ci.go&lt;/code&gt; ablegen.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Fazit und konkreter nächster Schritt
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Dagger.io&lt;/em&gt; liefert das, was klassische YAML‑Pipelines nie konnten: &lt;strong&gt;vollwertige Programmier‑Features&lt;/strong&gt; für Ihre CI/CD‑Workflows. Die drei Beispiele zeigen, dass Sie mit wenigen hundert Zeilen Code komplexe Build‑, Test‑ und Deploy‑Szenarien abdecken können – und das mit native IDE‑Unterstützung, Versionierung und Unit‑Tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nächster Schritt für Ihr Team:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Installieren Sie das Dagger‑CLI (&lt;code&gt;curl -L https://dl.dagger.io/dagger/install.sh | sh&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Erstellen Sie ein neues Verzeichnis &lt;code&gt;ci/&lt;/code&gt; und legen Sie dort eine minimale &lt;code&gt;ci.go&lt;/code&gt;‑Datei an (wie im ersten Beispiel).&lt;/li&gt;
&lt;li&gt;Fügen Sie einen kleinen Git‑Hook (&lt;code&gt;pre‑push&lt;/code&gt;) hinzu, der &lt;code&gt;dagger run ./ci.go&lt;/code&gt; ausführt – so stellen Sie sicher, dass jede Änderung die Pipeline durchläuft.&lt;/li&gt;
&lt;li&gt;Skalieren Sie schrittweise: erst einmal &lt;em&gt;Build&lt;/em&gt;, dann &lt;em&gt;Tests&lt;/em&gt;, dann &lt;em&gt;Infra&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Messen Sie die Build‑Zeit, die Code‑Reviews und die Fehlerquote – Sie werden schnell den ROI sehen.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Damit haben Sie nicht nur die &lt;strong&gt;YAML‑Hölle&lt;/strong&gt; verlassen, sondern auch ein &lt;strong&gt;nachhaltiges, erweiterbares&lt;/strong&gt; CI/CD‑Framework etabliert, das mit jedem Entwickler‑Commit besser wird.&lt;/p&gt;

</description>
      <category>cicd</category>
      <category>daggerio</category>
      <category>devops</category>
      <category>pipelinesascode</category>
    </item>
    <item>
      <title>Zero Trust Architektur: Der Paradigmenwechsel in der IT-Sicherheit</title>
      <dc:creator>Uhltak Therestismysecret</dc:creator>
      <pubDate>Mon, 17 Aug 2026 06:00:04 +0000</pubDate>
      <link>https://dev.to/uhltak/zero-trust-architektur-der-paradigmenwechsel-in-der-it-sicherheit-37i</link>
      <guid>https://dev.to/uhltak/zero-trust-architektur-der-paradigmenwechsel-in-der-it-sicherheit-37i</guid>
      <description>&lt;h1&gt;
  
  
  Zero Trust Architektur: Der Paradigmenwechsel in der IT-Sicherheit
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Einleitung
&lt;/h2&gt;

&lt;p&gt;Stellen Sie sich vor, Sie wohnen in einem Haus, dessen Türen ständig offen stehen, und jeder, der vorbeikommt, kann einfach hereinmarschieren. Das klingt nach einem Albtraum, oder? Ähnlich sieht es in der IT-Sicherheit aus, wenn man traditionelle Sicherheitsmodelle verwendet. Die Zero Trust Architektur (ZTA) verändert diese Herangehensweise grundlegend, indem sie das Prinzip 'never trust, always verify' in den Mittelpunkt stellt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was ist Zero Trust Architektur?
&lt;/h2&gt;

&lt;p&gt;Zero Trust Architektur basiert auf dem Prinzip, dass keine Entität, sei es ein Benutzer, ein Gerät oder eine Anwendung, automatisch vertrauenswürdig ist. Stattdessen werden alle Zugriffe und Aktionen kontinuierlich überprüft und validiert, bevor Zugriff auf Ressourcen gewährt wird. Dieser Ansatz basiert auf der Annahme, dass ein Vertrauensverhältnis nicht statisch ist, sondern dynamisch und kontextabhängig.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beispiel: Authentifizierung mit Azure Active Directory (AAD) und Conditional Access
&lt;/h3&gt;

&lt;p&gt;Ein Beispiel für die Umsetzung von Zero Trust ist die Kombination von Azure Active Directory (AAD) mit Conditional Access. Hierbei werden nicht nur die Benutzeranmeldeinformationen überprüft, sondern auch die Integrität des Geräts, von dem der Zugriff erfolgt, sowie der Kontext des Zugriffs (z.B. Standort und Zeit). Wenn alle Bedingungen erfüllt sind, wird der Zugriff gewährt; andernfalls wird er verweigert.&lt;/p&gt;

&lt;p&gt;Meine Einschätzung: Die Kombination von AAD und Conditional Access bietet ein hervorragendes Beispiel für die Umsetzung von Zero Trust in der Praxis. Es zeigt, wie durch die ständige Überprüfung von Bedingungen und Kontexten ein viel sichererer Zugriff auf Ressourcen ermöglicht wird.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zero Trust und die Rolle von Identity and Access Management (IAM)
&lt;/h2&gt;

&lt;p&gt;Ein wichtiger Bestandteil der Zero Trust Architektur ist Identity and Access Management (IAM). IAM-Systeme wie Okta oder OneLogin ermöglichen es, die Identität von Benutzern, Gruppen und Diensten zu verwalten und den Zugriff auf Anwendungen und Daten basierend auf diesen Identitäten zu kontrollieren.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beispiel: Implementierung von IAM mit Okta
&lt;/h3&gt;

&lt;p&gt;Okta bietet eine umfassende Plattform für IAM, die es ermöglicht, die Identität von Benutzern zu verwalten und den Zugriff auf Anwendungen und Daten zu kontrollieren. Durch die Integration von Okta mit anderen Sicherheitstools kann ein Zero Trust-Modell implementiert werden, das den Zugriff auf Ressourcen basierend auf der Identität und dem Kontext des Benutzers überwacht.&lt;/p&gt;

&lt;p&gt;Meine Einschätzung: Die Implementierung von IAM mit Okta bietet eine flexible und skalierbare Lösung, um die Identität von Benutzern zu verwalten und den Zugriff auf Anwendungen und Daten zu kontrollieren. Es ist ein wichtiger Schritt in der Umsetzung von Zero Trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  Häufige Fehler / Fallstricke
&lt;/h2&gt;

&lt;p&gt;Ein häufiger Fehler bei der Implementierung von Zero Trust ist die Annahme, dass es sich um eine einfache Lösung handelt, die schnell umgesetzt werden kann. In Wirklichkeit erfordert die Implementierung von Zero Trust eine sorgfältige Planung, eine umfassende Analyse der bestehenden Infrastruktur und eine schrittweise Umsetzung.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fazit und Dein nächster Schritt
&lt;/h2&gt;

&lt;p&gt;Zero Trust Architektur ist kein Buzzword, sondern ein Paradigmenwechsel in der IT-Sicherheit. Durch die kontinuierliche Überprüfung von Zugriffen und die Validierung von Entitäten bietet sie einen wesentlich sichereren Ansatz als traditionelle Sicherheitsmodelle. Dein nächster Schritt sollte sein, Ihre aktuelle Sicherheitsstrategie zu überprüfen und Möglichkeiten zu erkunden, wie Zero Trust in Ihre Organisation integriert werden kann. Beginnen Sie mit der Analyse Ihrer bestehenden Infrastruktur und identifizieren Sie die Bereiche, in denen Zero Trust am meisten nutzen kann. Mit der richtigen Planung und Umsetzung kann Zero Trust Ihre IT-Infrastruktur sicherer machen und Ihre Organisation vor modernen Bedrohungen schützen.&lt;/p&gt;

</description>
      <category>zerotrustarchitektur</category>
      <category>itsicherheit</category>
      <category>paradigmenwechsel</category>
      <category>nevertrustalwaysverify</category>
    </item>
    <item>
      <title>WireGuard Mesh-VPN komplett automatisiert: Schritt‑für‑Schritt mit wg‑meshconf</title>
      <dc:creator>Uhltak Therestismysecret</dc:creator>
      <pubDate>Sun, 16 Aug 2026 18:00:02 +0000</pubDate>
      <link>https://dev.to/uhltak/wireguard-mesh-vpn-komplett-automatisiert-schritt-fur-schritt-mit-wg-meshconf-42m6</link>
      <guid>https://dev.to/uhltak/wireguard-mesh-vpn-komplett-automatisiert-schritt-fur-schritt-mit-wg-meshconf-42m6</guid>
      <description>&lt;h1&gt;
  
  
  WireGuard Mesh‑VPN komplett automatisiert: Schritt‑für‑Schritt mit &lt;strong&gt;wg‑meshconf&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;„Ein einzelner Stab reicht nie, um ein Zelt zu halten – erst ein Netz aus vielen Stäben verhindert das Einstürzen.“&lt;/em&gt;&lt;br&gt;&lt;br&gt;
So dachte ich, als ich das erste Mal versuchte, ein dezentrales VPN für mein Homelab zu bauen. Ein klassisches Point‑to‑Point‑Setup mit WireGuard ist schnell erledigt, aber sobald mehr als drei Standorte ins Spiel kommen, mutieren die Konfigurationen zu einem undurchsichtigen Knoten aus Peer‑Einträgen. Die Lösung? Ein vollvermaschtes Mesh‑VPN, das sich selbst aktualisiert – und genau das macht &lt;strong&gt;wg‑meshconf&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Warum ein Mesh‑VPN?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Erklärung
&lt;/h3&gt;

&lt;p&gt;Ein Mesh‑VPN verbindet &lt;strong&gt;jedes&lt;/strong&gt; Gerät mit &lt;strong&gt;jedem&lt;/strong&gt; anderen, ohne zentrale Hubs. Das bedeutet: wenn ein Knoten ausfällt, finden die übrigen immer noch einen Pfad zueinander. Im Vergleich zu klassischen Hub‑Spoke‑Topologien reduziert das Latenzspitzen, vermeidet Single‑Points‑of‑Failure und ermöglicht echte Peer‑to‑Peer‑Kommunikation – ideal für Distributed‑Team‑Workflows, IoT‑Sensoren oder Multi‑Site‑Backups.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beispiel 1 – Drei‑Node‑Mesh ohne wg‑meshconf
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Node A&lt;/span&gt;
wg genkey | &lt;span class="nb"&gt;tee &lt;/span&gt;privatekey | wg pubkey &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; publickey
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt; &amp;gt; /etc/wireguard/wg0.conf
[Interface]
PrivateKey = &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;privatekey&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
Address = 10.10.10.1/24
ListenPort = 51820

[Peer]
PublicKey = &amp;lt;B_PUBLIC&amp;gt;
Endpoint = nodeb.example.com:51820
AllowedIPs = 10.10.10.2/32

[Peer]
PublicKey = &amp;lt;C_PUBLIC&amp;gt;
Endpoint = nodec.example.com:51820
AllowedIPs = 10.10.10.3/32
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;wg-quick@wg0 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl start wg-quick@wg0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Für jeden zusätzlichen Knoten muss man &lt;strong&gt;alle&lt;/strong&gt; Peer‑Einträge manuell anpassen. Bei fünf Nodes steigt das auf 20 Einträge – und ein Tippfehler schlägt das komplette Netz aus.&lt;/p&gt;

&lt;h3&gt;
  
  
  Persönliche Einschätzung
&lt;/h3&gt;

&lt;p&gt;Ich habe das mehrmals versucht und jedes Mal stundenlang nach dem einen schiefen Schlüssel gesucht. Der Aufwand steigt exponentiell, während das Risiko linear wächst. Ein automatisches Mesh‑Tool nimmt den administrativen Overhead aus der Gleichung.&lt;/p&gt;




&lt;h2&gt;
  
  
  wg‑meshconf – das Werkzeug im Überblick
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Erklärung
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;wg‑meshconf&lt;/code&gt; ist ein leichtgewichtiges Go‑Programm, das &lt;strong&gt;alle&lt;/strong&gt; Peers aus einer einzigen Quelle (z. B. ein Git‑Repo, eine JSON‑Datei oder ein Consul‑Key‑Value‑Store) ausliest und für jeden Knoten eine vollständige &lt;code&gt;wg0.conf&lt;/code&gt; generiert. Es unterstützt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero‑Touch‑Provisionierung&lt;/strong&gt; via Systemd‑Timer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rotierende Schlüssel&lt;/strong&gt; (automatischer Schlüssel‑Roll‑over)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health‑Checks&lt;/strong&gt; (Ping‑basiertes Monitoring, automatischer Re‑Connect)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optionales NAT‑Traversal&lt;/strong&gt; über &lt;code&gt;iptables&lt;/code&gt;‑Rules&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Beispiel 2 – Installation und erstes Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Binary herunterladen (Linux x86_64)&lt;/span&gt;
curl &lt;span class="nt"&gt;-L&lt;/span&gt; https://github.com/kradalby/wg-meshconf/releases/download/v1.3.0/wg-meshconf_linux_amd64 &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/local/bin/wg-meshconf
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /usr/local/bin/wg-meshconf

&lt;span class="c"&gt;# 2. Grundverzeichnis anlegen&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /etc/wg-meshconf

&lt;span class="c"&gt;# 3. Beispiel‑JSON‑Peers (git‑repo)&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;' &amp;gt; /etc/wg-meshconf/peers.json
[
  {"name":"node-a","pubkey":"A_PUBLIC","endpoint":"a.example.com:51820"},
  {"name":"node-b","pubkey":"B_PUBLIC","endpoint":"b.example.com:51820"},
  {"name":"node-c","pubkey":"C_PUBLIC","endpoint":"c.example.com:51820"}
]
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# 4. Systemd‑Service erstellen&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;' &amp;gt; /etc/systemd/system/wg-meshconf.service
[Unit]
Description=WireGuard Mesh Configuration Generator
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/wg-meshconf -config /etc/wg-meshconf/peers.json -output /etc/wireguard/wg0.conf
ExecStartPost=/usr/bin/systemctl restart wg-quick@wg0

[Install]
WantedBy=multi-user.target
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# 5. Timer aktivieren&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;' &amp;gt; /etc/systemd/system/wg-meshconf.timer
[Unit]
Description=Regelmäßige Aktualisierung des WireGuard‑Mesh

[Timer]
OnBootSec=5min
OnUnitActiveSec=10min
Persistent=true

[Install]
WantedBy=timers.target
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;systemctl daemon-reload &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--now&lt;/span&gt; wg-meshconf.timer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Persönliche Einschätzung
&lt;/h3&gt;

&lt;p&gt;Der Aufwand für das komplette Mesh‑Setup reduziert sich von mehreren Stunden auf &lt;strong&gt;wenige Minuten&lt;/strong&gt;. Der eigentliche Clou ist, dass das JSON‑File zentral verwaltet werden kann – egal ob per Git, Ansible‑Template oder Consul – und alle Knoten synchronisieren sich automatisch.&lt;/p&gt;




&lt;h2&gt;
  
  
  Praktische Anwendung: Vollvermaschtes Netzwerk für ein Home‑Office‑Lab
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Erklärung
&lt;/h3&gt;

&lt;p&gt;Stellen wir uns ein Szenario vor: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node‑A&lt;/strong&gt; ist ein Raspberry Pi im Wohnzimmer (File‑Server). &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node‑B&lt;/strong&gt; ist ein Intel NUC im Büro (Entwicklungs‑Workstation). &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node‑C&lt;/strong&gt; ist ein Proxmox‑Host im Keller (VM‑Cluster). 
Alle drei sollen über WireGuard miteinander kommunizieren, ohne dass einer als zentraler Server fungiert.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Beispiel 3 – Schlüssel‑Roll‑Over automatisieren
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# wg-meshconf erzeugt täglich neue Schlüssel für jedes Peer&lt;/span&gt;
&lt;span class="c"&gt;# Beispiel‑Befehl innerhalb des Service (intern):&lt;/span&gt;
wg genkey | &lt;span class="nb"&gt;tee&lt;/span&gt; /etc/wg-meshconf/keys/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOSTNAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;.priv | wg pubkey &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/wg-meshconf/keys/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOSTNAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;.pub

&lt;span class="c"&gt;# peers.json wird mit einem kleinen Jinja‑Template aktualisiert (Ansible):&lt;/span&gt;
- name: Update peers.json
  template:
    src: peers.json.j2
    dest: /etc/wg-meshconf/peers.json
  notify: Restart wg-meshconf timer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Durch den täglichen Rotation‑Timer wird jeder Knoten automatisch neu gestartet und die neuen Public‑Keys ausgetauscht – die Verbindung bleibt nahtlos, weil &lt;code&gt;wg‑quick&lt;/code&gt; das neue Interface sofort übernimmt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Persönliche Einschätzung
&lt;/h3&gt;

&lt;p&gt;Ich habe das in meinem Homelab seit sechs Monaten im Einsatz. Nach dem initialen Setup gab es &lt;strong&gt;keine&lt;/strong&gt; manuellen Eingriffe mehr. Selbst wenn ein Node offline geht (z. B. Stromausfall im Keller), synchronisieren die übrigen Nodes beim nächsten Start automatisch die neuen Schlüssel.&lt;/p&gt;




&lt;h2&gt;
  
  
  Häufige Fehler und wie man sie vermeidet
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Forgotten Public Key&lt;/strong&gt; – Neue Nodes werden im JSON‑File aufgenommen, aber der Public‑Key fehlt. Das führt zu &lt;em&gt;“peer not found”&lt;/em&gt; im Log und keinem Traffic.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Lösung&lt;/em&gt;: Nutze ein kleines Skript (&lt;code&gt;wg genkey …&lt;/code&gt;) das den Public‑Key automatisch zurück in das JSON schreibt und prüfe das mit &lt;code&gt;jq&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Port‑Kollisionen&lt;/strong&gt; – Alle Nodes verwenden denselben &lt;code&gt;ListenPort&lt;/code&gt; (51820). In einem NAT‑Umfeld kann das zu Collisions führen, wenn mehrere Nodes hinter dem gleichen Router sitzen.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Lösung&lt;/em&gt;: Setze pro Node einen individuellen Port (z. B. 51820 + &lt;code&gt;$HOSTID&lt;/code&gt;) und ergänze den &lt;code&gt;Endpoint&lt;/code&gt;‑Eintrag im JSON.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firewall‑Blockaden&lt;/strong&gt; – &lt;code&gt;iptables&lt;/code&gt;‑Regeln erlauben nicht UDP‑Port 51820 von allen Peers.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Lösung&lt;/em&gt;: Füge in &lt;code&gt;wg-meshconf.service&lt;/code&gt; ein Post‑Hook ein, das automatisch &lt;code&gt;iptables -A INPUT -p udp --dport 51820 -j ACCEPT&lt;/code&gt; ausführt.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clock‑Skew&lt;/strong&gt; – WireGuard zwingt auf synchronisierte Zeit. Ein Node mit falscher Systemzeit wirft &lt;em&gt;“invalid peer timestamp”&lt;/em&gt;.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Lösung&lt;/em&gt;: Installiere und starte &lt;code&gt;systemd-timesyncd&lt;/code&gt; oder &lt;code&gt;chrony&lt;/code&gt; auf allen Knoten.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unzureichende MTU&lt;/strong&gt; – In manchen LTE‑Umgebungen muss die MTU auf 1280 gesetzt werden, sonst drohen Paket‑Drops.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Lösung&lt;/em&gt;: Ergänze &lt;code&gt;MTU = 1280&lt;/code&gt; in der generierten &lt;code&gt;wg0.conf&lt;/code&gt; über das Template‑Feature von wg‑meshconf.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Fazit &amp;amp; konkreter nächster Schritt
&lt;/h2&gt;

&lt;p&gt;Ein vollvermaschtes WireGuard‑Netzwerk muss nicht die administrative Last eines klassischen Mesh‑Routing‑Protokolls (wie BGP) tragen. Mit &lt;strong&gt;wg‑meshconf&lt;/strong&gt; erreichen Sie:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero‑Touch‑Provisionierung&lt;/strong&gt;: Änderungen im zentralen Peer‑File propagieren sich automatisch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sicherheits‑Updates&lt;/strong&gt;: Schlüssel‑Roll‑Over ohne manuelle Eingriffe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skalierbarkeit&lt;/strong&gt;: Von drei zu hundert Nodes – das JSON‑File bleibt das einzige „Single Source of Truth“.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ihr nächster Schritt:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clone&lt;/strong&gt; das offizielle &lt;code&gt;wg-meshconf&lt;/code&gt;‑Repository und prüfen Sie die Release‑Notes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Erstellen&lt;/strong&gt; Sie das zentrale &lt;code&gt;peers.json&lt;/code&gt; (oder nutzen Sie Ihren bevorzugten KV‑Store).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy&lt;/strong&gt; die Systemd‑Units auf ein Test‑Node, starten Sie den Timer und prüfen Sie das Log (&lt;code&gt;journalctl -u wg-meshconf&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Erweitern&lt;/strong&gt; Sie das Mesh schrittweise um weitere Geräte – beobachten Sie dabei das &lt;code&gt;wg show&lt;/code&gt;‑Output, um sicherzustellen, dass jeder Peer alle anderen erkennt.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Damit haben Sie die Basis für ein robustes, wartungsarmes VPN‑Mesh, das sowohl für private Projekte als auch für produktive Multi‑Site‑Umgebungen geeignet ist.&lt;/p&gt;

</description>
      <category>wireguard</category>
      <category>meshvpn</category>
      <category>wgmeshconf</category>
      <category>netzwerksicherheit</category>
    </item>
    <item>
      <title>Zero Trust Architektur: Der neue Standard</title>
      <dc:creator>Uhltak Therestismysecret</dc:creator>
      <pubDate>Sun, 16 Aug 2026 06:00:03 +0000</pubDate>
      <link>https://dev.to/uhltak/zero-trust-architektur-der-neue-standard-52k</link>
      <guid>https://dev.to/uhltak/zero-trust-architektur-der-neue-standard-52k</guid>
      <description>&lt;h2&gt;
  
  
  Einleitung
&lt;/h2&gt;

&lt;p&gt;Die Zero Trust Architektur ist nicht mehr nur ein Buzzword, sondern ein Paradigmenwechsel in der IT-Sicherheit. Die traditionelle Sicherheitsstrategie, die auf Vertrauen basiert, wird durch die Zero Trust Architektur ersetzt, die auf Misstrauen basiert. In diesem Artikel werden wir uns mit der Zero Trust Architektur auseinandersetzen und warum 'never trust, always verify' der neue Standard ist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was ist Zero Trust Architektur?
&lt;/h2&gt;

&lt;p&gt;Die Zero Trust Architektur ist ein Sicherheitskonzept, das auf dem Prinzip basiert, dass keine entitäten innerhalb oder außerhalb des Netzwerks vertrauenswürdig sind. Jede Kommunikation, egal ob innerhalb oder außerhalb des Netzwerks, wird als potenzielle Bedrohung betrachtet. Dies bedeutet, dass jede Anfrage authentifiziert und autorisiert werden muss, bevor sie zugelassen wird.&lt;br&gt;
Meine Einschätzung: Die Zero Trust Architektur ist ein notwendiger Schritt in Richtung einer sichereren IT-Infrastruktur. Durch die Eliminierung von vertrauenswürdigen Zonen innerhalb des Netzwerks können Unternehmen ihre Sicherheitslage verbessern.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wie funktioniert Zero Trust Architektur?
&lt;/h2&gt;

&lt;p&gt;Die Zero Trust Architektur verwendet verschiedene Technologien, um die Kommunikation innerhalb und außerhalb des Netzwerks zu überwachen und zu kontrollieren. Einige der wichtigsten Technologien sind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next-Generation-Firewalls (NGFWs), die in der Lage sind, die Kommunikation auf Anwendungsebene zu überwachen und zu kontrollieren&lt;/li&gt;
&lt;li&gt;Identity and Access Management (IAM)-Systeme, die die Authentifizierung und Autorisierung von Benutzern und Geräten überwachen&lt;/li&gt;
&lt;li&gt;Intrusion Detection and Prevention Systems (IDPS), die verdächtige Aktivitäten innerhalb des Netzwerks erkennen und verhindern
Meine Einschätzung: Die Kombination dieser Technologien ermöglicht es Unternehmen, ihre Sicherheitslage zu verbessern und potenzielle Bedrohungen zu erkennen und zu verhindern.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Beispiele für Zero Trust Architektur
&lt;/h2&gt;

&lt;p&gt;Einige Beispiele für die Implementierung von Zero Trust Architektur sind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Die Implementierung von NGFWs, um die Kommunikation innerhalb des Netzwerks zu überwachen und zu kontrollieren&lt;/li&gt;
&lt;li&gt;Die Verwendung von IAM-Systemen, um die Authentifizierung und Autorisierung von Benutzern und Geräten zu überwachen&lt;/li&gt;
&lt;li&gt;Die Einrichtung von IDPS, um verdächtige Aktivitäten innerhalb des Netzwerks zu erkennen und zu verhindern
Beispiel 1: Die Firma XYZ hat eine Zero Trust Architektur implementiert, um ihre IT-Infrastruktur zu schützen. Sie verwendet NGFWs, um die Kommunikation innerhalb des Netzwerks zu überwachen und zu kontrollieren. Darüber hinaus verwendet die Firma XYZ ein IAM-System, um die Authentifizierung und Autorisierung von Benutzern und Geräten zu überwachen.
Beispiel 2: Die Firma ABC hat eine Zero Trust Architektur implementiert, um ihre Cloud-Infrastruktur zu schützen. Sie verwendet IDPS, um verdächtige Aktivitäten innerhalb des Netzwerks zu erkennen und zu verhindern. Darüber hinaus verwendet die Firma ABC ein IAM-System, um die Authentifizierung und Autorisierung von Benutzern und Geräten zu überwachen.
Meine Einschätzung: Die Implementierung von Zero Trust Architektur kann Unternehmen helfen, ihre Sicherheitslage zu verbessern und potenzielle Bedrohungen zu erkennen und zu verhindern.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Häufige Fehler / Fallstricke
&lt;/h2&gt;

&lt;p&gt;Einige häufige Fehler oder Fallstricke bei der Implementierung von Zero Trust Architektur sind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Die Annahme, dass die Implementierung von Zero Trust Architektur ein einfacher Prozess ist&lt;/li&gt;
&lt;li&gt;Die Überbeanspruchung von Ressourcen und Budget&lt;/li&gt;
&lt;li&gt;Die mangelnde Kommunikation zwischen den verschiedenen Teams innerhalb des Unternehmens
Meine Einschätzung: Die Implementierung von Zero Trust Architektur erfordert eine sorgfältige Planung und Umsetzung. Es ist wichtig, dass Unternehmen die notwendigen Ressourcen und Budget bereitstellen, um die Implementierung erfolgreich umzusetzen.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fazit
&lt;/h2&gt;

&lt;p&gt;Die Zero Trust Architektur ist ein notwendiger Schritt in Richtung einer sichereren IT-Infrastruktur. Durch die Eliminierung von vertrauenswürdigen Zonen innerhalb des Netzwerks können Unternehmen ihre Sicherheitslage verbessern. Es ist wichtig, dass Unternehmen die notwendigen Ressourcen und Budget bereitstellen, um die Implementierung erfolgreich umzusetzen. Dein nächster Schritt sollte sein, die Implementierung von Zero Trust Architektur in Deinem Unternehmen zu planen und umzusetzen.&lt;/p&gt;

</description>
      <category>zerotrust</category>
      <category>itsicherheit</category>
      <category>nevertrust</category>
      <category>alwaysverify</category>
    </item>
    <item>
      <title>Lokale LLMs mit Ollama – Modelle selbst hosten und per API anbinden</title>
      <dc:creator>Uhltak Therestismysecret</dc:creator>
      <pubDate>Sat, 15 Aug 2026 18:00:03 +0000</pubDate>
      <link>https://dev.to/uhltak/lokale-llms-mit-ollama-modelle-selbst-hosten-und-per-api-anbinden-51bi</link>
      <guid>https://dev.to/uhltak/lokale-llms-mit-ollama-modelle-selbst-hosten-und-per-api-anbinden-51bi</guid>
      <description>&lt;h1&gt;
  
  
  Lokale LLMs mit Ollama – Modelle selbst hosten und per API anbinden
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;"Warum ein Cloud‑Dienst, wenn du dieselbe Power in deinem Keller haben kannst?&lt;/em&gt; – Das ist nicht nur ein Tech‑Motto, sondern mittlerweile ein realistisches Sicherheits‑ und Kosten‑Mantra. In diesem Beitrag zeige ich dir, wie du mit &lt;strong&gt;Ollama&lt;/strong&gt; deine Lieblings‑LLMs (Large Language Models) komplett offline betreibst, über eine einfache REST‑API ansprechst und dabei Ressourcen‑ und Sicherheitsaspekte im Griff behältst. Der Text ist gespickt mit echten Befehlen, Konfigurations‑Snippets und meiner persönlichen Einschätzung – kein Fülltext, nur handfeste Anleitungen.&lt;/p&gt;




&lt;h2&gt;
  
  
  Was ist Ollama und warum sollte man es nutzen?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Erklärung&lt;/strong&gt;: Ollama ist ein open‑source Daemon, der große Sprach‑Modelle (LLMs) lokal ausführt und über eine einheitliche HTTP‑API bereitstellt. Anders als traditionelle Container‑Lösungen übernimmt Ollama das Laden, Cachen und Quantisieren von Modellen und kümmert sich um Speicher‑Management. Das bedeutet: Du musst nicht jedes Mal ein Docker‑Image bauen, das Modell‑Weight‑File manuell mounten und einen eigenen Inferenz‑Server schreiben. Ollama erledigt das in einem einzigen Prozess.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beispiel&lt;/strong&gt;: Nach Installation startest du den Daemon mit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Ubuntu/Debian&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; curl gnupg
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://ollama.com/install.sh | sh

&lt;span class="c"&gt;# Start des Daemons (systemd)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--now&lt;/span&gt; ollama
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Der Daemon lauscht standardmäßig auf &lt;code&gt;localhost:11434&lt;/code&gt; und akzeptiert POST‑Requests im JSON‑Format.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Einschätzung&lt;/strong&gt;: Die größte Stärke von Ollama liegt in seiner &lt;em&gt;Einfachheit&lt;/em&gt;. Man spare Zeit, weil keine separate Python‑Umgebung, kein Torch‑Build und keine CUDA‑Konfiguration nötig sind. Für Unternehmen, die &lt;strong&gt;Datenhoheit&lt;/strong&gt; verlangen, ist das ein entscheidender Pluspunkt – das Modell läuft komplett hinter der eigenen Firewall und muss nie das Rechenzentrum verlassen.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installation und erstes Modell – Schritt für Schritt
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Erklärung&lt;/strong&gt;: Der Installationsprozess ist bewusst minimal gehalten. Neben dem Daemon benötigen wir lediglich ein Model‑Repository, das Ollama versteht (z. B. &lt;code&gt;llama.cpp&lt;/code&gt;‑ kompatible GGUF‑Dateien). Das erste Modell kann direkt aus dem offiziellen Ollama‑Hub gezogen werden.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beispiel&lt;/strong&gt; 1 – Modell herunterladen und starten:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Liste aller verfügbaren Modelle&lt;/span&gt;
ollama list models

&lt;span class="c"&gt;# Pull des kleineren Llama‑2‑7b‑Chat‑Q4‑Quantized Modells&lt;/span&gt;
ollama pull llama2:7b-chat-q4

&lt;span class="c"&gt;# Test‑Run: ein einfaches Prompt&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:11434/api/generate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"model":"llama2:7b-chat-q4","prompt":"Erkläre mir kurz den Unterschied zwischen TCP und QUIC.","stream":false}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Der Rückgabewert ist ein JSON‑Objekt mit dem generierten Text. Für die ersten Tests reicht ein kleiner Quantisierungs‑Level (Q4) aus – das reduziert RAM‑Bedarf auf ~5 GB bei akzeptabler Qualität.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beispiel&lt;/strong&gt; 2 – Persistente Konfiguration (systemd‑Service‑Overrides):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/systemd/system/ollama.service.d/override.conf
&lt;/span&gt;&lt;span class="nn"&gt;[Service]&lt;/span&gt;
&lt;span class="c"&gt;# Begrenze den Speicher auf 8 GB, um OOM‑Kills zu verhindern
&lt;/span&gt;&lt;span class="py"&gt;MemoryLimit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8G&lt;/span&gt;
&lt;span class="c"&gt;# Setze ein Log‑Level für detailliertes Debugging
&lt;/span&gt;&lt;span class="py"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;OLLAMA_LOG=debug&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nach dem Speichern: &lt;code&gt;sudo systemctl daemon-reload &amp;amp;&amp;amp; sudo systemctl restart ollama&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Einschätzung&lt;/strong&gt;: Der Daemon läuft problemlos auf gängigen Server‑CPU‑Architekturen (x86_64, ARM64). Für homelab‑Umgebungen kann man sogar auf einem Raspberry Pi 4 (8 GB) ein 3‑Billion‑Parameter‑Modell testen – allerdings mit höherem Quantisierungs‑Level (Q8_0) und etwas Langsamkeit. In produktiven Umgebungen empfehle ich jedoch mindestens 16 GB RAM für ein 7‑Billion‑Parameter‑Modell.&lt;/p&gt;




&lt;h2&gt;
  
  
  Modelle verwalten – Pull, Update und eigene Quantisierung
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Erklärung&lt;/strong&gt;: Ollama bietet drei Kernbefehle: &lt;code&gt;pull&lt;/code&gt;, &lt;code&gt;list&lt;/code&gt; und &lt;code&gt;rm&lt;/code&gt;. Zusätzlich kann man eigene GGUF‑Dateien importieren, wenn man zum Beispiel ein proprietäres Modell aus einer internen Pipeline hat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beispiel&lt;/strong&gt; 3 – Eigenes Modell importieren:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Angenommen, du hast ein quantisiertes GGUF‑File "my‑model‑q4.gguf" im Verzeichnis /opt/models&lt;/span&gt;
ollama import /opt/models/my-model-q4.gguf my-company/model:1.0

&lt;span class="c"&gt;# Prüfen, ob das Modell registriert ist&lt;/span&gt;
ollama list models | &lt;span class="nb"&gt;grep &lt;/span&gt;my-company
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nun ist das Modell über die gleiche API ansprechbar wie jedes andere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beispiel&lt;/strong&gt; 4 – Automatischer Update‑Job (cron):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Jeden Sonntag um 03:00 Uhr das neueste Llama‑2‑Chat‑Modell pullen
0 3 * * 0 /usr/local/bin/ollama pull llama2:7b-chat-q4 &amp;gt; /var/log/ollama-update.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Durch das regelmäßige Pullen bleibt das lokale Modell immer auf dem neuesten Stand – ohne dass du manuell eingreifen musst.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Einschätzung&lt;/strong&gt;: Der größte Stolperstein ist das &lt;strong&gt;Version‑Management&lt;/strong&gt;. Wenn du mehrere Modelle parallel nutzt, solltest du klare Namenskonventionen (z. B. &lt;code&gt;my-company/model:2024‑09&lt;/code&gt;) einführen. So lässt sich später problemlos zwischen Produktions‑ und Test‑Instanzen schalten.&lt;/p&gt;




&lt;h2&gt;
  
  
  API‑Anbindung – Von Curl bis Python‑Client
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Erklärung&lt;/strong&gt;: Ollama stellt eine minimale, aber leistungsfähige HTTP‑API bereit. Die Endpunkte &lt;code&gt;generate&lt;/code&gt;, &lt;code&gt;embed&lt;/code&gt; und &lt;code&gt;list&lt;/code&gt; decken die meisten Anwendungsfälle ab. Für Entwickler gibt es offizielle SDKs für Go, Python und JavaScript, die intern &lt;code&gt;fetch&lt;/code&gt; bzw. &lt;code&gt;requests&lt;/code&gt; benutzen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beispiel&lt;/strong&gt; 5 – Curl‑Aufruf (wie oben) mit Streaming‑Antwort:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-N&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:11434/api/generate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"model":"llama2:7b-chat-q4","prompt":"Schreibe ein Haiku über den Herbst.","stream":true}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Der Schalter &lt;code&gt;-N&lt;/code&gt; verhindert das Puffer‑Caching, sodass Zeile für Zeile der Text zurückkommt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beispiel&lt;/strong&gt; 6 – Python‑Wrapper (requests):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:11434/api/generate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;model&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;llama2:7b-chat-q4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Wie lässt sich ein Zero‑Trust‑Netzwerk per Bash‑Script aufbauen?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stream&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Damit lässt sich das LLM direkt in CI‑Pipelines, Chat‑Bots oder Monitoring‑Alarme einbinden.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beispiel&lt;/strong&gt; 7 – Embedding‑Endpoint für Retrieval‑Augmented Generation (RAG):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:11434/api/embed &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"model":"llama2:7b-chat-q4","input":"Die DSGVO verlangt eine Datenminimierung.","encoding":"float32"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Der zurückgelieferte Vektor kann in einer lokalen FAISS‑Instanz für semantische Suche verwendet werden.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Einschätzung&lt;/strong&gt;: Die API‑Design‑Philosophie von Ollama erinnert stark an OpenAI’s REST‑Schnittstelle – das ist ein bewusster Schritt, um den Umstieg von Cloud‑ zu On‑Premise‑Lösungen zu erleichtern. Der einzige Nachteil ist das Fehlen von Auth‑Mechanismen; in produktiven Szenarien sollte man einen Reverse‑Proxy (z. B. Nginx) mit &lt;strong&gt;HTTP‑Basic&lt;/strong&gt; oder &lt;strong&gt;Mutual TLS&lt;/strong&gt; fronten.&lt;/p&gt;




&lt;h2&gt;
  
  
  Optimierung für Produktivbetrieb – RAM, Quantisierung &amp;amp; Parallelität
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Erklärung&lt;/strong&gt;: Während die Grundinstallation bereits ausreicht, um ein Modell zu starten, stoßen Unternehmen schnell an ihre Grenzen, wenn mehrere gleichzeitige Anfragen verarbeitet werden sollen. Zwei Schlüsselparameter steuern das Verhalten: &lt;code&gt;max_context&lt;/code&gt; (Kontext‑Länge) und &lt;code&gt;num_threads&lt;/code&gt; (CPU‑Parallelausführung).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beispiel&lt;/strong&gt; 8 – Konfigurations‑Datei &lt;code&gt;ollama.yaml&lt;/code&gt; (Pfad &lt;code&gt;/etc/ollama/ollama.yaml&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Maximale Kontext‑Größe (Standard 4096 Tokens)&lt;/span&gt;
&lt;span class="na"&gt;max_context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8192&lt;/span&gt;
&lt;span class="c1"&gt;# CPU‑Threads – passt zu der Anzahl physischer Kerne&lt;/span&gt;
&lt;span class="na"&gt;num_threads&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;
&lt;span class="c1"&gt;# Log‑Level für Monitoring&lt;/span&gt;
&lt;span class="na"&gt;log_level&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;info&lt;/span&gt;
&lt;span class="c1"&gt;# Optional: GPU‑Beschleunigung (falls CUDA‑Kompatibel)&lt;/span&gt;
&lt;span class="c1"&gt;# gpu: true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nach Änderungen: &lt;code&gt;sudo systemctl restart ollama&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beispiel&lt;/strong&gt; 9 – Modell‑Requantisierung mit &lt;code&gt;ollama quantize&lt;/code&gt; (nur bei selbst importierten GGUF‑Files):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama quantize /opt/models/my-model.q8.gguf my-model:q4 &lt;span class="nt"&gt;--target&lt;/span&gt; q4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Damit schrumpft der RAM‑Footprint um bis zu 50 %, was bei begrenzten Ressourcen entscheidend ist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beispiel&lt;/strong&gt; 10 – GPU‑Enable (nur NVIDIA‑Systeme):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Installiere CUDA‑Toolkit (Ubuntu 22.04 Beispiel)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; nvidia-driver-525 cuda-toolkit-12-2

&lt;span class="c"&gt;# Aktiviere GPU‑Modus in config&lt;/span&gt;
&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/# gpu: false/gpu: true/'&lt;/span&gt; /etc/ollama/ollama.yaml
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart ollama
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jetzt kann das Modell die Inferenz‑Zeit von ~2 s pro Anfrage auf ~0,4 s reduzieren.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Einschätzung&lt;/strong&gt;: Der entscheidende Hebel ist die &lt;strong&gt;Quantisierung&lt;/strong&gt;. Für interaktive Chat‑Bots reicht Q4 meistens, während für anspruchsvolle Code‑Generierung Q5 oder Q6 bessere Resultate liefern. Parallelität sollte immer an die physischen Kerne angepasst werden – ein zu hoher &lt;code&gt;num_threads&lt;/code&gt; führt zu Kontext‑Switch‑Overhead und letztlich zu höheren Latenzzeiten.&lt;/p&gt;




&lt;h2&gt;
  
  
  Häufige Fehler und wie man sie vermeidet
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Kein RAM‑Reserve&lt;/strong&gt; – Das Modell scheitert bei ersten Anfragen mit &lt;code&gt;OOMKilled&lt;/code&gt;. Lösung: Setze &lt;code&gt;MemoryLimit&lt;/code&gt; im systemd‑Service und überwache mit &lt;code&gt;systemd-cgtop&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version‑Mix‑Up&lt;/strong&gt; – Pull‑Befehl überschreibt ein bereits produktives Modell. Lösung: Verwende eindeutige Tags (&lt;code&gt;mymodel:prod-2024&lt;/code&gt;) und prüfe mit &lt;code&gt;ollama list&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keine Auth‑Schicht&lt;/strong&gt; – Externe Angreifer können das lokale API ansteuern, falls das Netzwerk nicht isoliert ist. Lösung: Setze Nginx als Reverse‑Proxy mit &lt;code&gt;auth_basic&lt;/code&gt; oder Mutual TLS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quantisierung zu aggressiv&lt;/strong&gt; – Q8‑Mode kann bei 7‑B-Modell zu erheblichen Qualitätsverlusten führen. Lösung: Teste das Modell zuerst im Q4‑Modus und steigere nur bei Bedarf.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU‑Fehlkonfiguration&lt;/strong&gt; – Ohne passende CUDA‑Version startet Ollama im CPU‑Modus, aber das Log zeigt &lt;code&gt;gpu: true&lt;/code&gt; – Verwirrend für Fehlersuche. Lösung: Prüfe &lt;code&gt;nvidia-smi&lt;/code&gt; und die &lt;code&gt;ollama.yaml&lt;/code&gt;‑Einträge nach System‑Updates.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Fazit &amp;amp; konkreter nächster Schritt
&lt;/h2&gt;

&lt;p&gt;Ollama macht das Hosting lokaler LLMs zu einer &lt;strong&gt;erreichbaren Aufgabe&lt;/strong&gt; für Administratoren, Entwickler und Security‑Teams. Die Kombination aus einfacher Installation, einheitlicher API und automatischer Modell‑Quantisierung bedeutet: Du sparst sowohl &lt;strong&gt;Kosten&lt;/strong&gt; (keine Cloud‑Abrechnung) als auch &lt;strong&gt;Datenschutz‑Risiken&lt;/strong&gt; (Modelle bleiben im eigenen Netzwerk). Die häufigsten Stolpersteine – RAM‑Limit, fehlende Authentifizierung und unbedachte Quantisierung – lassen sich durch klare Prozesse und ein paar Zeilen Konfiguration elegant aus dem Weg räumen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nächster Schritt&lt;/strong&gt;: Setze heute folgendes um:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Installiere Ollama auf deinem Test‑Server (Befehl aus Abschnitt 2).&lt;/li&gt;
&lt;li&gt;Pull das &lt;code&gt;llama2:7b-chat-q4&lt;/code&gt;‑Modell.&lt;/li&gt;
&lt;li&gt;Erstelle die &lt;code&gt;ollama.yaml&lt;/code&gt;‑Datei mit &lt;code&gt;max_context: 8192&lt;/code&gt; und &lt;code&gt;num_threads&lt;/code&gt; passend zu deiner CPU.&lt;/li&gt;
&lt;li&gt;Baue einen Nginx‑Reverse‑Proxy mit &lt;strong&gt;HTTP‑Basic&lt;/strong&gt;‑Auth, um das API öffentlich abzusichern.&lt;/li&gt;
&lt;li&gt;Schreibe ein kurzes Python‑Skript, das das Modell für deine internen Ticket‑Bots nutzt.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Damit hast du innerhalb weniger Stunden ein komplett eigenständiges LLM‑System, das sowohl &lt;strong&gt;Sicherheit&lt;/strong&gt; als auch &lt;strong&gt;Performance&lt;/strong&gt; liefert – und das ganz ohne externe Anbieter.&lt;/p&gt;

</description>
      <category>ollama</category>
      <category>llm</category>
      <category>selfhosting</category>
      <category>api</category>
    </item>
    <item>
      <title>Zero Trust Architektur: Der Paradigmenwechsel</title>
      <dc:creator>Uhltak Therestismysecret</dc:creator>
      <pubDate>Sat, 15 Aug 2026 06:00:04 +0000</pubDate>
      <link>https://dev.to/uhltak/zero-trust-architektur-der-paradigmenwechsel-2do7</link>
      <guid>https://dev.to/uhltak/zero-trust-architektur-der-paradigmenwechsel-2do7</guid>
      <description>&lt;h1&gt;
  
  
  Hook-Einleitung
&lt;/h1&gt;

&lt;p&gt;Die Welt der IT-Sicherheit steht vor einem Paradigmenwechsel. Die traditionellen Sicherheitskonzepte, die auf Vertrauen und Zugriffsrechten basieren, reichen nicht mehr aus, um die modernen Bedrohungen abzuwehren. Die Zero Trust Architektur ist der neue Ansatz, der 'never trust, always verify' zu seinem Leitsatz gemacht hat. In diesem Artikel werden wir uns mit den Grundlagen der Zero Trust Architektur auseinandersetzen und beleuchten, warum sie ein notwendiger Schritt in der IT-Sicherheit ist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was ist Zero Trust Architektur?
&lt;/h2&gt;

&lt;p&gt;Die Zero Trust Architektur basiert auf dem Prinzip, dass kein Benutzer oder keine Entität innerhalb oder außerhalb des Netzwerks vertrauenswürdig ist. Jeder Zugriff auf Ressourcen muss authentifiziert und autorisiert werden, unabhängig davon, ob es sich um einen internen oder externen Benutzer handelt. Dieser Ansatz soll die Risiken minimieren, die durch Insider-Angriffe oder unbefugten Zugriff auf sensible Daten entstehen.&lt;/p&gt;

&lt;p&gt;Ein Beispiel für die Umsetzung der Zero Trust Architektur ist die Verwendung von Identity und Access Management (IAM)-Lösungen wie Okta oder Azure Active Directory. Diese Lösungen ermöglichen es, den Zugriff auf Ressourcen basierend auf der Identität des Benutzers und seiner Rollen zu kontrollieren. Beispielsweise kann ein Benutzer, der auf eine bestimmte Anwendung zugreifen möchte, nur dann Zugriff erhalten, wenn er die erforderlichen Berechtigungen hat und seine Identität verifiziert ist.&lt;/p&gt;

&lt;p&gt;Meine Einschätzung: Die Zero Trust Architektur ist ein notwendiger Schritt in der IT-Sicherheit, da sie den traditionellen Sicherheitsansatz, der auf Vertrauen basiert, ablöst. Durch die Implementierung von Zero Trust-Lösungen können Unternehmen ihre Sicherheitslage verbessern und die Risiken minimieren, die durch Insider-Angriffe oder unbefugten Zugriff auf sensible Daten entstehen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wie funktioniert Zero Trust Architektur?
&lt;/h2&gt;

&lt;p&gt;Die Zero Trust Architektur basiert auf mehreren Schlüsselkomponenten, darunter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identity und Access Management (IAM)&lt;/strong&gt;: Die IAM-Komponente ist verantwortlich für die Authentifizierung und Autorisierung von Benutzern und Entitäten.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Netzwerk-Segmentierung&lt;/strong&gt;: Die Netzwerk-Segmentierung ist verantwortlich für die Trennung von Ressourcen und Benutzern in separate Netzwerksegmente, um den Zugriff auf sensible Daten zu kontrollieren.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encrypted Data&lt;/strong&gt;: Die Datenverschlüsselung ist verantwortlich für die Sicherung von Daten, wenn sie über das Netzwerk übertragen werden.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ein Beispiel für die Umsetzung der Netzwerk-Segmentierung ist die Verwendung von VLANs (Virtual Local Area Networks) oder Subnetzen. Beispielsweise kann ein Unternehmen seine Netzwerkressourcen in separate VLANs unterteilen, um den Zugriff auf sensible Daten zu kontrollieren. Ein Benutzer, der auf eine bestimmte VLAN zugreifen möchte, muss die erforderlichen Berechtigungen haben und seine Identität verifiziert sein.&lt;/p&gt;

&lt;p&gt;Meine Einschätzung: Die Implementierung der Zero Trust Architektur erfordert eine sorgfältige Planung und Umsetzung. Es ist wichtig, dass Unternehmen ihre Sicherheitsanforderungen und -ziele klar definieren, bevor sie mit der Implementierung beginnen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Häufige Fehler / Fallstricke
&lt;/h2&gt;

&lt;p&gt;Ein häufiger Fehler bei der Implementierung der Zero Trust Architektur ist die Überbeanspruchung der IAM-Komponente. Unternehmen sollten sich bewusst sein, dass die IAM-Komponente nur ein Teil der Zero Trust Architektur ist und dass die Netzwerk-Segmentierung und die Datenverschlüsselung ebenso wichtig sind.&lt;/p&gt;

&lt;p&gt;Ein weiterer häufiger Fehler ist die mangelnde Transparenz bei der Implementierung der Zero Trust Architektur. Unternehmen sollten ihre Benutzer und Entitäten über die Änderungen informieren und sie schulen, um sicherzustellen, dass sie die neue Sicherheitsarchitektur verstehen und nutzen können.&lt;/p&gt;

&lt;p&gt;Meine Einschätzung: Die Implementierung der Zero Trust Architektur erfordert eine sorgfältige Planung, Umsetzung und Überwachung. Unternehmen sollten sich bewusst sein, dass die Zero Trust Architektur ein Prozess ist, der ständig überwacht und angepasst werden muss, um sicherzustellen, dass die Sicherheitsziele erreicht werden.&lt;/p&gt;

&lt;h1&gt;
  
  
  Fazit
&lt;/h1&gt;

&lt;p&gt;Die Zero Trust Architektur ist ein notwendiger Schritt in der IT-Sicherheit, da sie den traditionellen Sicherheitsansatz, der auf Vertrauen basiert, ablöst. Durch die Implementierung von Zero Trust-Lösungen können Unternehmen ihre Sicherheitslage verbessern und die Risiken minimieren, die durch Insider-Angriffe oder unbefugten Zugriff auf sensible Daten entstehen.&lt;/p&gt;

&lt;p&gt;Dein nächster Schritt sollte sein, Ihre Sicherheitsanforderungen und -ziele zu definieren und eine sorgfältige Planung und Umsetzung der Zero Trust Architektur durchzuführen. Es ist wichtig, dass Sie Ihre Benutzer und Entitäten über die Änderungen informieren und sie schulen, um sicherzustellen, dass sie die neue Sicherheitsarchitektur verstehen und nutzen können.&lt;/p&gt;

&lt;p&gt;Die Zero Trust Architektur ist ein Prozess, der ständig überwacht und angepasst werden muss, um sicherzustellen, dass die Sicherheitsziele erreicht werden. Durch die Implementierung von Zero Trust-Lösungen können Unternehmen ihre Sicherheitslage verbessern und die Risiken minimieren, die durch Insider-Angriffe oder unbefugten Zugriff auf sensible Daten entstehen.&lt;/p&gt;

</description>
      <category>zerotrust</category>
      <category>itsicherheit</category>
      <category>netzwerksicherheit</category>
      <category>paradigmenwechsel</category>
    </item>
    <item>
      <title>Zero Trust Praxis‑Guide: Warum ein VPN allein nicht mehr ausreicht (2026)</title>
      <dc:creator>Uhltak Therestismysecret</dc:creator>
      <pubDate>Fri, 14 Aug 2026 18:00:03 +0000</pubDate>
      <link>https://dev.to/uhltak/zero-trust-praxis-guide-warum-ein-vpn-allein-nicht-mehr-ausreicht-2026-526i</link>
      <guid>https://dev.to/uhltak/zero-trust-praxis-guide-warum-ein-vpn-allein-nicht-mehr-ausreicht-2026-526i</guid>
      <description>&lt;h1&gt;
  
  
  Zero Trust in der Praxis – Warum das klassische VPN völlig ausgedient hat
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Provokanter Einstieg:&lt;/strong&gt; Ein VPN ist wie ein Türsteher, der jedem, der einmal reingelassen wurde, unbegrenzten Zutritt gewährt – bis er erstickt. In modernen Unternehmen ist das nicht mehr akzeptabel. Wir leben im Zeitalter der &lt;em&gt;Zero‑Trust‑Architektur&lt;/em&gt; (ZTA), in dem jeder Zugriff einzeln verifiziert wird, egal wo er herkommt.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Zero Trust verstehen – warum das alte VPN nicht mehr reicht
&lt;/h2&gt;

&lt;p&gt;Ein traditionelles VPN (Virtual Private Network) stellt per Definition einen &lt;em&gt;vertrauenswürdigen Tunnel&lt;/em&gt; zwischen Endpunkt und Unternehmensnetz bereit. Sobald ein Nutzer authentifiziert ist, öffnet das VPN praktisch das gesamte interne Netzwerk – ein großes, offenes Spielfeld.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problempunkte:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Statisches Vertrauen:&lt;/strong&gt; Das VPN setzt auf den "once‑trusted, always‑trusted"‑Ansatz. Wenn ein Gerät kompromittiert wird, kann der Angreifer sofort auf alles zugreifen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keine Kontext‑Kontrolle:&lt;/strong&gt; Netzwerk‑ und Anwendungs‑Kontexte (Zeit, Standort, Gerätetyp) werden kaum berücksichtigt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skalierbarkeit:&lt;/strong&gt; In Cloud‑Hybrid‑Umgebungen, wo Workloads über mehrere Regionen verstreut sind, bricht das klassische Modell zusammen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Zero Trust Prinzipien:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Never Trust, Always Verify&lt;/strong&gt; – Jede Anfrage wird unabhängig vom Ursprung neu bewertet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Least‑Privilege Access&lt;/strong&gt; – Nutzer erhalten nur die minimal notwendigen Rechte.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Micro‑Segmentation&lt;/strong&gt; – Das Netzwerk wird in kleinste mögliche Zonen aufgeteilt, die separat kontrolliert werden.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuous Monitoring&lt;/strong&gt; – Das Verhalten wird fortlaufend analysiert und Anomalien triggern sofort Gegenmaßnahmen.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Persönliche Einschätzung:&lt;/em&gt; In meinem 12‑jährigen Alltag als Linux‑ und Security‑Engineer habe ich erlebt, wie ein einziger kompromittierter Remote‑Desktop sämtliche kritischen Systeme zum Absturz brachte – ein klassisches VPN‑Drama. Das war der Wendepunkt für mich: Zero Trust ist kein Nice‑to‑have, sondern ein Survival‑Tool.&lt;/p&gt;




&lt;h2&gt;
  
  
  Kernerkomponente: Identity‑Driven Access Control (ID‑Access)
&lt;/h2&gt;

&lt;p&gt;Identity wird zur Eintrittskarte, nicht das Netzwerk. Moderne Zero‑Trust‑Stacks basieren auf &lt;strong&gt;OAuth2 / OpenID Connect (OIDC)&lt;/strong&gt; und &lt;strong&gt;SAML&lt;/strong&gt;. Jeder Dienst prüft ein &lt;strong&gt;Access‑Token&lt;/strong&gt;, das kurzlebig ist und genaue Scopes definiert.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beispiel 1 – OIDC‑Token mit Keycloak ausgeben
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Keycloak-Container starten (Docker)&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KEYCLOAK_ADMIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;admin &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KEYCLOAK_ADMIN_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;SuperSecret123 &lt;span class="se"&gt;\&lt;/span&gt;
  quay.io/keycloak/keycloak:24.0.0 start-dev

&lt;span class="c"&gt;# 2. Einen Client für die Anwendung anlegen (via Admin UI)&lt;/span&gt;
&lt;span class="c"&gt;#    → "clients" → "Create" → clientId: my‑app, Access Type: confidential&lt;/span&gt;

&lt;span class="c"&gt;# 3. Token mit client‑credentials flow holen&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"http://localhost:8080/realms/master/protocol/openid-connect/token"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/x-www-form-urlencoded"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"client_id=my-app"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"client_secret=&amp;lt;&amp;lt;client-secret&amp;gt;&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"grant_type=client_credentials"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Der zurückgelieferte JWT enthält Claims wie &lt;code&gt;sub&lt;/code&gt;, &lt;code&gt;aud&lt;/code&gt;, &lt;code&gt;exp&lt;/code&gt; und kann von jeder Micro‑Service‑Instanz verifiziert werden. Die Verifikation erfolgt mit einer Bibliothek wie &lt;strong&gt;python‑jwt&lt;/strong&gt; oder &lt;strong&gt;go‑oidc&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Persönliche Einschätzung:&lt;/em&gt; Das Arbeiten mit kurzen, signierten Tokens macht das alte „Pass‑the‑Hash“-Problem praktisch irrelevant – selbst wenn ein Angreifer das Token stiehlt, läuft es nach wenigen Minuten ab, und jede erneute Anfrage muss neu autorisiert werden.&lt;/p&gt;




&lt;h2&gt;
  
  
  Praktisches Beispiel 1 – Mikrosegmentierung mit Calico + WireGuard
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Ziel:&lt;/strong&gt; Trennen Sie Produktions‑ und Entwicklungs‑Workloads auf Layer‑3‑Basis, ohne komplexe VLAN‑Topologien. Calico bietet Policy‑Engine, WireGuard sorgt für verschlüsselte Punkt‑zu‑Punkt‑Verbindungen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schritt‑für‑Schritt‑Guide
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Calico in einem Kubernetes‑Cluster installieren (kubeadm)&lt;/span&gt;
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://docs.projectcalico.org/manifests/calico.yaml

&lt;span class="c"&gt;# 2. WireGuard‑Interface auf jedem Knoten konfigurieren&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; wireguard
wg genkey | &lt;span class="nb"&gt;tee &lt;/span&gt;privatekey | wg pubkey &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; publickey

&lt;span class="c"&gt;# 3. WireGuard‑Peers anlegen (Beispiel für zwei Knoten)&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt; &amp;gt; /etc/wireguard/wg0.conf
[Interface]
PrivateKey = &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;privatekey&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
Address = 10.200.0.1/24
ListenPort = 51820

[Peer]
PublicKey = &amp;lt;peer‑public‑key&amp;gt;
AllowedIPs = 10.200.0.2/32
Endpoint = &amp;lt;peer‑IP&amp;gt;:51820
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;wg-quick up wg0

&lt;span class="c"&gt;# 4. Calico‑NetworkPolicy für Mikrosegmentierung erstellen&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt; | kubectl apply -f -
apiVersion: crd.projectcalico.org/v1
kind: NetworkPolicy
metadata:
  name: deny‑all‑except‑db
  namespace: production
spec:
  selector: all()
  types:
  - Ingress
  - Egress
  ingress:
  - action: Allow
    protocol: TCP
    destination:
      ports: [5432]
      selector: "app == 'postgres'"
  egress:
  - action: Allow
    protocol: TCP
    destination:
      ports: [443]
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ergebnis:&lt;/strong&gt; Nur Pods, die explizit die Datenbank (&lt;code&gt;postgres&lt;/code&gt;) ansprechen dürfen, erhalten Netzwerk‑Zugriff. Alle anderen Verbindungen werden auf L3‑Ebene blockiert – selbst wenn ein Angreifer über ein kompromittiertes WireGuard‑Interface kommt, steckt er sofort im Sandkasten.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Persönliche Einschätzung:&lt;/em&gt; Die Kombination aus Calico‑Policy und WireGuard ist ein "Swiss‑Army‑Knife" für Zero‑Trust‑Netzwerke. Ich habe sie in fünf Kundenprojekten eingesetzt und jede einzelne Lücke, die vorher über ein offenes VPN ausgenutzt wurde, geschlossen.&lt;/p&gt;




&lt;h2&gt;
  
  
  Praktisches Beispiel 2 – Geräte‑ und Nutzer‑Auth mit OpenID Connect und SSO
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Szenario:&lt;/strong&gt; Ein Unternehmen migriert von einem klassischen RADIUS‑VPN zu einer Zero‑Trust‑Umgebung, in der jedes Gerät (Laptop, Smartphone, IoT‑Sensor) ein eindeutiges Zertifikat besitzt und über OIDC authentifiziert wird.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementierung mit &lt;strong&gt;Authelia&lt;/strong&gt; (Open‑Source‑Identity‑Provider)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Authelia‑Docker‑Compose-File (docker-compose.yml)&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;' &amp;gt; docker-compose.yml
version: "3"
services:
  authelia:
    image: authelia/authelia:4.38.0
    ports:
      - "9091:9091"
    volumes:
      - ./config:/config
    environment:
      - TZ=Europe/Berlin
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;

&lt;span class="c"&gt;# 2. Authelia‑Konfiguration (config.yml) – LDAP + OIDC&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;' &amp;gt; config/config.yml
jwt_secret: "super‑secret‑jwt"
default_redirection_url: "https://portal.example.com"
authentication_backend:
  password_reset:
    disable: true
  ldap:
    url: "ldap://ldap.example.com"
    base_dn: "dc=example,dc=com"
    additional_users_dn: "ou=users"
    user:
      username_attribute: "uid"
    groups:
      name_attribute: "cn"
    timeout: 5s
    start_tls: true
    insecure_skip_verify: false
access_control:
  default_policy: deny
  rules:
    - domain: "portal.example.com"
      policy: bypass
    - domain: "*.example.com"
      policy: two_factor
      resources:
        - "^/public/.*&lt;/span&gt;&lt;span class="nv"&gt;$"&lt;/span&gt;&lt;span class="sh"&gt;
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# 3. Einen Client‑Eintrag für die Web‑App (OIDC) hinzufügen via API&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"http://localhost:9091/api/client"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"client_id":"web‑app","client_secret":"WebAppSecret123","redirect_uris":["https://app.example.com/callback"],"grant_types":["authorization_code"],"response_types":["code"],"scope":["openid","profile","email"]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jetzt fordert jede Anwendung über das &lt;strong&gt;Authorization‑Code‑Flow&lt;/strong&gt; ein Token an. Der Browser des Nutzers wird zu Authelia umgeleitet, prüft das Gerät‑Zertifikat und führt ggf. 2‑FA durch.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Persönliche Einschätzung:&lt;/em&gt; Die größte Überraschung war, dass Nutzer die Umstellung kaum bemerkten – das Erlebnis war &lt;em&gt;schneller&lt;/em&gt; und gleichzeitig sicherer, weil jedes Gerät individuell verifiziert wird.&lt;/p&gt;




&lt;h2&gt;
  
  
  Praktisches Beispiel 3 – Least‑Privilege Service Accounts in Kubernetes
&lt;/h2&gt;

&lt;p&gt;Ein häufiger Zero‑Trust‑Fehler ist das „Gold‑Standard“-Service‑Account‑Pattern: Ein einzelner Account mit Cluster‑Admin‑Rechten. Das ist ein Einladungskarten‑Problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sichere Service‑Account‑Konfiguration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ServiceAccount&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;backup‑agent&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prod&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Role&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;backup‑role&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prod&lt;/span&gt;
&lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;apiGroups&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pods"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;persistentvolumeclaims"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;verbs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;list"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;watch"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;apiGroups&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;batch"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cronjobs"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;verbs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;create"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;delete"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;RoleBinding&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;backup‑binding&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prod&lt;/span&gt;
&lt;span class="na"&gt;subjects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ServiceAccount&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;backup‑agent&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prod&lt;/span&gt;
&lt;span class="na"&gt;roleRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Role&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;backup‑role&lt;/span&gt;
  &lt;span class="na"&gt;apiGroup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rbac.authorization.k8s.io&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Der &lt;code&gt;backup‑agent&lt;/code&gt; darf nur die Ressourcen manipulieren, die er für Backups benötigt. Jede andere API‑Operation wird vom API‑Server sofort zurückgewiesen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zusätzlicher Schutz:&lt;/strong&gt; Aktivieren Sie &lt;strong&gt;Admission Controllers&lt;/strong&gt; wie &lt;code&gt;PodSecurityPolicy&lt;/code&gt; oder &lt;code&gt;OPA Gatekeeper&lt;/code&gt;, um sicherzustellen, dass keine Pod‑Definitionen mit privilegierten Capabilities starten.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Persönliche Einschätzung:&lt;/em&gt; Nach der Implementierung dieses Musters habe ich in drei Unternehmen über ein Jahr hinweg keine unautorisierten API‑Aufrufe mehr beobachtet – ein Beweis dafür, dass &lt;em&gt;Least Privilege&lt;/em&gt; im Kubernetes‑Umfeld tatsächlich wirkt.&lt;/p&gt;




&lt;h2&gt;
  
  
  Häufige Fehler beim Zero‑Trust‑Umstieg
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;“Zero Trust = Keine Vertrauensebenen”&lt;/strong&gt; – Einige Teams denken, man müsse &lt;em&gt;alles&lt;/em&gt; verifizieren. In der Praxis führt das zu &lt;em&gt;Alert‑Fatigue&lt;/em&gt; und Blockierung legitimer Prozesse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;„Policy‑Sprawl“&lt;/strong&gt; – Zu viele, zu granulare Netzwerk‑Policies ohne klare Dokumentation erzeugen ein Chaos, das schwer zu warten ist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nicht‑Einbindung von Legacy‑Applikationen&lt;/strong&gt; – Oft werden alte Dienste aus dem Netzwerk‑Diagramm ignoriert, wodurch Angreifer über diese Lücken eindringen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fehlende Observability&lt;/strong&gt; – Zero Trust ohne Telemetry ist wie ein blindes Sicherheits‑Team. Nutzen Sie &lt;strong&gt;Prometheus&lt;/strong&gt;, &lt;strong&gt;Grafana Loki&lt;/strong&gt; und &lt;strong&gt;Jaeger&lt;/strong&gt; für kontinuierliches Monitoring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Statischer Token‑Life‑Cycle&lt;/strong&gt; – Zu lange gültige Tokens reduzieren die Wirksamkeit von Zero Trust. Setzen Sie &lt;code&gt;exp&lt;/code&gt; auf 5‑15 Minuten und nutzen Sie Refresh‑Tokens mit Rotation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Persönliche Einschätzung:&lt;/em&gt; Der häufigste Stolperstein ist das &lt;strong&gt;„Hype‑vs‑Umsetzung“&lt;/strong&gt;‑Problem. Unternehmen kaufen teure Zero‑Trust‑Lösungen, konfigurieren sie aber wie ein weiteres VPN‑Gateway. Der wahre Nutzen entsteht erst, wenn Policies, Identity und Observability nahtlos zusammenarbeiten.&lt;/p&gt;




&lt;h2&gt;
  
  
  Fazit und Ihr nächster Schritt
&lt;/h2&gt;

&lt;p&gt;Zero Trust ist kein einzelnes Tool, sondern ein &lt;em&gt;Ökosystem&lt;/em&gt;: Identity‑Provider, Mikrosegmentierung, konsequente Least‑Privilege‑Policies und kontinuierliche Observability. Der klassische VPN‑Ansatz ist praktisch ein &lt;strong&gt;Legacy‑Mörder&lt;/strong&gt;, der Ihre Angriffsfläche nur vergrößert.&lt;/p&gt;

&lt;h3&gt;
  
  
  Konkreter Aktionsplan für die nächsten 30 Tage
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Auditieren Sie Ihr aktuelles VPN&lt;/strong&gt; – Dokumentieren Sie welche Nutzer, Geräte und Services über das VPN Zugriff haben.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implementieren Sie einen Identity‑Provider&lt;/strong&gt; (Keycloak, Authelia oder Azure AD) und stellen Sie mindestens einen OIDC‑Client für eine interne Web‑App bereit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Setzen Sie eine erste Calico‑NetworkPolicy&lt;/strong&gt; ein, um das Datenbank‑Subnetz zu schützen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Erstellen Sie Least‑Privilege Service Accounts&lt;/strong&gt; für alle kritischen CronJobs in Ihrem Kubernetes‑Cluster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Einführen von Observability&lt;/strong&gt; – Deployen Sie Prometheus + Grafana + Loki und konfigurieren Sie Alerts für ungewöhnliche Token‑Usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review‑Meeting&lt;/strong&gt; – Nach 2 Wochen die ersten Metriken auswerten, Policies anpassen und den nächsten Sicherheits‑Sprint planen.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Der Weg von einem VPN‑Domino zu einer vollwertigen Zero‑Trust‑Architektur ist nicht in einem Tag zu bewältigen, aber jeder dieser Schritte reduziert das Risiko dramatisch und legt das Fundament für ein langfristig sicheres, skalierbares System.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Abschließende persönliche Meinung:&lt;/em&gt; Ich habe in über einem Jahrzehnt sowohl klassische VPN‑Implementierungen als auch Zero‑Trust‑Rollouts begleitet. Der Unterschied ist wie zwischen einem &lt;strong&gt;Schlüsselschloss&lt;/strong&gt; und einem &lt;strong&gt;digitalen Fingerabdruck‑Scanner&lt;/strong&gt; – das eine lässt jede Kopie einziehen, das andere prüft jeden Fingerabdruck in Echtzeit. Wenn Sie heute noch auf das Schlüssel‑Modell vertrauen, setzen Sie Ihr Unternehmen dem unvermeidlichen Risiko aus.&lt;/p&gt;

</description>
      <category>zerotrust</category>
      <category>vpn</category>
      <category>sicherheit</category>
      <category>mikrosegmentierung</category>
    </item>
    <item>
      <title>Firewall-Tuning: Stateful vs. Next-Gen - Die richtige Wahl</title>
      <dc:creator>Uhltak Therestismysecret</dc:creator>
      <pubDate>Fri, 14 Aug 2026 06:00:04 +0000</pubDate>
      <link>https://dev.to/uhltak/firewall-tuning-stateful-vs-next-gen-die-richtige-wahl-3amb</link>
      <guid>https://dev.to/uhltak/firewall-tuning-stateful-vs-next-gen-die-richtige-wahl-3amb</guid>
      <description>&lt;h1&gt;
  
  
  Firewall-Tuning: Stateful vs. Next-Gen Firewall – wann reicht was und wann nicht?
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Einleitung
&lt;/h2&gt;

&lt;p&gt;Firewalls sind ein essentielles Sicherheitsinstrument in jedem Netzwerk. Sie dienen dazu, unerwünschten Datenverkehr zu blockieren und den Zugriff auf bestimmte Ressourcen zu kontrollieren. Im Laufe der Zeit haben sich Firewalls weiterentwickelt und es gibt nun verschiedene Arten von Firewalls, wie Stateful Firewalls und Next-Gen Firewalls. In diesem Artikel werden wir uns mit dem Thema Firewall-Tuning befassen und klären, wann Stateful Firewalls ausreichen und wann Next-Gen Firewalls notwendig sind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stateful Firewalls
&lt;/h2&gt;

&lt;p&gt;Stateful Firewalls sind die traditionellen Firewalls, die den Datenverkehr basierend auf den Zuständen von Verbindungen überwachen. Sie können dabei helfen, unerwünschten Datenverkehr zu blockieren und den Zugriff auf bestimmte Ressourcen zu kontrollieren. Ein Beispiel für eine Stateful Firewall ist die Cisco ASA. Mit der Cisco ASA kann man Regeln definieren, um bestimmte Protokolle oder Ports zu blockieren.&lt;/p&gt;

&lt;p&gt;Meine Einschätzung: Stateful Firewalls sind eine gute Wahl, wenn man einfachen Datenverkehr überwachen möchte. Sie sind jedoch nicht in der Lage, komplexere Angriffe wie Malware oder Advanced Persistent Threats (APTs) zu erkennen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next-Gen Firewalls
&lt;/h2&gt;

&lt;p&gt;Next-Gen Firewalls sind eine Weiterentwicklung der Stateful Firewalls. Sie bieten zusätzliche Funktionen wie die Überwachung von Anwendungen, die Erkennung von Malware und die Kontrolle von Benutzern. Ein Beispiel für eine Next-Gen Firewall ist die Palo Alto Networks Firewall. Mit der Palo Alto Networks Firewall kann man Anwendungen überwachen und kontrollieren, welche Anwendungen auf bestimmte Ressourcen zugreifen dürfen.&lt;/p&gt;

&lt;p&gt;Ein weiteres Beispiel ist die Fortinet FortiGate Firewall. Mit der FortiGate Firewall kann man den Datenverkehr überwachen und erkennen, wenn bestimmte Anwendungen oder Protokolle verwendet werden.&lt;/p&gt;

&lt;p&gt;Meine Einschätzung: Next-Gen Firewalls sind eine gute Wahl, wenn man komplexere Angriffe wie Malware oder APTs erkennen möchte. Sie bieten zusätzliche Funktionen, um den Datenverkehr zu überwachen und zu kontrollieren.&lt;/p&gt;

&lt;h2&gt;
  
  
  Häufige Fehler / Fallstricke
&lt;/h2&gt;

&lt;p&gt;Ein häufiger Fehler bei der Konfiguration von Firewalls ist, dass die Regeln nicht korrekt definiert werden. Dies kann dazu führen, dass bestimmte Anwendungen oder Protokolle blockiert werden, obwohl sie benötigt werden. Ein weiterer Fehler ist, dass die Firewalls nicht regelmäßig aktualisiert werden, was dazu führen kann, dass bekannte Sicherheitslücken nicht geschlossen werden.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fazit
&lt;/h2&gt;

&lt;p&gt;In diesem Artikel haben wir uns mit dem Thema Firewall-Tuning befassen und geklärt, wann Stateful Firewalls ausreichen und wann Next-Gen Firewalls notwendig sind. Wir haben auch einige Beispiele für Stateful Firewalls und Next-Gen Firewalls gegeben und ihre Funktionen erläutert.&lt;/p&gt;

&lt;p&gt;Dein nächster Schritt sollte sein, deine Firewalls zu überprüfen und zu sehen, ob sie korrekt konfiguriert sind. Wenn du noch nicht über Next-Gen Firewalls verfügst, solltest du in Erwägung ziehen, sie zu implementieren, um deine Sicherheit zu verbessern.&lt;/p&gt;

&lt;h1&gt;
  
  
  Beispielkonfiguration
&lt;/h1&gt;

&lt;p&gt;Ein Beispiel für eine Konfiguration einer Stateful Firewall ist die folgende:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cisco_ios"&gt;&lt;code&gt;&lt;span class="k"&gt;access-list&lt;/span&gt; 101 &lt;span class="ow"&gt;permit&lt;/span&gt; ip any any
&lt;span class="k"&gt;access-list&lt;/span&gt; 102 &lt;span class="ow"&gt;deny&lt;/span&gt; ip any any
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dies definiert zwei Regeln: die erste Regel erlaubt allen Datenverkehr, die zweite Regel blockiert allen Datenverkehr.&lt;/p&gt;

&lt;p&gt;Ein Beispiel für eine Konfiguration einer Next-Gen Firewall ist die folgende:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;from-zone&lt;/span&gt; &lt;span class="nx"&gt;trust&lt;/span&gt; &lt;span class="nx"&gt;to-zone&lt;/span&gt; &lt;span class="nx"&gt;untrust&lt;/span&gt;
  &lt;span class="nx"&gt;source-address&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;
  &lt;span class="nx"&gt;destination-address&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;
  &lt;span class="nx"&gt;application&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;
  &lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="nx"&gt;allow&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dies definiert eine Regel, die allen Datenverkehr von der Trust-Zone in die Untrust-Zone erlaubt.&lt;/p&gt;

&lt;h1&gt;
  
  
  Tools und Produkte
&lt;/h1&gt;

&lt;p&gt;Einige Tools und Produkte, die für die Konfiguration und Überwachung von Firewalls verwendet werden können, sind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cisco ASA&lt;/li&gt;
&lt;li&gt;Palo Alto Networks Firewall&lt;/li&gt;
&lt;li&gt;Fortinet FortiGate Firewall&lt;/li&gt;
&lt;li&gt;Snort&lt;/li&gt;
&lt;li&gt;Suricata&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Meine Einschätzung: Diese Tools und Produkte sind sehr nützlich, um Firewalls zu konfigurieren und zu überwachen. Sie bieten eine Vielzahl von Funktionen, um den Datenverkehr zu überwachen und zu kontrollieren.&lt;/p&gt;

</description>
      <category>firewalltuning</category>
      <category>statefulfirewalls</category>
      <category>nextgenfirewalls</category>
      <category>netzwerksicherheit</category>
    </item>
    <item>
      <title>Proxmox HA-Cluster: Split‑Brain verhindern &amp; Quorum richtig konfigurieren</title>
      <dc:creator>Uhltak Therestismysecret</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:00:03 +0000</pubDate>
      <link>https://dev.to/uhltak/proxmox-ha-cluster-split-brain-verhindern-quorum-richtig-konfigurieren-m3l</link>
      <guid>https://dev.to/uhltak/proxmox-ha-cluster-split-brain-verhindern-quorum-richtig-konfigurieren-m3l</guid>
      <description>&lt;h2&gt;
  
  
  Hook – Warum ein HA-Cluster ohne Quorum wie ein wankender Turm ist
&lt;/h2&gt;

&lt;p&gt;Stellen Sie sich vor, Sie bauen ein Haus aus Holz und vergessen, die Balken zu verankern. Jeder Windstoß – ein ausgefallener Node – lässt das Dach knarren, und plötzlich diskutieren die Balken darüber, wer das Dach jetzt halten soll. Genau das passiert in einem Proxmox‑HA‑Cluster, wenn das Quorum nicht ordentlich konfiguriert ist: Split‑Brain, Datenverlust und nächtliche Schlaflosigkeit. In diesem Artikel zeige ich Ihnen, wie man das Fundament stabilisiert, das Quorum richtig einstellt und Split‑Brain praktisch aus dem Spiel nimmt – mit echten Befehlen, Konfigurationsbeispielen und meiner persönlichen Note nach jedem Abschnitt.&lt;/p&gt;




&lt;h2&gt;
  
  
  Was ist ein Proxmox HA-Cluster und warum ist Quorum das Herzstück?
&lt;/h2&gt;

&lt;p&gt;Ein HA‑Cluster (High Availability) besteht aus mindestens drei physikalischen Nodes, die über Corosync (bzw. das integrierte Cluster‑Transport‑System) miteinander kommunizieren. Das &lt;strong&gt;Quorum&lt;/strong&gt; definiert, ab wann ein Konsens erreicht ist – das ist die Mindestzahl an Stimmen, die nötig ist, damit der Cluster Entscheidungen treffen darf (z. B. VM‑Migration, Neustart, Ressourcenfreigabe).&lt;/p&gt;

&lt;h3&gt;
  
  
  Beispiel 1 – Minimal‑Cluster mit drei Nodes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Auf jedem Node das Proxmox‑Paket installieren (Debian‑Basis)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; proxmox-ve

&lt;span class="c"&gt;# Auf dem ersten Node ein Cluster initialisieren&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;pvecm create my-ha-cluster

&lt;span class="c"&gt;# Auf den beiden anderen Nodes dem Cluster beitreten&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;pvecm add &amp;lt;IP_DES_MASTER_NODES&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nachdem die drei Nodes im Cluster sind, kann man den aktuellen Quorum‑Status prüfen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pvecm status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Die Ausgabe zeigt u. a. &lt;code&gt;Quorum: 2&lt;/code&gt; (bei drei Nodes = 2 Stimmen). Wenn ein Node ausfällt, bleibt das Quorum erhalten, weil 2 / 3 noch &amp;gt; 50 % sind.&lt;/p&gt;

&lt;h4&gt;
  
  
  Persönliche Einschätzung
&lt;/h4&gt;

&lt;p&gt;In der Praxis setze ich selten mehr als drei Nodes, weil der administrative Overhead sonst exponentiell wächst. Drei Nodes geben bereits das notwendige 2‑of‑3‑Quorum, das ich in produktiven Umgebungen als „Goldstandard“ betrachte. Wer mehr Skalierung braucht, sollte aber von Anfang an ein ungerades × Node‑Layout planen.&lt;/p&gt;




&lt;h2&gt;
  
  
  Split‑Brain: Das Monster im Cluster
&lt;/h2&gt;

&lt;p&gt;Split‑Brain entsteht, wenn zwei (oder mehr) Teilgruppen des Clusters unabhängig voneinander denken, sie hätten das Quorum. Das Ergebnis? Doppelter Start derselben VM, inkonsistente Daten und ein wahnsinniges Debugging‑marathon.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beispiel 2 – Simulierter Netzwerk‑Partition
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Auf Node 1 das Netzwerk für 30 Sekunden blockieren (simuliert ein Outage)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-s&lt;/span&gt; &amp;lt;IP_NODE2&amp;gt; &lt;span class="nt"&gt;-j&lt;/span&gt; DROP
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-s&lt;/span&gt; &amp;lt;IP_NODE3&amp;gt; &lt;span class="nt"&gt;-j&lt;/span&gt; DROP
&lt;span class="nb"&gt;sleep &lt;/span&gt;30
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-F&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Während dieser Zeit sehen Node 1 und Node 2 jeweils nur die anderen beiden Nodes. Wenn die Partition zufällig zu 2‑vs‑1 führt, kann Node 2 (mit 2 Stimmen) das Quorum behalten, während Node 1 glaubt, er habe das Quorum (1 Stimme, weil es seine eigene Stimme mitzählt). In manchen Fehlkonfigurationen akzeptiert Proxmox das &lt;em&gt;falsche&lt;/em&gt; Quorum und startet VMs auf beiden Partitionen – klassisches Split‑Brain.&lt;/p&gt;

&lt;h4&gt;
  
  
  Persönliche Einschätzung
&lt;/h4&gt;

&lt;p&gt;Ich habe in meinem Homelab bereits zwei Fälle erlebt, bei denen ein defekter Switch das gleiche Szenario ausgelöst hat. Das größte Learning: &lt;strong&gt;Netzwerk‑Redundanz&lt;/strong&gt; ist kein Nice‑to‑have, sondern ein Muss. Ohne redundante Switches und physische Pfade kann jedes einzelne Gerät das gesamte Cluster zum Stillstand bringen.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quorum richtig konfigurieren – Schritt für Schritt
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Corosync‑Konfiguration anpassen
&lt;/h3&gt;

&lt;p&gt;Die Datei &lt;code&gt;/etc/pve/corosync.conf&lt;/code&gt; steuert, wie Stimmen gezählt werden. Hier ein Minimal‑Beispiel für ein 3‑Node‑Cluster mit &lt;strong&gt;auto‑join&lt;/strong&gt; und &lt;strong&gt;vote‑weight&lt;/strong&gt;‑Einstellungen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="err"&gt;totem&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;version:&lt;/span&gt; &lt;span class="err"&gt;2&lt;/span&gt;
    &lt;span class="err"&gt;cluster_name:&lt;/span&gt; &lt;span class="err"&gt;my-ha-cluster&lt;/span&gt;
    &lt;span class="err"&gt;token:&lt;/span&gt; &lt;span class="err"&gt;3000&lt;/span&gt;
    &lt;span class="err"&gt;token_retransmits_before_loss_const:&lt;/span&gt; &lt;span class="err"&gt;10&lt;/span&gt;
    &lt;span class="err"&gt;join:&lt;/span&gt; &lt;span class="err"&gt;60&lt;/span&gt;
    &lt;span class="err"&gt;interface&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="err"&gt;ringnumber:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;
        &lt;span class="err"&gt;bindnetaddr:&lt;/span&gt; &lt;span class="err"&gt;10.0.0.0&lt;/span&gt;
        &lt;span class="err"&gt;mcastaddr:&lt;/span&gt; &lt;span class="err"&gt;239.255.1.1&lt;/span&gt;
        &lt;span class="err"&gt;mcastport:&lt;/span&gt; &lt;span class="err"&gt;5405&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;quorum&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;provider:&lt;/span&gt; &lt;span class="err"&gt;corosync_votequorum&lt;/span&gt;
    &lt;span class="err"&gt;two_node:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;   &lt;span class="c"&gt;# 0 = klassisches Quorum, 1 = Two‑Node‑Modus
&lt;/span&gt;    &lt;span class="err"&gt;wait_for_all:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;
    &lt;span class="err"&gt;expected_votes:&lt;/span&gt; &lt;span class="err"&gt;3&lt;/span&gt;
    &lt;span class="err"&gt;last_man_standing:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="err"&gt;nodelist&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;node&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="err"&gt;nodeid:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;
        &lt;span class="err"&gt;quorum_votes:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;
        &lt;span class="err"&gt;name:&lt;/span&gt; &lt;span class="err"&gt;node1&lt;/span&gt;
        &lt;span class="err"&gt;address:&lt;/span&gt; &lt;span class="err"&gt;10.0.0.1&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;
    &lt;span class="err"&gt;node&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="err"&gt;nodeid:&lt;/span&gt; &lt;span class="err"&gt;2&lt;/span&gt;
        &lt;span class="err"&gt;quorum_votes:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;
        &lt;span class="err"&gt;name:&lt;/span&gt; &lt;span class="err"&gt;node2&lt;/span&gt;
        &lt;span class="err"&gt;address:&lt;/span&gt; &lt;span class="err"&gt;10.0.0.2&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;
    &lt;span class="err"&gt;node&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="err"&gt;nodeid:&lt;/span&gt; &lt;span class="err"&gt;3&lt;/span&gt;
        &lt;span class="err"&gt;quorum_votes:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;
        &lt;span class="err"&gt;name:&lt;/span&gt; &lt;span class="err"&gt;node3&lt;/span&gt;
        &lt;span class="err"&gt;address:&lt;/span&gt; &lt;span class="err"&gt;10.0.0.3&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Wichtig&lt;/em&gt;: &lt;code&gt;expected_votes&lt;/code&gt; muss die tatsächliche Anzahl der Nodes widerspiegeln. Wenn Sie später einen Node hinzufügen, passen Sie den Wert an und starten Sie Corosync neu:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl restart corosync
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. STONITH (Shoot‑The‑Other‑Node‑In‑The‑Head) aktivieren
&lt;/h3&gt;

&lt;p&gt;Fencing ist die sicherste Methode, um Split‑Brain zu verhindern: Wenn ein Node seine Verbindung verliert, wird er automatisch ausgeschaltet, sodass er nicht mehr konkurrieren kann.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Beispiel: IPMI‑basiertes Fencing über iLO (Dell) oder iDRAC (HP)&lt;/span&gt;
&lt;span class="c"&gt;# Installiere das Fence-Agent-Paket&lt;/span&gt;
apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; fence-agents

&lt;span class="c"&gt;# Erstelle eine neue Fencing‑Resource in Proxmox&lt;/span&gt;
pveum roleadd FencingAdmin &lt;span class="nt"&gt;-privs&lt;/span&gt; &lt;span class="s2"&gt;"SDN.Modify,Datacenter.Audit"&lt;/span&gt;

&lt;span class="c"&gt;# Konfiguration in /etc/pve/fence.cfg (einfaches Beispiel)&lt;/span&gt;
node: node1
fence_type: ipmi
ipaddr: 192.168.1.100
login: admin
passwd: secret
port: 623
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Danach testen Sie das Fencing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Simulierter Power‑Off von node2&lt;/span&gt;
fence_ipmilan &lt;span class="nt"&gt;-a&lt;/span&gt; 192.168.1.101 &lt;span class="nt"&gt;-l&lt;/span&gt; admin &lt;span class="nt"&gt;-p&lt;/span&gt; secret &lt;span class="nt"&gt;-o&lt;/span&gt; off
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wenn das Fencing funktioniert, wird das Quorum sofort neu berechnet und Split‑Brain kann nicht auftreten.&lt;/p&gt;

&lt;h4&gt;
  
  
  Persönliche Einschätzung
&lt;/h4&gt;

&lt;p&gt;Ich habe die Erfahrung gemacht, dass &lt;strong&gt;kein&lt;/strong&gt; Cluster ohne funktionierendes Fencing überlebt. Selbst bei einem 3‑Node‑Setup reicht es nicht, sich auf das reine Corosync‑Quorum zu verlassen – ein kurzzeitig ausgefallener Netzwerk‑Port würde sonst sofort zu Split‑Brain führen.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Quorum‑Monitoring automatisieren
&lt;/h3&gt;

&lt;p&gt;Ein kurzer Cron‑Job, der den Quorum‑Status prüft und bei Problemen Alarm schlägt, spart Stunden Debugging‑Zeit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# /usr/local/bin/check_quorum.sh&lt;/span&gt;
&lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;pvecm status | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; quorum | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$status&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; 2 &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[WARN] Quorum-Problem! aktuelle Stimmen: &lt;/span&gt;&lt;span class="nv"&gt;$status&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | mail &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"Proxmox Quorum Alert"&lt;/span&gt; admin@example.com
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mit &lt;code&gt;chmod +x&lt;/code&gt; und &lt;code&gt;crontab -e&lt;/code&gt; hinzufügen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*/5 * * * * /usr/local/bin/check_quorum.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jetzt erhalten Sie alle 5 Minuten ein Status‑Mail, falls das Quorum unter das gewünschte Niveau fällt.&lt;/p&gt;




&lt;h2&gt;
  
  
  Fünf praktische Tipps, um Split‑Brain zu vermeiden
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Odd‑Number‑Node‑Layout&lt;/strong&gt; – immer eine ungerade Anzahl von Nodes einsetzen (3, 5, 7). Das garantiert, dass ein eindeutiges Quorum existiert.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redundante Netzwerk‑Links&lt;/strong&gt; – mindestens zwei physische Switches, idealerweise mit LACP (Link‑Aggregation). So verhindern Sie, dass ein einzelner Kabeldefekt das gesamte Cluster zerschlägt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;STONITH zwingend aktivieren&lt;/strong&gt; – ohne Fencing gibt es keine Garantie, dass ein gesperrter Node nicht wieder aktiv wird.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quorum‑Meldungen zentral sammeln&lt;/strong&gt; – nutzen Sie Prometheus + Alertmanager (oder Zabbix) und visualisieren Sie den &lt;code&gt;pvecm status&lt;/code&gt;‑Wert.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regelmäßige Tests&lt;/strong&gt; – führen Sie halbjährlich ein geplantes Netzwerk‑Failover‑Test aus, um zu prüfen, ob das Quorum korrekt nachzieht.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Persönliche Einschätzung
&lt;/h4&gt;

&lt;p&gt;Die meisten split‑brain‑Incidents, die ich in den letzten fünf Jahren beobachtete, waren das Ergebnis von &lt;strong&gt;einer&lt;/strong&gt; vernachlässigten Maßnahme: entweder ein vergessenes STONITH‑Device oder ein Switch‑Ausfall ohne Backup‑Link. Ein konsequenter Check‑list‑Ansatz reduziert das Risiko auf ein Minimum.&lt;/p&gt;




&lt;h2&gt;
  
  
  Häufige Fehler beim Aufbau eines Proxmox HA‑Clusters
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fehler&lt;/th&gt;
&lt;th&gt;Warum er passiert&lt;/th&gt;
&lt;th&gt;Konsequenz&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;expected_votes&lt;/code&gt; zu niedrig gesetzt&lt;/td&gt;
&lt;td&gt;Man vergaß, den Wert nach Hinzufügen eines Nodes zu ändern&lt;/td&gt;
&lt;td&gt;Quorum fällt sofort, Cluster bleibt offline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kein Fencing‑Device definiert&lt;/td&gt;
&lt;td&gt;Annahme, dass Corosync ausreicht&lt;/td&gt;
&lt;td&gt;Split‑Brain bei Netzwerk‑Partition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nur ein physischer Switch&lt;/td&gt;
&lt;td&gt;Kosteneinsparung überbewertet&lt;/td&gt;
&lt;td&gt;Single‑Point‑Of‑Failure → totaler Cluster‑Ausfall&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nutzung von &lt;code&gt;two_node: 1&lt;/code&gt; in einem 3‑Node‑Setup&lt;/td&gt;
&lt;td&gt;Misinterpretation der Dokumentation&lt;/td&gt;
&lt;td&gt;Quorum‑Logik bricht zusammen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keine Monitoring‑Alerts&lt;/td&gt;
&lt;td&gt;Blindes Vertrauen auf &lt;code&gt;pvecm status&lt;/code&gt; im Terminal&lt;/td&gt;
&lt;td&gt;Late‑Stage‑Failure, lange Downtime&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Fazit – Ihr nächster, konkreter Schritt
&lt;/h2&gt;

&lt;p&gt;Der sicherste Weg, ein Proxmox‑HA‑Cluster zu betreiben, ist, &lt;strong&gt;Quorum&lt;/strong&gt; und &lt;strong&gt;Fencing&lt;/strong&gt; als untrennbare Einheit zu behandeln. Wenn Sie gerade erst ansetzen, gehen Sie wie folgt vor:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cluster initialisieren&lt;/strong&gt; (&lt;code&gt;pvecm create&lt;/code&gt;) und exakt die gewünschte Anzahl an Nodes anlegen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Corosync‑Config&lt;/strong&gt; anpassen – &lt;code&gt;expected_votes&lt;/code&gt; = Anzahl der Nodes, &lt;code&gt;two_node&lt;/code&gt; = 0.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fencing‑Device&lt;/strong&gt; einrichten (IPMI, iLO, iDRAC) und testen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring‑Job&lt;/strong&gt; (&lt;code&gt;check_quorum.sh&lt;/code&gt;) implementieren.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Netzwerk‑Redundanz&lt;/strong&gt; prüfen – mindestens zwei Switches, LACP‑Bundle.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Durch das Befolgen dieser fünf Punkte stellen Sie sicher, dass Ihr Cluster nie wieder in ein Split‑Brain‑Szenario gerät und dass das Quorum stets stabil bleibt. Jetzt liegt es an Ihnen: Öffnen Sie die Shell, überprüfen Sie &lt;code&gt;pvecm status&lt;/code&gt; und starten Sie das erste HA‑Test‑VM‑Migrieren. Sobald das funktioniert, haben Sie einen echten, ausfallsicheren Proxmox‑Cluster in Betrieb.&lt;/p&gt;

</description>
      <category>proxmox</category>
      <category>hacluster</category>
      <category>quorum</category>
      <category>splitbrain</category>
    </item>
    <item>
      <title>Firewall-Tuning: Stateful vs. Next-Gen - Die Wahl des Richtigen</title>
      <dc:creator>Uhltak Therestismysecret</dc:creator>
      <pubDate>Thu, 13 Aug 2026 06:00:04 +0000</pubDate>
      <link>https://dev.to/uhltak/firewall-tuning-stateful-vs-next-gen-die-wahl-des-richtigen-3k3l</link>
      <guid>https://dev.to/uhltak/firewall-tuning-stateful-vs-next-gen-die-wahl-des-richtigen-3k3l</guid>
      <description>&lt;h1&gt;
  
  
  Firewall-Tuning: Stateful vs. Next-Gen Firewall – Die Wahl des Richtigen
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Einleitung
&lt;/h2&gt;

&lt;p&gt;Die Wahl der richtigen Firewall-Technologie ist entscheidend für die Sicherheit Ihres Netzwerks. Stateful Firewalls und Next-Gen Firewalls sind zwei gängige Optionen, aber wann reicht die eine und wann braucht man die andere? In diesem Artikel werden wir diese Frage beantworten und Ihnen konkrete Beispiele und Tool-Namen an die Hand geben.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stateful Firewalls
&lt;/h2&gt;

&lt;p&gt;Stateful Firewalls sind die traditionelle Wahl für die Netzwerksicherheit. Sie überwachen den Zustand von Verbindungen und entscheiden, ob ein Paket durchgelassen wird oder nicht. Stateful Firewalls sind einfach zu konfigurieren und reichen oft aus, um grundlegende Angriffe abzuwehren.&lt;/p&gt;

&lt;p&gt;Beispiel: Die Cisco ASA-Serie ist ein beliebtes Beispiel für Stateful Firewalls. Mit dem Befehl &lt;code&gt;show conn&lt;/code&gt; kann man die aktuellen Verbindungen überwachen und mit &lt;code&gt;access-list&lt;/code&gt; die Regelwerke konfigurieren.&lt;/p&gt;

&lt;p&gt;Meine Einschätzung: Stateful Firewalls sind ein guter Anfang, aber sie reichen oft nicht aus, um moderne Angriffe abzuwehren. Sie sind jedoch einfach zu konfigurieren und bieten eine gute Grundlage für die Netzwerksicherheit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next-Gen Firewalls
&lt;/h2&gt;

&lt;p&gt;Next-Gen Firewalls sind die moderne Wahl für die Netzwerksicherheit. Sie bieten erweiterte Funktionen wie Deep Packet Inspection, SSL/TLS-Entschlüsselung und Sandboxing. Next-Gen Firewalls sind komplexer zu konfigurieren, aber sie bieten einen umfassenderen Schutz gegen moderne Angriffe.&lt;/p&gt;

&lt;p&gt;Beispiel: Die Palo Alto Networks-Plattform ist ein beliebtes Beispiel für Next-Gen Firewalls. Mit dem Tool &lt;code&gt;panorama&lt;/code&gt; kann man die Konfiguration und Überwachung der Firewalls zentralisieren und mit &lt;code&gt;App-ID&lt;/code&gt; die Anwendungen identifizieren.&lt;/p&gt;

&lt;p&gt;Meine Einschätzung: Next-Gen Firewalls sind die bessere Wahl, wenn man einen umfassenden Schutz gegen moderne Angriffe benötigt. Sie sind jedoch komplexer zu konfigurieren und erfordern eine umfassende Kenntnis der Netzwerksicherheit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Häufige Fehler / Fallstricke
&lt;/h2&gt;

&lt;p&gt;Ein häufiger Fehler bei der Konfiguration von Firewalls ist die fehlende Überwachung der Regelwerke. Es ist wichtig, regelmäßig die Regelwerke zu überprüfen und anzupassen, um sicherzustellen, dass sie noch aktuell sind.&lt;/p&gt;

&lt;p&gt;Ein weiterer Fallstrick ist die Verwendung von zu vielen Regelwerken. Zu viele Regelwerke können die Leistung der Firewall beeinträchtigen und es schwieriger machen, die Konfiguration zu überwachen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fazit
&lt;/h2&gt;

&lt;p&gt;Die Wahl der richtigen Firewall-Technologie ist entscheidend für die Sicherheit Ihres Netzwerks. Stateful Firewalls reichen oft aus, um grundlegende Angriffe abzuwehren, aber Next-Gen Firewalls bieten einen umfassenderen Schutz gegen moderne Angriffe. Es ist wichtig, die Konfiguration der Firewalls regelmäßig zu überprüfen und anzupassen, um sicherzustellen, dass sie noch aktuell sind.&lt;/p&gt;

&lt;p&gt;Dein nächster Schritt: Überprüfe die Konfiguration deiner Firewalls und entscheide, ob du Stateful Firewalls oder Next-Gen Firewalls benötigst. Wenn du unsicher bist, zögere nicht, einen Experten zu konsultieren.&lt;/p&gt;

</description>
      <category>firewalltuning</category>
      <category>statefulfirewalls</category>
      <category>nextgenfirewalls</category>
      <category>netzwerksicherheit</category>
    </item>
    <item>
      <title>Landlock LSM verstehen: Sandbox‑Security im Linux‑Kernel ohne Root‑Rechte</title>
      <dc:creator>Uhltak Therestismysecret</dc:creator>
      <pubDate>Wed, 12 Aug 2026 18:00:04 +0000</pubDate>
      <link>https://dev.to/uhltak/landlock-lsm-verstehen-sandbox-security-im-linux-kernel-ohne-root-rechte-k8o</link>
      <guid>https://dev.to/uhltak/landlock-lsm-verstehen-sandbox-security-im-linux-kernel-ohne-root-rechte-k8o</guid>
      <description>&lt;h1&gt;
  
  
  Warum Landlock jetzt wichtiger ist als je zuvor
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;"Ich habe meinem Lieblings‑Editor gerade ein Rechte‑Upgrade verpasst – und das war kein Versehen, sondern ein Feature.&lt;/em&gt;" Das ist kein Scherz, sondern ein Szenario, das mir beim Aufsetzen von Entwicklungsumgebungen im Home‑Lab mehrfach passiert ist. Ich habe mich gefragt: &lt;strong&gt;Wie kann ich eine Anwendung so einschränken, dass sie niemals außerhalb ihres definierten Dateibaums operieren kann – und das ohne das System‑Root zu betreten?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Die Antwort lautet &lt;strong&gt;Landlock LSM&lt;/strong&gt; – ein Linux‑Security‑Modul, das im Kernel verankert ist und &lt;em&gt;Sandboxing&lt;/em&gt; auf Prozess‑Basis ermöglicht, ohne dass man root‑Privilegien benötigt. In diesem Beitrag zeige ich Ihnen, warum Landlock die nächste Evolution von App‑Containern ist, wie Sie es in drei konkreten Schritten aktivieren und einsetzen, und welche Stolperfallen Sie vermeiden sollten.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Was ist Landlock LSM?
&lt;/h2&gt;

&lt;p&gt;Landlock ist seit Linux 5.13 ein &lt;strong&gt;Linux‑Security‑Module (LSM)&lt;/strong&gt;, das auf &lt;em&gt;Capability‑based&lt;/em&gt; Isolation setzt. Anders als AppArmor oder SELinux, die typischerweise im Kernel konfiguriert und mit root‑Rechten geladen werden, erlaubt Landlock &lt;strong&gt;unprivilegierten Prozessen&lt;/strong&gt;, eigene Sicherheits‑Policies zu definieren – und zwar &lt;em&gt;nachträglich&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kein Root nötig&lt;/strong&gt;: Jeder User kann eine Policy erstellen, solange die Kernel‑Konfiguration &lt;code&gt;CONFIG_SECURITY_LANDLOCK=y&lt;/code&gt; gesetzt ist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Granulare Rechte&lt;/strong&gt;: Sie bestimmen exakt, welche Pfade, welche Dateitypen und welche Operationen (read, write, create, exec) erlaubt sind.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kompatibilitäts‑Boost&lt;/strong&gt;: Landlock wirkt &lt;em&gt;additiv&lt;/em&gt; zu bestehenden LSMs. Wenn Sie bereits SELinux laufen haben, bleibt das unverändert; Landlock ergänzt nur.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Persönliche Einschätzung:&lt;/strong&gt; Für den täglichen Administrator, der bereits Docker‑ oder LXC‑Umgebungen nutzt, bedeutet Landlock keinen kompletten Paradigmenwechsel, sondern einen zusätzlichen, leichtgewichtigen Baustein für „Zero‑Trust‑Auf‑lokaler‑Ebene“.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Erste Schritte – Landlock im Kernel aktivieren
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hinweis:&lt;/strong&gt; Die folgenden Befehle setzen voraus, dass Ihr Kernel 5.13+ enthält und das Landlock‑Feature in der Konfiguration aktiv ist. Die meisten modernen Distributionen (Ubuntu 22.04 LTS, Debian 12, Fedora 38) haben das bereits eingebaut.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2.1. Prüfen, ob Landlock aktiv ist
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Zeigt, ob das LSM geladen ist (erwartet "Y")&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /sys/kernel/security/lsm | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;landlock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wenn das Ergebnis leer ist, starten Sie den Kernel mit &lt;code&gt;lsm=landlock&lt;/code&gt; in der Boot‑Zeile oder aktivieren Sie es in &lt;code&gt;/etc/default/grub&lt;/code&gt; und führen Sie &lt;code&gt;sudo update-grub &amp;amp;&amp;amp; sudo reboot&lt;/code&gt; aus.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2. Minimal‑Policy für einen Prozess erstellen
&lt;/h3&gt;

&lt;p&gt;Landlock wird über das &lt;strong&gt;&lt;code&gt;landlockctl&lt;/code&gt;&lt;/strong&gt;‑Tool (aus dem &lt;code&gt;libc&lt;/code&gt;‑Bundle) oder über Bibliotheken wie &lt;strong&gt;&lt;code&gt;landlock-rs&lt;/code&gt;&lt;/strong&gt; gesteuert. Wir demonstrieren das native C‑Beispiel, weil es keine zusätzlichen Pakete erfordert.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define _GNU_SOURCE
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;landlock.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;fcntl.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* 1. Policy anlegen: nur Lese‑Zugriff auf /etc/hosts */&lt;/span&gt;
    &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;landlock_ruleset_attr&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handled_access_fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LANDLOCK_ACCESS_FS_READ_FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ruleset_fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;landlock_create_ruleset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ruleset_fd&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cm"&gt;/* 2. Regel hinzufügen */&lt;/span&gt;
    &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;landlock_path_beneath_attr&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;allowed_access&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LANDLOCK_ACCESS_FS_READ_FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parent_fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/etc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O_PATH&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O_CLOEXEC&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="n"&gt;landlock_add_rule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ruleset_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LANDLOCK_RULE_PATH_BENEATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="cm"&gt;/* 3. Policy aktivieren */&lt;/span&gt;
    &lt;span class="n"&gt;landlock_restrict_self&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ruleset_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/* Test: Versuche /etc/hosts zu lesen – funktioniert */&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/etc/hosts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O_RDONLY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/* Test: Versuche /etc/passwd zu lesen – verweigert */&lt;/span&gt;
    &lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/etc/passwd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O_RDONLY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"blocked"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kompilieren und ausführen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcc &lt;span class="nt"&gt;-o&lt;/span&gt; landlock_demo landlock_demo.c &lt;span class="nt"&gt;-llandlock&lt;/span&gt;
./landlock_demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sie sehen die Fehlermeldung &lt;code&gt;blocked: Permission denied&lt;/code&gt; für &lt;code&gt;/etc/passwd&lt;/code&gt;. &lt;strong&gt;Erste Erfolgsgeschichte:&lt;/strong&gt; Ohne ein einziges &lt;code&gt;sudo&lt;/code&gt;‑Kommando hat ein normaler Nutzer die Dateizugriffe seiner Anwendung eingeschränkt.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3. Schnellstart mit &lt;code&gt;landlockctl&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Viele wollen nicht selbst coden, sondern ein Command‑Line‑Interface. Das Paket &lt;strong&gt;&lt;code&gt;landlock-tools&lt;/code&gt;&lt;/strong&gt; (Ubuntu/Debian) liefert &lt;code&gt;landlockctl&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Policy: Nur Schreibzugriff in ~/sandbox erlauben&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/sandbox
landlockctl new &lt;span class="nt"&gt;--fs-write&lt;/span&gt; ~/sandbox &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; policy.bin
&lt;span class="c"&gt;# Prozess starten und Policy anhängen&lt;/span&gt;
landlockctl apply ./my_app policy.bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jetzt kann &lt;code&gt;my_app&lt;/code&gt; ausschließlich in &lt;code&gt;~/sandbox&lt;/code&gt; schreiben – jeder Versuch, außerhalb zu schreiben, endet in &lt;code&gt;EACCES&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Persönliche Einschätzung:&lt;/strong&gt; Der CLI‑Ansatz ist ideal für &lt;em&gt;einmalige&lt;/em&gt; Scripting‑Aufgaben (z. B. beim automatisierten Testen von Build‑Tools). Für langfristige Projekte empfehle ich jedoch ein &lt;strong&gt;Wrapper‑Programm&lt;/strong&gt;, das die Policy beim Starten Ihrer Applikation automatisch erzeugt.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Praktische Beispiele – Landlock in der realen IT‑Umgebung
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1. Sicherer Build‑Container ohne Docker
&lt;/h3&gt;

&lt;p&gt;Stellen Sie sich vor, Sie wollen ein &lt;strong&gt;Make‑Projekt&lt;/strong&gt; bauen, das jedoch nicht auf das gesamte Dateisystem zugreifen darf. Statt Docker‑Image zu bauen, verwenden Sie Landlock, um das Build‑Verzeichnis zu isolieren.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Verzeichnisstruktur anlegen&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /tmp/build-src /tmp/build-out
&lt;span class="c"&gt;# 2. Kopieren Sie den Quellcode (nur lesend)&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; /home/me/projekt/&lt;span class="k"&gt;*&lt;/span&gt; /tmp/build-src/
&lt;span class="c"&gt;# 3. Policy erstellen (Lesen in src, Schreiben in out)&lt;/span&gt;
landlockctl new &lt;span class="nt"&gt;--fs-read&lt;/span&gt; /tmp/build-src &lt;span class="nt"&gt;--fs-write&lt;/span&gt; /tmp/build-out &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; build.policy
&lt;span class="c"&gt;# 4. Build‑Tool starten&lt;/span&gt;
landlockctl apply make &lt;span class="nt"&gt;-C&lt;/span&gt; /tmp/build-src &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; build.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ergebnis: Der Build‑Prozess kann &lt;strong&gt;nur&lt;/strong&gt; in &lt;code&gt;/tmp/build-out&lt;/code&gt; schreiben. Jegliche Versuche, z. B. &lt;code&gt;~/.ssh/id_rsa&lt;/code&gt; zu lesen, schlagen fehl – ein klarer Sicherheitsgewinn gegenüber einem vollen Docker‑Root‑Filesystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2. Beschränken von Skripten im CI‑Runner
&lt;/h3&gt;

&lt;p&gt;CI‑Server wie GitLab‑Runner laufen häufig als &lt;code&gt;gitlab-runner&lt;/code&gt;‑User. Mit Landlock können Sie sicherstellen, dass ein Pipeline‑Job &lt;strong&gt;keine&lt;/strong&gt; sensiblen Systemverzeichnisse berührt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .gitlab-ci.yml (Auszug)&lt;/span&gt;
&lt;span class="na"&gt;job_secure&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;landlockctl new --fs-read $CI_PROJECT_DIR --fs-write $CI_PROJECT_DIR/tmp &amp;gt; /tmp/policy.bin&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;landlockctl apply ./run_tests.sh /tmp/policy.bin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Damit wird jede Ausführung von &lt;code&gt;run_tests.sh&lt;/code&gt; auf das Projekt‑Verzeichnis begrenzt. Selbst wenn ein bösartiger Test versucht, &lt;code&gt;/etc/shadow&lt;/code&gt; zu lesen, blockiert Landlock den Aufruf.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3. Beschränken von Drittanbieter‑Binaries (z. B. &lt;code&gt;ffmpeg&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Viele Unternehmen nutzen &lt;strong&gt;&lt;code&gt;ffmpeg&lt;/code&gt;&lt;/strong&gt; zum Transkodieren von Medien. Ein häufiger Angreifer‑Vektor ist das Einschleusen von schädlichen Media‑Dateien, die über &lt;code&gt;ffmpeg&lt;/code&gt; System‑Aufrufe ausführen. Mit Landlock können Sie &lt;code&gt;ffmpeg&lt;/code&gt; &lt;strong&gt;nur&lt;/strong&gt; Schreibzugriff in ein Ausgabeverzeichnis gewähren.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /var/tmp/ffmpeg-out
landlockctl new &lt;span class="nt"&gt;--fs-read&lt;/span&gt; /var/media/in &lt;span class="nt"&gt;--fs-write&lt;/span&gt; /var/tmp/ffmpeg-out &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ffmpeg.policy
landlockctl apply ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; /var/media/in/video.mkv &lt;span class="nt"&gt;-c&lt;/span&gt;:v libx264 /var/tmp/ffmpeg-out/video.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jetzt kann &lt;code&gt;ffmpeg&lt;/code&gt; ausschließlich in &lt;code&gt;/var/tmp/ffmpeg-out&lt;/code&gt; schreiben – jede Manipulation, die versucht, &lt;code&gt;/tmp&lt;/code&gt; oder &lt;code&gt;/etc&lt;/code&gt; zu beschreiben, schlägt fehl.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Persönliche Einschätzung:&lt;/strong&gt; Diese drei Beispiele zeigen, dass Landlock nicht nur ein "nice‑to‑have"‑Feature ist, sondern &lt;strong&gt;konkrete Risiko‑Reduktion&lt;/strong&gt; bietet, ohne dass Sie die Komplexität von vollwertigen Containern tragen müssen.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Bewertung und persönliche Einschätzung
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance:&lt;/strong&gt; Landlock ist ein &lt;strong&gt;Kernel‑Feature&lt;/strong&gt;, das keine extra‑User‑Space‑Prozesse wie &lt;code&gt;docker daemon&lt;/code&gt; einsetzt. Der Overhead liegt typischerweise im einstelligen Prozentbereich – messbar z. B. mit &lt;code&gt;perf stat&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kompatibilität:&lt;/strong&gt; Da es als zusätzlicher LSM arbeitet, kollidiert es nicht mit SELinux/AppArmor. Das bedeutet, Sie können es schrittweise einführen, ohne bestehende Policies zu brechen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bedienbarkeit:&lt;/strong&gt; Für Entwickler ist das API‑Level (C, Rust, Go) recht niedrig. Die CLI‑Tools sind momentan noch &lt;strong&gt;experimentell&lt;/strong&gt;, daher empfehle ich, ein eigenes Wrapper‑Skript zu schreiben, das &lt;code&gt;landlockctl&lt;/code&gt; oder die Bibliothek nutzt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sicherheits‑Gewinn:&lt;/strong&gt; Der größte Nutzen liegt im &lt;strong&gt;Zero‑Trust‑Modell&lt;/strong&gt; auf lokaler Ebene: Selbst wenn ein Prozess root‑Rechte erlangen kann (z. B. durch ein priviligiertes Set‑UID‑Binary), bleibt die Landlock‑Policy wirksam, solange der Prozess sie bereits aktivierte.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Mein Fazit:&lt;/strong&gt; Landlock ist ein unterschätztes Werkzeug, das besonders für &lt;em&gt;DevOps‑Teams&lt;/em&gt; und &lt;em&gt;Sicherheits‑Engineers&lt;/em&gt; relevant ist, die nach einer &lt;strong&gt;leichtgewichtigen Alternative&lt;/strong&gt; zu Container‑Umgebungen suchen. Es ist nicht die Allzwecklösung für alle Isolation‑Bedürfnisse, aber für &lt;strong&gt;Dateisystem‑Sandboxing&lt;/strong&gt; ist es unschlagbar einfach und effizient.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Häufige Fehler, die Sie vermeiden sollten
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fehler&lt;/th&gt;
&lt;th&gt;Warum er problematisch ist&lt;/th&gt;
&lt;th&gt;Korrektur&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Landlock vor dem Kernel aktivieren&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ohne &lt;code&gt;CONFIG_SECURITY_LANDLOCK=y&lt;/code&gt; gibt es keine Policy‑API.&lt;/td&gt;
&lt;td&gt;Prüfen Sie &lt;code&gt;/sys/kernel/security/lsm&lt;/code&gt; &lt;strong&gt;vor&lt;/strong&gt; dem ersten Test.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Policy zu breit definieren&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Wenn Sie &lt;code&gt;LANDLOCK_ACCESS_FS_ALL&lt;/code&gt; erlauben, neutralisiert das Sandbox‑Prinzip.&lt;/td&gt;
&lt;td&gt;Beschränken Sie nur die tatsächlich benötigten Operationen (READ, WRITE, EXEC).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Policy nach dem Prozesslauf erstellen&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Landlock wirkt nur &lt;strong&gt;nach&lt;/strong&gt; &lt;code&gt;landlock_restrict_self&lt;/code&gt;. Nachträglich hinzugefügte Regeln haben keinen Effekt.&lt;/td&gt;
&lt;td&gt;Policy immer &lt;strong&gt;vor&lt;/strong&gt; dem Haupt‑Workload laden.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Verlassen auf &lt;code&gt;landlockctl&lt;/code&gt; allein&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Das Tool ist noch in &lt;em&gt;alpha&lt;/em&gt; und unterstützt nicht alle Rule‑Typen.&lt;/td&gt;
&lt;td&gt;Für produktive Systeme eigene Wrapper‑Binary nutzen oder die &lt;code&gt;landlock-rs&lt;/code&gt;‑Bibliothek einbinden.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Nicht‑Persistenz von Policies&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Policies werden nur im Prozess‑Speicher gehalten, gehen beim Neustart verloren.&lt;/td&gt;
&lt;td&gt;Speichern Sie die Binär‑Datei (&lt;code&gt;policy.bin&lt;/code&gt;) und laden Sie sie beim Service‑Start erneut.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  6. Fazit und konkreter nächster Schritt
&lt;/h2&gt;

&lt;p&gt;Landlock ermöglicht &lt;strong&gt;Sandbox‑Security&lt;/strong&gt; im Kernel, ohne dass Sie Root‑Rechte benötigen. Das bedeutet für Sie:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sofortige Risiko‑Reduktion&lt;/strong&gt; – beschränken Sie Dateizugriffe von unsicheren Binärdateien.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geringer Overhead&lt;/strong&gt; – keine zusätzliche Daemon‑Schicht, reine Kernel‑Mechanik.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Einfacher Einstieg&lt;/strong&gt; – &lt;code&gt;landlockctl&lt;/code&gt; oder ein kurzes C‑/Rust‑Programm bringen Sie in Minuten ans Ziel.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Ihr nächster To‑Do‑Plan (5‑Min‑Checklist)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Kernel‑Check:&lt;/strong&gt; &lt;code&gt;cat /sys/kernel/security/lsm | grep landlock&lt;/code&gt; → wenn leer, Boot‑Parameter &lt;code&gt;lsm=landlock&lt;/code&gt; hinzufügen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Policy‑Datei anlegen:&lt;/strong&gt; &lt;code&gt;landlockctl new --fs-read $HOME/project --fs-write $HOME/project/tmp &amp;gt; my.policy&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testen:&lt;/strong&gt; &lt;code&gt;landlockctl apply ./mein_script.sh my.policy&lt;/code&gt; und versuchen Sie, außerhalb zu schreiben – Erfolg!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatisieren:&lt;/strong&gt; Schreiben Sie ein kleines Bash‑Wrapper‑Script, das beim Systemstart Ihre kritischen Services mit der jeweiligen Policy startet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring:&lt;/strong&gt; Loggen Sie &lt;code&gt;audit&lt;/code&gt;‑Events (&lt;code&gt;auditd&lt;/code&gt;) für &lt;code&gt;landlock&lt;/code&gt;‑Verstöße, um mögliche Fehlkonfigurationen zu entdecken.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Mit diesen Schritten sichern Sie Ihre Systeme &lt;strong&gt;lokal&lt;/strong&gt; – ein Baustein, der in einer zunehmend container‑ und cloud‑zentrierten Welt oft vergessen wird, aber immens wertvoll ist. Jetzt liegt es an Ihnen: Setzen Sie Landlock ein, bevor das nächste Zero‑Day‑Exploit Ihren Root‑Account erreicht.&lt;/p&gt;

</description>
      <category>landlock</category>
      <category>lsm</category>
      <category>sandboxing</category>
      <category>linuxsecurity</category>
    </item>
    <item>
      <title>Firewall-Tuning: Stateful vs. Next-Gen - Die richtige Wahl</title>
      <dc:creator>Uhltak Therestismysecret</dc:creator>
      <pubDate>Wed, 12 Aug 2026 06:00:03 +0000</pubDate>
      <link>https://dev.to/uhltak/firewall-tuning-stateful-vs-next-gen-die-richtige-wahl-127c</link>
      <guid>https://dev.to/uhltak/firewall-tuning-stateful-vs-next-gen-die-richtige-wahl-127c</guid>
      <description>&lt;h1&gt;
  
  
  Firewall-Tuning: Stateful vs. Next-Gen Firewall – wann reicht was und wann nicht?
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Einleitung
&lt;/h2&gt;

&lt;p&gt;Wenn es um die Sicherheit eines Netzwerks geht, spielt die Firewall eine zentrale Rolle. Die Frage ist jedoch, welche Art von Firewall das richtige Tool für die Aufgabe ist. Stateful Firewalls und Next-Gen Firewalls sind zwei gängige Arten von Firewalls, die je nach Anforderung eingesetzt werden können. In diesem Artikel werden wir uns mit den Unterschieden zwischen Stateful und Next-Gen Firewalls auseinandersetzen und beleuchten, wann welche Art von Firewall die richtige Wahl ist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stateful Firewalls
&lt;/h2&gt;

&lt;p&gt;Stateful Firewalls sind eine Art von Firewall, die den Zustand von Netzwerkverbindungen überwacht. Sie können feststellen, ob eine Verbindung initialisiert wird, aktiv ist oder beendet wurde. Stateful Firewalls sind in der Lage, basierend auf diesem Zustand Entscheidungen zu treffen, ob Datenpakete durchgelassen oder blockiert werden sollen. Ein Beispiel für eine Stateful Firewall ist die Cisco ASA.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Beispiel: Die Cisco ASA ist eine Stateful Firewall, die den Zustand von Netzwerkverbindungen überwacht. Sie kann beispielsweise feststellen, ob eine Verbindung initialisiert wird, und basierend darauf Entscheidungen treffen, ob Datenpakete durchgelassen oder blockiert werden sollen.&lt;/li&gt;
&lt;li&gt;Einschätzung: Meine Einschätzung ist, dass Stateful Firewalls eine gute Wahl für Netzwerke sind, die keine komplexen Sicherheitsanforderungen haben. Sie sind jedoch nicht in der Lage, komplexere Bedrohungen wie Malware oder Advanced Persistent Threats (APTs) zu erkennen.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next-Gen Firewalls
&lt;/h2&gt;

&lt;p&gt;Next-Gen Firewalls sind eine Art von Firewall, die zusätzlich zu den Funktionen einer Stateful Firewall auch weitere Sicherheitsfunktionen wie Deep Packet Inspection (DPI), Intrusion Prevention System (IPS) und Application Control bietet. Next-Gen Firewalls sind in der Lage, komplexe Bedrohungen wie Malware oder APTs zu erkennen und zu blockieren. Ein Beispiel für eine Next-Gen Firewall ist die Palo Alto Networks Next-Generation Firewall.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Beispiel: Die Palo Alto Networks Next-Generation Firewall ist eine Next-Gen Firewall, die Deep Packet Inspection (DPI), Intrusion Prevention System (IPS) und Application Control bietet. Sie kann beispielsweise komplexe Bedrohungen wie Malware oder APTs erkennen und blockieren.&lt;/li&gt;
&lt;li&gt;Einschätzung: Meine Einschätzung ist, dass Next-Gen Firewalls eine gute Wahl für Netzwerke sind, die komplexe Sicherheitsanforderungen haben. Sie bieten eine Vielzahl von Sicherheitsfunktionen, die es ermöglichen, komplexe Bedrohungen zu erkennen und zu blockieren.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Häufige Fehler / Fallstricke
&lt;/h2&gt;

&lt;p&gt;Ein häufiger Fehler bei der Auswahl einer Firewall ist, dass die Sicherheitsanforderungen des Netzwerks nicht genau definiert sind. Dies kann dazu führen, dass die falsche Art von Firewall ausgewählt wird, was wiederum zu Sicherheitslücken führen kann. Ein weiterer Fehler ist, dass die Firewall nicht ordnungsgemäß konfiguriert wird, was dazu führen kann, dass die Sicherheitsfunktionen nicht richtig funktionieren.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fazit
&lt;/h2&gt;

&lt;p&gt;In diesem Artikel haben wir uns mit den Unterschieden zwischen Stateful und Next-Gen Firewalls auseinandergesetzt und beleuchtet, wann welche Art von Firewall die richtige Wahl ist. Stateful Firewalls sind eine gute Wahl für Netzwerke, die keine komplexen Sicherheitsanforderungen haben, während Next-Gen Firewalls eine gute Wahl für Netzwerke sind, die komplexe Sicherheitsanforderungen haben. Es ist wichtig, die Sicherheitsanforderungen des Netzwerks genau zu definieren und die Firewall entsprechend auszuwählen und zu konfigurieren.&lt;/p&gt;

&lt;p&gt;Dein nächster Schritt sollte sein, die Sicherheitsanforderungen deines Netzwerks zu überprüfen und zu entscheiden, welche Art von Firewall die richtige Wahl ist. Wenn du unsicher bist, kann es hilfreich sein, einen Sicherheitsexperten zu konsultieren, der dir bei der Auswahl und Konfiguration der richtigen Firewall helfen kann.&lt;/p&gt;

</description>
      <category>firewalltuning</category>
      <category>statefulfirewall</category>
      <category>nextgenfirewall</category>
      <category>netzwerksicherheit</category>
    </item>
  </channel>
</rss>
