Scenarij 10.3: mTLS Deployment

Kategorija: TLS/mTLS
Složenost: ⭐⭐⭐⭐ (Visoka)
Preduvjeti: Server i klijentski certifikati, PKI
Procijenjeno vrijeme: 30-45 minuta


Opis

Ovaj scenarij opisuje potpuni deployment mTLS infrastrukture za obostranu autentifikaciju između klijenata i servera.

Područja primjene:

  • Zero-Trust arhitekture
  • Service-Mesh (Istio, Linkerd)
  • API sigurnost
  • Microservices komunikacija
  • IoT autentifikacija uređaja

Arhitektura

flowchart TD subgraph PKI ROOT[Root-CA] --> INT_SRV[Intermediate-CA Server] ROOT --> INT_CLI[Intermediate-CA Klijenti] end subgraph Server INT_SRV --> SRV_CERT[Server certifikat] SRV_CERT --> API[API Server] end subgraph Klijenti INT_CLI --> CLI1[Klijent 1] INT_CLI --> CLI2[Klijent 2] INT_CLI --> CLI3[Servis A] end CLI1 <-->|mTLS| API CLI2 <-->|mTLS| API CLI3 <-->|mTLS| API


1. PKI struktura za 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  // Bez Name Constraints za klijente
        );
        SaveCertAndKey(basePath, "client-int-ca", clientIntCert, clientIntKey);
 
        Console.WriteLine("mTLS PKI kreiran");
    }
}

2. Konfiguracija servera

// ASP.NET Core Kestrel mTLS
builder.WebHost.ConfigureKestrel(options =>
{
    options.ListenAnyIP(443, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            // Server certifikat
            httpsOptions.ServerCertificate = new X509Certificate2(
                "server.pfx", "ServerPassword!");
 
            // Zahtijevanje klijentskog certifikata
            httpsOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
 
            // Prihvaćeni klijentski CA-ovi
            httpsOptions.ClientCertificateValidation = (cert, chain, errors) =>
            {
                // Prihvatiti samo certifikate našeg klijentskog CA
                return ValidateClientCertificate(cert, chain);
            };
        });
    });
});
 
bool ValidateClientCertificate(X509Certificate2 cert, X509Chain? chain)
{
    // Učitavanje pouzdanog klijentskog CA
    var trustedClientCa = new X509Certificate2("client-int-ca.crt.pem");
 
    // Izgradnja prilagođenog lanca
    var customChain = new X509Chain();
    customChain.ChainPolicy.CustomTrustStore.Add(trustedClientCa);
    customChain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
    customChain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
 
    // Provjera Extended Key Usage: clientAuth
    customChain.ChainPolicy.ApplicationPolicy.Add(
        new Oid("1.3.6.1.5.5.7.3.2"));
 
    return customChain.Build(cert);
}

3. Konfiguracija klijenta

public HttpClient CreateMtlsClient(string clientCertPath, string clientKeyPath, string password)
{
    using var ctx = PqCryptoContext.Initialize();
 
    // Učitavanje klijentskog certifikata
    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 certifikat
    ssl_certificate     /etc/nginx/ssl/server-chain.pem;
    ssl_certificate_key /etc/nginx/ssl/server.key.pem;
 
    # Klijentska autentifikacija
    ssl_client_certificate /etc/nginx/ssl/client-ca-chain.pem;
    ssl_verify_client on;
    ssl_verify_depth 2;
 
    # CRL provjera
    ssl_crl /etc/nginx/ssl/client-ca.crl;
 
    # TLS 1.3
    ssl_protocols TLSv1.3;
    ssl_prefer_server_ciphers off;
 
    # OCSP Stapling za server certifikat
    ssl_stapling on;
    ssl_stapling_verify on;
 
    location / {
        # Proslijeđivanje informacija o klijentu backendu
        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 za sve servise u namespace-u
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: production
spec:
  mtls:
    mode: STRICT  # mTLS obavezan
---
# DestinationRule - mTLS za odlazne veze
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: default
  namespace: production
spec:
  host: "*.production.svc.cluster.local"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL  # Istio upravljani certifikati
---
# AuthorizationPolicy - Autorizacija temeljena na certifikatima
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 i logiranje

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 zahtjev: Subject={Subject}, Thumbprint={Thumbprint}, " +
                "Serial={Serial}, NotAfter={NotAfter}",
                clientCert.Subject,
                clientCert.Thumbprint,
                clientCert.SerialNumber,
                clientCert.NotAfter
            );
 
            // Upozorenje za certifikate koji uskoro ističu
            var daysUntilExpiry = (clientCert.NotAfter - DateTime.UtcNow).Days;
            if (daysUntilExpiry < 30)
            {
                _logger.LogWarning(
                    "Klijentski certifikat ističe za {Days} dana: {Subject}",
                    daysUntilExpiry,
                    clientCert.Subject
                );
            }
        }
 
        await _next(context);
    }
}

Sektorski specifični mTLS deployementi

Sektor Infrastruktura Rotacija certifikata Posebnost
Cloud Native Istio/Linkerd Automatski (SPIFFE) Service Mesh
Financijski sektor Hardware LB 90 dana HSM podržano
Zdravstvo On-Premise 1 godina Air-Gap moguć
IoT Edge Gateway 2-5 godina Offline sposobno

Povezani scenariji

Odnos Scenarij Opis
Preduvjet 10.1 TLS server Server strana
Preduvjet 10.2 TLS klijent Klijent strana
Povezano 9.1 mTLS Auth Autentifikacija
Proširenje 10.4 Hybrid TLS PQ nadogradnja

« ← 10.2 TLS klijent | ↑ Pregled TLS-a | 10.4 Hybrid TLS → »


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

Zuletzt geändert: 30.01.2026. u 06:52