Szenario 10.3: mTLS Deployment

Kategorie: TLS/mTLS
Komplexität: ⭐⭐⭐⭐ (Hoch)
Voraussetzungen: Server- und Client-Zertifikate, PKI
Geschätzte Zeit: 30-45 Minuten


Beschreibung

Dieses Szenario beschreibt das vollständige Deployment einer mTLS-Infrastruktur für gegenseitige Authentifizierung zwischen Clients und Servern.

Einsatzgebiete:

  • Zero-Trust Architekturen
  • Service-Mesh (Istio, Linkerd)
  • API-Security
  • Microservices-Kommunikation
  • IoT-Geräte-Authentifizierung

Architektur

flowchart TD subgraph PKI ROOT[Root-CA] --> INT_SRV[Intermediate-CA Server] ROOT --> INT_CLI[Intermediate-CA Clients] end subgraph Server INT_SRV --> SRV_CERT[Server-Zertifikat] SRV_CERT --> API[API Server] end subgraph Clients INT_CLI --> CLI1[Client 1] INT_CLI --> CLI2[Client 2] INT_CLI --> CLI3[Service A] end CLI1 <-->|mTLS| API CLI2 <-->|mTLS| API CLI3 <-->|mTLS| API


1. PKI-Struktur für mTLS

using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
 
public class MtlsPkiSetup
{
    public void CreateMtlsPki(string basePath)
    {
        using var ctx = PqCryptoContext.Initialize();
 
        // Root-CA
        using var rootKey = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65);
        var rootCert = ctx.CreateSelfSignedCertificate(
            rootKey,
            new DnBuilder().AddCN("mTLS Root CA").AddO("Example").Build(),
            validDays: 3650,
            extensions: new ExtBuilder()
                .BasicConstraints(ca: true, pathLengthConstraint: 2, critical: true)
                .KeyUsage(KeyUsageFlags.KeyCertSign | KeyUsageFlags.CrlSign, critical: true)
                .Build()
        );
        SaveCertAndKey(basePath, "root-ca", rootCert, rootKey);
 
        // Server Intermediate-CA
        using var serverIntKey = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65);
        var serverIntCert = CreateIntermediateCa(
            ctx, rootCert, rootKey, serverIntKey,
            "mTLS Server Intermediate CA",
            new[] { "dns:.example.com" }  // Name Constraint
        );
        SaveCertAndKey(basePath, "server-int-ca", serverIntCert, serverIntKey);
 
        // Client Intermediate-CA
        using var clientIntKey = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65);
        var clientIntCert = CreateIntermediateCa(
            ctx, rootCert, rootKey, clientIntKey,
            "mTLS Client Intermediate CA",
            null  // Keine Name Constraints für Clients
        );
        SaveCertAndKey(basePath, "client-int-ca", clientIntCert, clientIntKey);
 
        Console.WriteLine("mTLS PKI erstellt");
    }
}

2. Server-Konfiguration

// ASP.NET Core Kestrel mTLS
builder.WebHost.ConfigureKestrel(options =>
{
    options.ListenAnyIP(443, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            // Server-Zertifikat
            httpsOptions.ServerCertificate = new X509Certificate2(
                "server.pfx", "ServerPassword!");
 
            // Client-Zertifikat anfordern
            httpsOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
 
            // Akzeptierte Client-CAs
            httpsOptions.ClientCertificateValidation = (cert, chain, errors) =>
            {
                // Nur Zertifikate unserer Client-CA akzeptieren
                return ValidateClientCertificate(cert, chain);
            };
        });
    });
});
 
bool ValidateClientCertificate(X509Certificate2 cert, X509Chain? chain)
{
    // Trusted Client CA laden
    var trustedClientCa = new X509Certificate2("client-int-ca.crt.pem");
 
    // Custom Chain bauen
    var customChain = new X509Chain();
    customChain.ChainPolicy.CustomTrustStore.Add(trustedClientCa);
    customChain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
    customChain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
 
    // Extended Key Usage prüfen: clientAuth
    customChain.ChainPolicy.ApplicationPolicy.Add(
        new Oid("1.3.6.1.5.5.7.3.2"));
 
    return customChain.Build(cert);
}

3. Client-Konfiguration

public HttpClient CreateMtlsClient(string clientCertPath, string clientKeyPath, string password)
{
    using var ctx = PqCryptoContext.Initialize();
 
    // Client-Zertifikat laden
    var clientCert = ctx.LoadCertificateWithPrivateKey(
        clientCertPath,
        clientKeyPath,
        password
    );
 
    // Server Trust Store
    var trustedServerCa = ctx.LoadCertificate("server-int-ca.crt.pem");
 
    var handler = new HttpClientHandler
    {
        ClientCertificateOptions = ClientCertificateOption.Manual,
        SslProtocols = SslProtocols.Tls13,
 
        ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
        {
            var customChain = new X509Chain();
            customChain.ChainPolicy.CustomTrustStore.Add(trustedServerCa);
            customChain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
 
            // Extended Key Usage: serverAuth
            customChain.ChainPolicy.ApplicationPolicy.Add(
                new Oid("1.3.6.1.5.5.7.3.1"));
 
            return customChain.Build(cert);
        }
    };
 
    handler.ClientCertificates.Add(clientCert);
 
    return new HttpClient(handler)
    {
        DefaultRequestHeaders = { { "User-Agent", "mTLS-Client/1.0" } }
    };
}

4. Nginx mTLS Reverse Proxy

server {
    listen 443 ssl http2;
    server_name api.example.com;
 
    # Server-Zertifikat
    ssl_certificate     /etc/nginx/ssl/server-chain.pem;
    ssl_certificate_key /etc/nginx/ssl/server.key.pem;
 
    # Client-Authentifizierung
    ssl_client_certificate /etc/nginx/ssl/client-ca-chain.pem;
    ssl_verify_client on;
    ssl_verify_depth 2;
 
    # CRL-Prüfung
    ssl_crl /etc/nginx/ssl/client-ca.crl;
 
    # TLS 1.3
    ssl_protocols TLSv1.3;
    ssl_prefer_server_ciphers off;
 
    # OCSP Stapling für Server-Cert
    ssl_stapling on;
    ssl_stapling_verify on;
 
    location / {
        # Client-Info an Backend weiterleiten
        proxy_set_header X-Client-Cert-Subject $ssl_client_s_dn;
        proxy_set_header X-Client-Cert-Issuer $ssl_client_i_dn;
        proxy_set_header X-Client-Cert-Serial $ssl_client_serial;
        proxy_set_header X-Client-Cert-Fingerprint $ssl_client_fingerprint;
        proxy_set_header X-Client-Verify $ssl_client_verify;
 
        proxy_pass http://backend:8080;
    }
}

5. Kubernetes mTLS (Istio)

# PeerAuthentication - mTLS für alle Services im Namespace
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: production
spec:
  mtls:
    mode: STRICT  # mTLS Pflicht
---
# DestinationRule - mTLS für ausgehende Verbindungen
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: default
  namespace: production
spec:
  host: "*.production.svc.cluster.local"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL  # Istio-verwaltete Zertifikate
---
# AuthorizationPolicy - Zertifikatsbasierte Autorisierung
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: api-access
  namespace: production
spec:
  selector:
    matchLabels:
      app: api-server
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/production/sa/frontend-service"]
        namespaces: ["production"]

6. Monitoring und Logging

public class MtlsLoggingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<MtlsLoggingMiddleware> _logger;
 
    public MtlsLoggingMiddleware(RequestDelegate next, ILogger<MtlsLoggingMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }
 
    public async Task InvokeAsync(HttpContext context)
    {
        var clientCert = context.Connection.ClientCertificate;
 
        if (clientCert != null)
        {
            _logger.LogInformation(
                "mTLS Request: Subject={Subject}, Thumbprint={Thumbprint}, " +
                "Serial={Serial}, NotAfter={NotAfter}",
                clientCert.Subject,
                clientCert.Thumbprint,
                clientCert.SerialNumber,
                clientCert.NotAfter
            );
 
            // Warnung bei bald ablaufenden Zertifikaten
            var daysUntilExpiry = (clientCert.NotAfter - DateTime.UtcNow).Days;
            if (daysUntilExpiry < 30)
            {
                _logger.LogWarning(
                    "Client-Zertifikat läuft in {Days} Tagen ab: {Subject}",
                    daysUntilExpiry,
                    clientCert.Subject
                );
            }
        }
 
        await _next(context);
    }
}

Branchenspezifische mTLS-Deployments

Branche Infrastruktur Cert-Rotation Besonderheit
Cloud Native Istio/Linkerd Automatisch (SPIFFE) Service Mesh
Finanzsektor Hardware LB 90 Tage HSM-gestützt
Healthcare On-Premise 1 Jahr Air-Gap möglich
IoT Edge Gateway 2-5 Jahre Offline-Fähig

Verwandte Szenarien

Beziehung Szenario Beschreibung
Voraussetzung 10.1 TLS-Server Server-Seite
Voraussetzung 10.2 TLS-Client Client-Seite
Verwandt 9.1 mTLS Auth Authentifizierung
Erweiterung 10.4 Hybrid TLS PQ-Upgrade

« ← 10.2 TLS-Client | ↑ TLS-Übersicht | 10.4 Hybrid TLS → »


Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional

Zuletzt geändert: den 29.01.2026 um 15:13