Zero Trust-arkitektur på Linux: Praktisk guide till mikrosegmentering, WireGuard och identitetsbaserad åtkomst

En praktisk guide till Zero Trust-arkitektur på Linux. Lär dig konfigurera mikrosegmentering med nftables, krypterade tunnlar med WireGuard, identitetsbaserad åtkomst med SPIFFE/SPIRE och avancerad policyhantering med eBPF och Cilium.

Introduktion till Zero Trust-arkitektur

Den gamla säkerhetsmodellen var i grunden ganska enkel: bygg en stark perimeter och lita på allt som finns innanför. Men ärligt talat — i en värld med distribuerade molntjänster, containerbaserade mikrotjänster och medarbetare som jobbar hemifrån i pyjamas, fungerar det inte längre. Zero Trust vänder upp och ner på hela tänket med sin grundprincip: "lita aldrig, verifiera alltid".

Zero Trust-arkitektur (ZTA) utgår från att intrång redan har skett, eller att de kommer att ske. Varje begäran om åtkomst ska autentiseras, auktoriseras och krypteras — oavsett om den kommer inifrån eller utifrån nätverket.

Under 2026 har detta blivit en absolut nödvändighet för Linux-infrastruktur. Och det är inte så konstigt — majoriteten av alla servrar i molnet och datacenter kör ju trots allt Linux.

Varför räcker inte perimetersäkerhet längre? Jo, det finns flera uppenbara anledningar:

  • Lateral rörelse: En angripare som tar sig in via en enda komprometterad tjänst kan röra sig fritt i ett platt nätverk. Det räcker med ett enda svagt led.
  • Insider-hot: Interna aktörer eller komprometterade konton har redan tillgång bakom brandväggen — perimetern hjälper inte alls här.
  • Molnintegration: Hybridmiljöer med både on-premise och molnresurser gör det i princip omöjligt att definiera en tydlig perimeter.
  • Mikrotjänstarkitektur: Hundratals tjänster som kommunicerar med varandra, och varje kommunikationsväg utgör en potentiell attackyta.

Så, låt oss dyka in. I den här guiden går vi igenom hur du praktiskt implementerar Zero Trust på Linux-system med verktyg som nftables, WireGuard, SPIFFE/SPIRE, eBPF och moderna övervakningsverktyg. Fokus ligger på konkreta konfigurationer du kan börja använda direkt.

Grundprinciper för Zero Trust på Linux

Innan vi kastar oss in i de tekniska detaljerna behöver vi förstå de fem grundpelarna i en Zero Trust-arkitektur anpassad för Linux-infrastruktur.

1. Identitetsverifiering

Varje användare, tjänst och arbetsbelastning (workload) måste ha en kryptografiskt verifierbar identitet. På Linux innebär det att vi använder certifikatbaserad autentisering istället för IP-baserade tillitszoner. SPIFFE (Secure Production Identity Framework for Everyone) har blivit standarden för att tilldela identiteter till arbetsbelastningar.

2. Minsta möjliga behörighet (Least Privilege)

Varje process, användare och tjänst ska enbart ha de behörigheter som krävs för att utföra sin uppgift — inget mer. På Linux implementeras detta genom en kombination av SELinux/AppArmor-profiler, Linux capabilities, namespace-isolering och nätverkspolicyer som begränsar vilka tjänster som får prata med varandra.

3. Mikrosegmentering

Nätverket delas upp i små, isolerade zoner där kommunikation mellan zonerna kräver explicit tillåtelse. Istället för ett platt nätverk där alla servrar kan nå varandra skapar vi finkorniga policyer som reglerar vilken trafik som tillåts mellan enskilda tjänster.

4. Kontinuerlig verifiering

Autentisering sker inte bara vid inloggning — den pågår hela tiden. Sessioner har kort livslängd, certifikat roteras regelbundet och beteendeanalys används för att upptäcka anomalier i realtid.

5. Enhets- och arbetsbelastningsattest

Innan en arbetsbelastning får kommunicera med andra tjänster måste den bevisa sin integritet. Det kan innebära verifiering av operativsystemets tillstånd, kontroll av att binärer inte har manipulerats, eller validering genom TPM-baserad attest.

Nätverksmikrosegmentering med nftables

nftables är den moderna ersättaren för iptables och utgör grunden för brandväggshantering i Linux-kärnan sedan version 3.13. I en Zero Trust-kontext använder vi nftables för att implementera mikrosegmentering — strikta regler för vilken trafik som tillåts mellan tjänster på samma nätverk.

Grundläggande zonbaserad policy

Vi börjar med att definiera en nftables-konfiguration som följer Zero Trust-principen: neka allt som standard och sedan explicit tillåta de kommunikationsvägar som faktiskt behövs.

#!/usr/sbin/nft -f

# Rensa alla befintliga regler
flush ruleset

# Definiera variabler för tjänstezoner
define webservrar = { 10.10.1.10, 10.10.1.11 }
define appservrar = { 10.10.2.10, 10.10.2.11, 10.10.2.12 }
define databasservrar = { 10.10.3.10, 10.10.3.11 }
define overvakningsserver = { 10.10.4.10 }

table inet zero_trust {

    # Kedja för inkommande trafik
    chain input {
        type filter hook input priority 0; policy drop;

        # Tillåt etablerade och relaterade anslutningar
        ct state established,related accept

        # Tillåt loopback
        iif lo accept

        # Tillåt ICMP för diagnostik (begränsat)
        ip protocol icmp icmp type { echo-request, echo-reply } \
            limit rate 5/second accept

        # SSH enbart från bastion-host
        tcp dport 22 ip saddr 10.10.0.5 accept

        # Logga och neka allt annat
        log prefix "ZT-INPUT-DROP: " limit rate 10/minute
        drop
    }

    # Kedja för vidarebefordran (east-west trafik)
    chain forward {
        type filter hook forward priority 0; policy drop;

        ct state established,related accept

        # Webservrar -> Appservrar (enbart HTTP)
        ip saddr $webservrar ip daddr $appservrar tcp dport 8080 accept

        # Appservrar -> Databasservrar (enbart PostgreSQL)
        ip saddr $appservrar ip daddr $databasservrar tcp dport 5432 accept

        # Alla zoner -> Övervakningsserver (metrics)
        ip daddr $overvakningsserver tcp dport { 9090, 9100 } accept

        # Logga nekad east-west trafik
        log prefix "ZT-FORWARD-DROP: " limit rate 10/minute
        drop
    }

    chain output {
        type filter hook output priority 0; policy drop;

        ct state established,related accept
        oif lo accept

        # Tillåt DNS
        tcp dport 53 accept
        udp dport 53 accept

        # Tillåt NTP
        udp dport 123 accept

        # Tillåt utgående trafik till definierade zoner
        ip daddr $overvakningsserver tcp dport { 9090, 9100 } accept

        log prefix "ZT-OUTPUT-DROP: " limit rate 10/minute
        drop
    }
}

Tjänstespecifik mikrosegmentering

För ännu mer finkornig kontroll kan vi använda nftables sets och maps för att definiera exakt vilka tjänster som får kommunicera med vilka portar. Det här är faktiskt ganska elegant:

# Skapa en namngiven map för tjänst-till-tjänst-kommunikation
table inet mikrosegment {

    # Set för tillåtna tjänstekombinationer
    set tillaten_api_trafik {
        type ipv4_addr . inet_service
        elements = {
            10.10.2.10 . 8080,
            10.10.2.11 . 8080,
            10.10.2.12 . 8080
        }
    }

    set tillaten_db_trafik {
        type ipv4_addr . inet_service
        elements = {
            10.10.3.10 . 5432,
            10.10.3.11 . 5432
        }
    }

    chain begrans_tjanster {
        type filter hook forward priority 10; policy drop;

        ct state established,related accept

        # Kontrollera mot tillåtna sets
        ip saddr 10.10.1.0/24 ip daddr . tcp dport @tillaten_api_trafik accept
        ip saddr 10.10.2.0/24 ip daddr . tcp dport @tillaten_db_trafik accept

        # Neka all annan east-west trafik
        log prefix "MIKROSEG-DROP: " counter drop
    }
}

Hastighetsbegränsning per tjänst

Zero Trust handlar också om att begränsa mängden trafik en tjänst kan skicka. Även om en tjänst blir komprometterad vill vi minimera skadan:

table inet rate_limiting {
    chain limit_tjanster {
        type filter hook forward priority 5; policy accept;

        # Begränsa databasanslutningar till 100 nya per minut per käll-IP
        ip daddr 10.10.3.0/24 tcp dport 5432 ct state new \
            meter db_limit { ip saddr limit rate 100/minute } accept

        ip daddr 10.10.3.0/24 tcp dport 5432 ct state new \
            log prefix "DB-RATE-LIMIT: " drop
    }
}

Spara konfigurationen och aktivera den vid systemstart:

# Spara konfigurationen
sudo nft list ruleset > /etc/nftables.conf

# Aktivera nftables-tjänsten
sudo systemctl enable nftables
sudo systemctl start nftables

# Verifiera att reglerna är aktiva
sudo nft list ruleset

WireGuard som Zero Trust-nätverkslager

WireGuard är ett modernt VPN-protokoll som är inbyggt i Linux-kärnan sedan version 5.6. Det passar utmärkt för Zero Trust-arkitekturer tack vare sin design som bygger på kryptografiskt verifierade peer-to-peer-tunnlar med cryptokey routing. Varje peer identifieras genom sin publika nyckel — inte genom IP-adresser. Och det är precis så det ska vara i en Zero Trust-värld.

Grundläggande WireGuard-konfiguration mellan servrar

Vi börjar med att skapa en krypterad tunnel mellan en appserver och en databasserver:

# På båda servrarna: installera WireGuard
sudo apt install wireguard

# Generera nyckelpar på appservern
wg genkey | tee /etc/wireguard/privkey_app | wg pubkey > /etc/wireguard/pubkey_app
chmod 600 /etc/wireguard/privkey_app

# Generera nyckelpar på databasservern
wg genkey | tee /etc/wireguard/privkey_db | wg pubkey > /etc/wireguard/pubkey_db
chmod 600 /etc/wireguard/privkey_db

Konfigurera WireGuard-gränssnittet på appservern (10.10.2.10):

# /etc/wireguard/wg0.conf på appservern
[Interface]
Address = 172.16.0.1/32
PrivateKey = <appserverns_privata_nyckel>
ListenPort = 51820

# Enbart trafik till databasservern routas genom tunneln
PostUp = nft add rule inet zero_trust input udp dport 51820 accept
PostDown = nft delete rule inet zero_trust input udp dport 51820 accept

[Peer]
# Databasservern
PublicKey = <databasserverns_publika_nyckel>
AllowedIPs = 172.16.0.2/32
Endpoint = 10.10.3.10:51820
PersistentKeepalive = 25

Konfigurera WireGuard på databasservern (10.10.3.10):

# /etc/wireguard/wg0.conf på databasservern
[Interface]
Address = 172.16.0.2/32
PrivateKey = <databasserverns_privata_nyckel>
ListenPort = 51820

# Tillåt enbart PostgreSQL-trafik genom WireGuard-tunneln
PostUp = nft add rule inet zero_trust input iifname wg0 tcp dport 5432 accept
PostDown = nft delete rule inet zero_trust input iifname wg0 tcp dport 5432 accept

[Peer]
# Appservern
PublicKey = <appserverns_publika_nyckel>
AllowedIPs = 172.16.0.1/32
Endpoint = 10.10.2.10:51820
PersistentKeepalive = 25
# Starta WireGuard på båda servrarna
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

# Verifiera tunnelstatus
sudo wg show

Cryptokey routing och Zero Trust

WireGuards design stödjer Zero Trust på flera intressanta sätt:

  • Obligatorisk ömsesidig autentisering: Båda parter måste ha varandras publika nycklar konfigurerade. Ingen anonym kommunikation tillåts.
  • Cryptokey routing: IP-paket mappas direkt till kryptografiska identiteter. Parametern AllowedIPs definierar exakt vilka IP-adresser en peer tillåts använda — det fungerar som en inbyggd brandväggsregel.
  • Perfekt framåtsekretess: Varje handskakningscykel använder efemära nycklar, vilket innebär att komprometterade sessionsnycklar inte avslöjar tidigare eller framtida trafik.
  • Minimal attackyta: WireGuard har cirka 4 000 rader kod jämfört med OpenVPN:s över 100 000. Det är en enorm skillnad som drastiskt minskar risken för sårbarheter.

Automatiserade mesh-nätverk med NetBird och Netmaker

Att manuellt hantera WireGuard-konfigurationer i stor skala blir snabbt ohållbart — och det är inget man vill lägga sin tid på i onödan. Verktyg som NetBird och Netmaker automatiserar skapandet av WireGuard-baserade mesh-nätverk med Zero Trust-policyer.

NetBird erbjuder ett agentbaserat system där varje nod automatiskt upprättar peer-to-peer WireGuard-tunnlar baserat på centralt definierade åtkomstpolicyer:

# Installera NetBird-agenten
curl -fsSL https://pkgs.netbird.io/install.sh | sh

# Anslut till NetBird-kontrollplanet
sudo netbird up --setup-key <din_setup_nyckel>

# Visa nätverksstatus
sudo netbird status

I NetBirds administrationsgränssnitt eller via API kan du sedan definiera åtkomstpolicyer:

# Exempel: NetBird Access Control Policy via API
# Tillåt enbart webservrar att nå appservrar på port 8080
{
  "name": "web-till-app",
  "description": "Tillat webservrar att na appservrar",
  "rules": [
    {
      "name": "http-access",
      "sources": ["grupp-webservrar"],
      "destinations": ["grupp-appservrar"],
      "bidirectional": false,
      "protocol": "tcp",
      "ports": ["8080"]
    }
  ]
}

Netmaker erbjuder liknande funktionalitet men med stöd för mer avancerade nätverkstopologier:

# Installera Netmaker-klienten
curl -sL 'https://apt.netmaker.org/gpg.key' | sudo tee /etc/apt/trusted.gpg.d/netclient.asc
sudo apt install netclient

# Gå med i Netmaker-nätverket
sudo netclient join -t <anslutnings_token>

# Visa WireGuard-peers som hanteras av Netmaker
sudo wg show

Båda verktygen hanterar automatiskt nyckelrotation, peer-discovery och NAT-traversering. Det gör det praktiskt att driva WireGuard-baserade Zero Trust-nätverk med hundratals noder utan att drunkna i manuell konfigurationshantering.

Identitetsbaserad åtkomst med SPIFFE och SPIRE

I en Zero Trust-arkitektur är identitet den nya perimetern. Det är ett av de viktigaste koncepten att internalisera. SPIFFE (Secure Production Identity Framework for Everyone) definierar en standard för arbetsbelastningsidentiteter, och SPIRE (SPIFFE Runtime Environment) är referensimplementationen som utfärdar och hanterar dessa identiteter.

Förstå SPIFFE-identiteter

Varje arbetsbelastning tilldelas en SPIFFE ID i form av en URI:

spiffe://foretag.se/webb/frontend
spiffe://foretag.se/api/betalning
spiffe://foretag.se/databas/postgres

Dessa identiteter representeras som SVIDs (SPIFFE Verifiable Identity Documents) — kortlivade X.509-certifikat eller JWT-tokens som automatiskt roteras. En SVID har typiskt en livslängd på mellan 1 och 24 timmar, vilket begränsar skadan rejält om nycklar skulle komprometteras.

Installera och konfigurera SPIRE Server

# Ladda ner och installera SPIRE
curl -s -N -L https://github.com/spiffe/spire/releases/download/v1.11.0/spire-1.11.0-linux-amd64-musl.tar.gz | \
    tar xz -C /opt/

# Skapa konfigurationskatalog
sudo mkdir -p /etc/spire/server
sudo mkdir -p /var/lib/spire/server

Skapa SPIRE Server-konfigurationen:

# /etc/spire/server/server.conf
server {
    bind_address = "0.0.0.0"
    bind_port = "8081"
    trust_domain = "foretag.se"
    data_dir = "/var/lib/spire/server"
    log_level = "INFO"

    # SVID-livslängd (1 timme)
    default_x509_svid_ttl = "1h"

    ca_ttl = "24h"

    # JWT-utfärdarkonfiguration
    jwt_issuer = "https://spire.foretag.se"
}

plugins {
    DataStore "sql" {
        plugin_data {
            database_type = "sqlite3"
            connection_string = "/var/lib/spire/server/datastore.sqlite3"
        }
    }

    NodeAttestor "join_token" {
        plugin_data {}
    }

    KeyManager "disk" {
        plugin_data {
            keys_path = "/var/lib/spire/server/keys.json"
        }
    }

    UpstreamAuthority "disk" {
        plugin_data {
            key_file_path = "/etc/spire/server/dummy_upstream_ca.key"
            cert_file_path = "/etc/spire/server/dummy_upstream_ca.crt"
        }
    }
}

Konfigurera SPIRE Agent

SPIRE Agent körs på varje nod och tillhandahåller identiteter till lokala arbetsbelastningar via en Unix Domain Socket:

# /etc/spire/agent/agent.conf
agent {
    data_dir = "/var/lib/spire/agent"
    log_level = "INFO"
    server_address = "spire-server.foretag.se"
    server_port = "8081"
    trust_domain = "foretag.se"
    socket_path = "/run/spire/agent/sockets/agent.sock"
}

plugins {
    NodeAttestor "join_token" {
        plugin_data {}
    }

    KeyManager "disk" {
        plugin_data {
            directory = "/var/lib/spire/agent"
        }
    }

    WorkloadAttestor "unix" {
        plugin_data {
            discover_workload_path = true
        }
    }
}

Registrera arbetsbelastningar

Innan en arbetsbelastning kan få en SVID måste den registreras med specifika attestregler. Här är några exempel:

# Registrera webbtjänsten (identifieras via Unix-process UID)
spire-server entry create \
    -spiffeID spiffe://foretag.se/webb/frontend \
    -parentID spiffe://foretag.se/agent/webbserver-01 \
    -selector unix:uid:1001

# Registrera API-tjänsten
spire-server entry create \
    -spiffeID spiffe://foretag.se/api/betalning \
    -parentID spiffe://foretag.se/agent/appserver-01 \
    -selector unix:uid:1002 \
    -selector unix:path:/usr/local/bin/betalning-api

# Registrera databasarbetsbelastning
spire-server entry create \
    -spiffeID spiffe://foretag.se/databas/postgres \
    -parentID spiffe://foretag.se/agent/dbserver-01 \
    -selector unix:uid:999

Implementera mTLS mellan tjänster

Med SPIRE på plats kan vi konfigurera ömsesidig TLS (mTLS) mellan tjänster. Här är ett exempel i Go som visar hur en tjänst hämtar sin SVID och upprättar en mTLS-anslutning:

// Exempel: Go-klient som använder SPIFFE Workload API
package main

import (
    "context"
    "fmt"
    "net/http"

    "github.com/spiffe/go-spiffe/v2/spiffeid"
    "github.com/spiffe/go-spiffe/v2/spiffetls/tlsconfig"
    "github.com/spiffe/go-spiffe/v2/workloadapi"
)

func main() {
    ctx := context.Background()

    // Anslut till SPIRE Agent Workload API
    source, err := workloadapi.NewX509Source(
        ctx,
        workloadapi.WithClientOptions(
            workloadapi.WithAddr("unix:///run/spire/agent/sockets/agent.sock"),
        ),
    )
    if err != nil {
        panic(fmt.Sprintf("Kunde inte skapa X509-källa: %v", err))
    }
    defer source.Close()

    // Definiera vilken SPIFFE-ID vi litar på
    betroddID := spiffeid.RequireFromString("spiffe://foretag.se/api/betalning")

    // Skapa TLS-konfiguration med mTLS
    tlsConfig := tlsconfig.MTLSClientConfig(source, source, tlsconfig.AuthorizeID(betroddID))

    client := &http.Client{
        Transport: &http.Transport{
            TLSClientConfig: tlsConfig,
        },
    }

    // Anropa API-tjänsten med mTLS
    resp, err := client.Get("https://api-betalning.intern:8443/halsokontroll")
    if err != nil {
        panic(fmt.Sprintf("Begäran misslyckades: %v", err))
    }
    defer resp.Body.Close()

    fmt.Printf("Svar: %d\n", resp.StatusCode)
}

Den här lösningen ger oss flera viktiga Zero Trust-fördelar:

  • Identiteter är kryptografiskt verifierbara och inte beroende av nätverksposition
  • Certifikat roteras automatiskt (standard varje timme)
  • Arbetsbelastningsattest säkerställer att enbart rätt processer får rätt identiteter
  • mTLS ger ömsesidig autentisering — både klient och server verifierar varandras identitet

eBPF-baserad policyhantering

eBPF (extended Berkeley Packet Filter) har ärligt talat revolutionerat hur vi implementerar säkerhetspolicyer på Linux. Genom att köra sandboxade program direkt i kärnan kan eBPF fatta beslut om nätverkstrafik, systemanrop och filåtkomst med minimal prestandapåverkan — ofta storleksordningar snabbare än traditionella iptables-kedjor.

Varför eBPF överträffar iptables för Zero Trust

Traditionella iptables-regler har betydande begränsningar i en Zero Trust-kontext:

  • Linjär regelutvärdering: iptables utvärderar regler sekventiellt, så prestanda försämras med antalet regler. I mikrosegmenterade miljöer med tusentals regler blir det en rejäl flaskhals.
  • Begränsad kontextmedvetenhet: iptables arbetar primärt med L3/L4-information (IP-adresser och portar). eBPF kan inspektera L7-data och fatta beslut baserat på applikationsprotokoll.
  • Statisk natur: iptables-regler kräver omladdning vid ändringar. eBPF-program kan uppdateras atomiskt utan avbrott.

Cilium för nätverkspolicy i Kubernetes

Cilium är det ledande eBPF-baserade nätverksverktyget för Kubernetes och Linux. Det ersätter kube-proxy och implementerar nätverkspolicyer direkt i kärnan:

# Installera Cilium med Helm
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium --version 1.16.5 \
    --namespace kube-system \
    --set kubeProxyReplacement=true \
    --set hubble.enabled=true \
    --set hubble.relay.enabled=true \
    --set hubble.ui.enabled=true

Definiera en Zero Trust-nätverkspolicy med Cilium:

# cilium-zero-trust-policy.yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "betalning-api-policy"
  namespace: "produktion"
spec:
  description: "Zero Trust-policy for betalnings-API"
  endpointSelector:
    matchLabels:
      app: betalning-api

  # Inkommande regler - vem får nå betalnings-API:et?
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: webb-frontend
            miljö: produktion
      toPorts:
        - ports:
            - port: "8443"
              protocol: TCP
          rules:
            http:
              - method: "POST"
                path: "/api/v1/betalningar"
              - method: "GET"
                path: "/api/v1/betalningar/[0-9]+"
              - method: "GET"
                path: "/halsokontroll"

  # Utgående regler - vad får betalnings-API:et kommunicera med?
  egress:
    - toEndpoints:
        - matchLabels:
            app: postgres
            roll: primär
      toPorts:
        - ports:
            - port: "5432"
              protocol: TCP
    - toEndpoints:
        - matchLabels:
            app: redis
      toPorts:
        - ports:
            - port: "6379"
              protocol: TCP
    # Tillåt DNS-uppslagning
    - toEndpoints:
        - matchLabels:
            "k8s:io.kubernetes.pod.namespace": kube-system
            k8s-app: kube-dns
      toPorts:
        - ports:
            - port: "53"
              protocol: UDP
          rules:
            dns:
              - matchPattern: "*.produktion.svc.cluster.local"

Den här policyn demonstrerar L7-medveten Zero Trust: vi begränsar inte bara vilka tjänster som får kommunicera, utan även vilka HTTP-metoder och URL-sökvägar som är tillåtna. Ganska kraftfullt.

Tetragon för körtidssäkerhet

Tetragon är Ciliums kompanjonprojekt för körtidssäkerhet (runtime security). Det använder eBPF för att övervaka och upprätthålla policyer på processnivå, filåtkomst och nätverkskommunikation:

# Installera Tetragon
helm install tetragon cilium/tetragon \
    --namespace kube-system \
    --set tetragon.enablePolicyFilter=true

Definiera en TracingPolicy som förhindrar obehörig filåtkomst:

# tetragon-fil-policy.yaml
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: "skydda-hemligheter"
spec:
  kprobes:
    - call: "fd_install"
      syscall: false
      args:
        - index: 0
          type: "int"
        - index: 1
          type: "file"
      selectors:
        - matchArgs:
            - index: 1
              operator: "Prefix"
              values:
                - "/etc/shadow"
                - "/etc/ssl/private"
                - "/var/lib/spire"
          matchActions:
            - action: Sigkill
              rateLimit: "1m"
            - action: Post
              rateLimit: "1m"
    - call: "sys_execve"
      syscall: true
      args:
        - index: 0
          type: "string"
      selectors:
        - matchArgs:
            - index: 0
              operator: "NotIn"
              values:
                - "/usr/local/bin/betalning-api"
                - "/usr/bin/node"
                - "/bin/sh"
          matchNamespaces:
            - namespace: Pid
              operator: NotIn
              values:
                - "host_ns"
          matchActions:
            - action: Sigkill

Tetragon kan även övervaka nätverksanslutningar på kärnnivå och avsluta processer som försöker upprätta otillåtna anslutningar. Det är en riktigt kraftfull mekanism för att förhindra lateral rörelse i realtid.

eBPF på icke-Kubernetes-system

Kör du Linux-servrar utan Kubernetes? Inga problem. Du kan använda bpftool och libbpf för att implementera eBPF-baserade policyer direkt:

# Visa laddade eBPF-program
sudo bpftool prog list

# Visa eBPF-kartor (maps) som används för policydata
sudo bpftool map list

# Fäst ett eBPF-program vid ett nätverksgränssnitt med tc
sudo tc filter add dev eth0 ingress bpf da obj zero_trust_filter.o sec ingress

# Inspektera eBPF-programstatistik
sudo bpftool prog show id 42 --json | jq '.run_cnt, .run_time_ns'

Kontinuerlig verifiering och övervakning

Zero Trust kräver att vi inte bara sätter upp policyer en gång och sen glömmer dem. Vi måste kontinuerligt verifiera att policyerna efterlevs och att inga avvikelser förekommer. Tre verktyg är särskilt effektiva för detta på Linux: Falco, Osquery och Wazuh.

Falco för körtidsdetektering

Falco övervakar systemanrop med eBPF och genererar varningar vid misstänkt beteende:

# Installera Falco
curl -fsSL https://falco.org/repo/falcosecurity-packages.asc | \
    sudo gpg --dearmor -o /usr/share/keyrings/falco-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] \
    https://download.falco.org/packages/deb stable main" | \
    sudo tee /etc/apt/sources.list.d/falcosecurity.list

sudo apt update && sudo apt install falco

Skapa anpassade Falco-regler för Zero Trust-övervakning:

# /etc/falco/rules.d/zero_trust.yaml

# Detektera otillåtna nätverksanslutningar
- rule: Ej godkänd utgående anslutning
  desc: >
    Detekterar när en tjänst försöker ansluta till en destination
    som inte finns i den godkända listan.
  condition: >
    evt.type in (connect) and
    evt.dir = < and
    fd.typechar = 4 and
    not fd.sip in (10.10.1.0/24, 10.10.2.0/24, 10.10.3.0/24, 10.10.4.0/24) and
    not fd.sport in (53, 123) and
    container.id != host
  output: >
    Otillåten utgående anslutning detekterad
    (process=%proc.name pid=%proc.pid användare=%user.name
     anslutning=%fd.name container=%container.name
     bild=%container.image.repository)
  priority: WARNING
  tags: [zero_trust, nätverk, lateral_rörelse]

# Detektera försök att läsa känsliga filer
- rule: Obehörig åtkomst till certifikatfiler
  desc: Detekterar processer som läser SPIRE-certifikat utan behörighet
  condition: >
    open_read and
    fd.name startswith /var/lib/spire/ and
    not proc.name in (spire-agent, spire-server) and
    not user.name = root
  output: >
    Obehörig läsning av SPIRE-certifikat
    (fil=%fd.name process=%proc.name användare=%user.name)
  priority: CRITICAL
  tags: [zero_trust, identitet, certifikat]

# Detektera oväntade processer som lyssnar på nätverksportar
- rule: Oväntad nätverkslyssnare
  desc: Detekterar processer som öppnar serverportar utanför godkänd lista
  condition: >
    evt.type = listen and
    not proc.name in (nginx, node, betalning-api, postgres, prometheus)
  output: >
    Oväntad process lyssnar på nätverksport
    (process=%proc.name port=%fd.sport pid=%proc.pid)
  priority: ERROR
  tags: [zero_trust, nätverk, obehörig_tjänst]

Osquery för kontinuerlig inventering

Osquery låter oss ställa SQL-frågor mot systemets tillstånd och kontinuerligt övervaka förändringar. Det här är ovärderligt i en Zero Trust-miljö där vi behöver verifiera att systemen faktiskt är i det tillstånd vi förväntar oss:

# /etc/osquery/osquery.conf
{
  "options": {
    "config_plugin": "filesystem",
    "logger_plugin": "filesystem",
    "schedule_splay_percent": 10
  },
  "schedule": {
    "zt_oppna_portar": {
      "query": "SELECT pid, name, local_address, local_port, remote_address, remote_port, state FROM process_open_sockets WHERE state = 'LISTEN' OR state = 'ESTABLISHED';",
      "interval": 60,
      "description": "Övervaka alla öppna nätverksanslutningar"
    },
    "zt_wireguard_status": {
      "query": "SELECT interface, public_key, allowed_ips, latest_handshake, transfer_rx, transfer_tx FROM wireguard_peers;",
      "interval": 300,
      "description": "Kontrollera WireGuard-tunnelstatus"
    },
    "zt_kernel_moduler": {
      "query": "SELECT name, size, status FROM kernel_modules WHERE status = 'Live';",
      "interval": 3600,
      "description": "Inventera laddade kärnmoduler"
    },
    "zt_obehaviga_suid": {
      "query": "SELECT path, username, permissions FROM suid_bin WHERE path NOT IN ('/usr/bin/sudo', '/usr/bin/passwd', '/usr/bin/newgrp', '/usr/bin/chsh', '/usr/bin/chfn');",
      "interval": 1800,
      "description": "Hitta oväntade SUID-binärer"
    },
    "zt_certifikat_utgangsdatum": {
      "query": "SELECT path, common_name, issuer, not_valid_after, CAST((JULIANDAY(not_valid_after) - JULIANDAY('now')) AS INTEGER) AS dagar_kvar FROM certificates WHERE path LIKE '/etc/ssl/%' AND dagar_kvar < 30;",
      "interval": 86400,
      "description": "Varna för certifikat som snart löper ut"
    }
  },
  "packs": {
    "incident-response": "/usr/share/osquery/packs/incident-response.conf"
  }
}

Wazuh för centraliserad övervakning

Wazuh fungerar som det centrala navet för Zero Trust-övervakning. Det samlar in data från Falco, Osquery och systemloggar för att skapa en sammanhängande helhetsvy:

# /var/ossec/etc/ossec.conf (relevant utdrag)
<ossec_config>
  <!-- Integrera med Falco -->
  <localfile>
    <log_format>json</log_format>
    <location>/var/log/falco/falco.json</location>
  </localfile>

  <!-- Övervaka nftables-ändringar -->
  <localfile>
    <log_format>syslog</log_format>
    <location>/var/log/kern.log</location>
  </localfile>

  <!-- Integritetsövervakning av kritiska filer -->
  <syscheck>
    <frequency>600</frequency>
    <directories check_all="yes" realtime="yes">
      /etc/nftables.conf,
      /etc/wireguard,
      /etc/spire
    </directories>
    <directories check_all="yes">
      /usr/local/bin
    </directories>
  </syscheck>

  <!-- Anpassade regler för Zero Trust-händelser -->
  <rule id="100100" level="12">
    <if_sid>86601</if_sid>
    <field name="rule.tags">lateral_rörelse</field>
    <description>Zero Trust: Möjlig lateral rörelse detekterad via Falco</description>
    <group>zero_trust,</group>
  </rule>

  <rule id="100101" level="14">
    <if_sid>550</if_sid>
    <match>/etc/wireguard|/etc/nftables.conf</match>
    <description>Zero Trust: Kritisk säkerhetskonfiguration ändrad</description>
    <group>zero_trust,config_ändring,</group>
  </rule>
</ossec_config>

Genom att kombinera dessa tre verktyg skapar vi ett övervakningsekosystem som ger:

  • Realtidsdetektering av policyöverträdelser (Falco)
  • Kontinuerlig inventering av systemtillstånd (Osquery)
  • Centraliserad korrelering och varning (Wazuh)
  • Historisk spårning för forensisk analys

Praktisk implementeringsplan

Att implementera Zero Trust på befintlig Linux-infrastruktur är ett stegvist arbete. Mitt starkaste råd: försök inte göra allt på en gång. Börja smått, mät effekterna och expandera gradvis.

Fas 1: Kartläggning och synlighet (vecka 1–4)

  1. Kartlägg alla kommunikationsvägar: Använd verktyg som ss, conntrack och nätverksövervakning för att dokumentera vilka tjänster som kommunicerar med varandra.
  2. Installera övervakningsverktyg: Sätt upp Osquery och Falco i övervakningsläge (utan blockering) på alla servrar.
  3. Skapa en inventering: Dokumentera alla tjänster, deras beroendekedjan och vilka portar och protokoll de använder.
  4. Definiera zoner: Gruppera tjänster i logiska zoner baserat på funktion och säkerhetskrav.
# Kartlägg aktiva anslutningar
ss -tulnp | sort -k5

# Visa etablerade anslutningar med processinformation
ss -tnp state established

# Exportera conntrack-tabell för analys
sudo conntrack -L -o extended > /tmp/anslutningar_$(date +%Y%m%d).log

Fas 2: Grundläggande segmentering (vecka 5–8)

  1. Implementera nftables-policyer: Börja med generösa regler som loggar men inte blockerar (log utan drop), och strama åt gradvis.
  2. Sätt upp WireGuard-tunnlar: Börja med de mest kritiska kommunikationsvägarna, till exempel mellan appservrar och databaser.
  3. Konfigurera bastion-host: Centralisera all SSH-åtkomst genom en enda bastion-host med strikt loggning.
# Steg 1: Starta i loggningsläge
# Byt "drop" mot "log" i din nftables-policy under testperioden
chain forward {
    type filter hook forward priority 0; policy accept;

    # Logga trafik som SKULLE blockeras
    ip saddr 10.10.2.0/24 ip daddr 10.10.3.0/24 tcp dport != 5432 \
        log prefix "ZT-SKULLE-BLOCKERA: " counter

    # Efter verifiering, aktivera blockering
    # ip saddr 10.10.2.0/24 ip daddr 10.10.3.0/24 tcp dport != 5432 drop
}

Fas 3: Identitetsbaserad åtkomst (vecka 9–14)

  1. Installera SPIRE: Driftsätt SPIRE Server och Agents på alla noder.
  2. Registrera arbetsbelastningar: Skapa SPIFFE-identiteter för alla tjänster med lämpliga attestregler.
  3. Migrera till mTLS: Ersätt gradvis nätverksbaserad tillit med certifikatbaserad mTLS mellan tjänster.
  4. Implementera auktorisering: Skapa policyer som bestämmer vilka SPIFFE-identiteter som får kommunicera med vilka.

Fas 4: Avancerad policyhantering (vecka 15–20)

  1. Implementera eBPF-policyer: Lägg till Cilium eller Tetragon för finkornig L7-policyhantering.
  2. Automatisera policyhantering: Använd GitOps-arbetsflöden för att hantera alla policyer som kod.
  3. Integrera med CI/CD: Se till att nya tjänster automatiskt får identiteter och policyer vid driftsättning.

Fas 5: Kontinuerlig förbättring (pågående)

  1. Regelbundna penetrationstester: Testa att policyerna faktiskt förhindrar lateral rörelse.
  2. Automatiserad efterlevnadskontroll: Använd Osquery-scheman och Wazuh-regler för att kontinuerligt verifiera att alla system följer policyn.
  3. Incidentövningar: Simulera intrång och mät hur snabbt det upptäcks och begränsas. Du vill inte att första gången du testar din respons ska vara under ett riktigt angrepp.

Vanliga misstag och bästa praxis

Misstag att undvika

Misstag 1: Allt-eller-inget-mentalitet. Att försöka implementera fullständig Zero Trust på hela infrastrukturen samtidigt leder nästan alltid till misslyckande. Jag har sett det hända mer än en gång. Börja med de mest kritiska tjänsterna och expandera stegvis.

Misstag 2: Att ignorera befintliga beroenden. Innan du inför strikta mikrosegmenteringsregler måste du ha fullständig synlighet över alla tjänsters kommunikationsmönster. En oväntad blockering av en kritisk kommunikationsväg kan orsaka produktionsavbrott — och det är ingen rolig fredagskväll.

Misstag 3: Att förlita sig enbart på nätverkssegmentering. Mikrosegmentering med nftables är ett viktigt lager, men utan identitetsbaserad åtkomst och kontinuerlig verifiering har du inte en fullständig Zero Trust-arkitektur. Alla tre komponenterna behövs.

Misstag 4: Otillräcklig loggning. Zero Trust utan fullständig loggning och övervakning är som att ha lås på dörrarna men inga fönster att se igenom. Varje åtkomstbeslut — både godkända och nekade — måste loggas.

Misstag 5: Statiska åtkomstpolicyer. Zero Trust kräver dynamiska policyer som anpassar sig efter kontext. Att enbart ha statiska brandväggsregler som aldrig ändras uppfyller inte kravet på kontinuerlig verifiering.

Bästa praxis

Följande riktlinjer har visat sig vara avgörande för framgångsrika Zero Trust-implementationer på Linux:

  1. Behandla policyer som kod: Alla nftables-konfigurationer, WireGuard-konfigurationer, SPIRE-registreringar och Cilium-policyer ska versionshanteras i Git. Använd pull requests och kodgranskning för alla policyändringar.
    # Exempel på katalogstruktur för Zero Trust-policyer
    zero-trust-policyer/
    ├── nftables/
    │   ├── bas.conf
    │   ├── webzon.conf
    │   └── databaszon.conf
    ├── wireguard/
    │   ├── appserver-01.conf
    │   └── dbserver-01.conf
    ├── spire/
    │   ├── registreringar/
    │   │   ├── webbfrontend.sh
    │   │   └── betalning-api.sh
    │   └── server.conf
    ├── cilium/
    │   ├── betalning-policy.yaml
    │   └── default-deny.yaml
    └── falco/
        └── zero_trust_regler.yaml
    
  2. Implementera break-glass-procedurer: Ha dokumenterade och testade nödprocedurer för att tillfälligt utöka åtkomst vid kritiska incidenter. Dessa procedurer ska kräva godkännande och loggas fullständigt.
    # Exempel: Nödåtkomstskript med tidsbegränsning och loggning
    #!/bin/bash
    # break-glass.sh - Tillfällig utökad åtkomst
    OPERATÖR=$(whoami)
    ANLEDNING="$1"
    VARAKTIGHET="${2:-3600}" # Standard: 1 timme
    
    logger -t BREAK-GLASS "Nödåtkomst aktiverad av $OPERATÖR: $ANLEDNING"
    
    # Öppna tillfällig åtkomst
    nft add rule inet zero_trust forward ip saddr 10.10.0.0/16 \
        ip daddr 10.10.0.0/16 accept comment \"BREAK-GLASS: $OPERATÖR\"
    
    # Schemalägg återställning
    at now + $((VARAKTIGHET / 60)) minutes <<SLUT
    nft delete rule inet zero_trust forward handle \
        \$(nft -a list chain inet zero_trust forward | grep BREAK-GLASS | awk '{print \$NF}')
    logger -t BREAK-GLASS "Nödåtkomst avslutad för $OPERATÖR"
    SLUT
    
    echo "Nödåtkomst aktiverad i $VARAKTIGHET sekunder."
    
  3. Automatisera certifikatrotation: Använd SPIRE:s automatiska certifikatrotation och se till att alla tjänster hanterar certifikatförnyelse utan avbrott. Övervaka certifikatens livslängd och varna proaktivt.
  4. Testa blockeringarna regelbundet: Använd automatiserade tester som verifierar att mikrosegmenteringsreglerna faktiskt fungerar:
    # Automatiserat test av mikrosegmentering
    #!/bin/bash
    # test_mikrosegmentering.sh
    
    MISSLYCKADE=0
    
    # Test 1: Webbserver SKA kunna nå appserver
    if timeout 3 bash -c "echo > /dev/tcp/10.10.2.10/8080" 2>/dev/null; then
        echo "[OK] Webb -> App: Tillåten trafik fungerar"
    else
        echo "[FEL] Webb -> App: Tillåten trafik blockeras!"
        ((MISSLYCKADE++))
    fi
    
    # Test 2: Webbserver SKA INTE kunna nå databas direkt
    if timeout 3 bash -c "echo > /dev/tcp/10.10.3.10/5432" 2>/dev/null; then
        echo "[FEL] Webb -> DB: Otillåten trafik tillåts!"
        ((MISSLYCKADE++))
    else
        echo "[OK] Webb -> DB: Otillåten trafik blockeras"
    fi
    
    # Test 3: Appserver SKA kunna nå databas
    if timeout 3 bash -c "echo > /dev/tcp/10.10.3.10/5432" 2>/dev/null; then
        echo "[OK] App -> DB: Tillåten trafik fungerar"
    else
        echo "[FEL] App -> DB: Tillåten trafik blockeras!"
        ((MISSLYCKADE++))
    fi
    
    if [ $MISSLYCKADE -gt 0 ]; then
        echo ""
        echo "VARNING: $MISSLYCKADE test misslyckades!"
        exit 1
    else
        echo ""
        echo "Alla mikrosegmenteringstest godkända."
        exit 0
    fi
    
  5. Övervaka WireGuard-handskakningar: En WireGuard-peer som inte har genomfört en handskakningscykel på längre tid kan indikera problem. Integrera detta i din övervakning:
    # Prometheus-metrik för WireGuard-övervakning
    # Använd prometheus-wireguard-exporter
    sudo wg show all dump | awk '{
        if (NR > 1) {
            peer=$2;
            senaste_handskak=$6;
            rx=$7;
            tx=$8;
            if (senaste_handskak > 0) {
                alder = systime() - senaste_handskak;
                if (alder > 300) {
                    print "VARNING: Peer " peer " senaste handskakningcykel: " alder "s sedan";
                }
            }
        }
    }'
    
  6. Implementera gradvis och mät: Inför varje ny policyändring, mät baslinjeprestanda och övervaka att ingen legitim trafik påverkas. Använd Ciliums Hubble eller nftables-räknare för att kvantifiera trafikmönster.

Sammanfattning

Zero Trust på Linux är ingen enskild produkt utan en arkitekturfilosofi som implementeras genom samverkan mellan flera verktyg och tekniker. Genom att kombinera nftables för mikrosegmentering, WireGuard för krypterad kommunikation, SPIFFE/SPIRE för identitetshantering, eBPF/Cilium/Tetragon för finkornig policyhantering och Falco/Osquery/Wazuh för kontinuerlig övervakning skapar du en robust försvarsarkitektur med försvar på djupet.

Det viktigaste att ta med sig? Zero Trust är en resa, inte en destination. Börja med att förstå din nuvarande miljö, implementera grundläggande segmentering och bygg stegvis vidare mot full identitetsbaserad åtkomst och kontinuerlig verifiering. Varje steg du tar minskar attackytan och ökar din förmåga att upptäcka och begränsa intrång.

I takt med att hotlandskapet fortsätter att utvecklas under 2026 och framåt är Zero Trust inte längre ett alternativ — det är ett krav för alla som tar Linux-säkerhet på allvar.

Om Författaren Editorial Team

Our team of expert writers and editors.