~~NOTOC~~ ====== Scenarij 10.3: Uvajanje mTLS ====== **Kategorija:** [[.:start|TLS/mTLS]] \\ **Kompleksnost:** ⭐⭐⭐⭐ (Visoka) \\ **Predpogoji:** Strežniški in odjemalčevi certifikati, PKI \\ **Predviden čas:** 30-45 minut ---- ===== Opis ===== Ta scenarij opisuje **popolno uvajanje mTLS infrastrukture** za obojestransko avtentikacijo med odjemalci in strežniki. **Področja uporabe:** * Zero-Trust arhitekture * Service-Mesh (Istio, Linkerd) * API varnost * Komunikacija mikrostoritev * Avtentikacija IoT naprav ---- ===== Arhitektura ===== flowchart TD subgraph PKI ROOT[Korenski CA] --> INT_SRV[Vmesni CA za strežnike] ROOT --> INT_CLI[Vmesni CA za odjemalce] end subgraph Strežnik INT_SRV --> SRV_CERT[Strežniški certifikat] SRV_CERT --> API[API strežnik] end subgraph Odjemalci INT_CLI --> CLI1[Odjemalec 1] INT_CLI --> CLI2[Odjemalec 2] INT_CLI --> CLI3[Storitev 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(); // Korenski 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); // Vmesni CA za strežnike using var serverIntKey = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65); var serverIntCert = CreateIntermediateCa( ctx, rootCert, rootKey, serverIntKey, "mTLS Server Intermediate CA", new[] { "dns:.example.com" } // Omejitev imen ); SaveCertAndKey(basePath, "server-int-ca", serverIntCert, serverIntKey); // Vmesni CA za odjemalce using var clientIntKey = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65); var clientIntCert = CreateIntermediateCa( ctx, rootCert, rootKey, clientIntKey, "mTLS Client Intermediate CA", null // Brez omejitev imen za odjemalce ); SaveCertAndKey(basePath, "client-int-ca", clientIntCert, clientIntKey); Console.WriteLine("mTLS PKI ustvarjen"); } } ---- ===== 2. Konfiguracija strežnika ===== // ASP.NET Core Kestrel mTLS builder.WebHost.ConfigureKestrel(options => { options.ListenAnyIP(443, listenOptions => { listenOptions.UseHttps(httpsOptions => { // Strežniški certifikat httpsOptions.ServerCertificate = new X509Certificate2( "server.pfx", "ServerPassword!"); // Zahtevanje odjemalčevega certifikata httpsOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate; // Sprejeti CA-ji za odjemalce httpsOptions.ClientCertificateValidation = (cert, chain, errors) => { // Sprejem samo certifikatov naše CA za odjemalce return ValidateClientCertificate(cert, chain); }; }); }); }); bool ValidateClientCertificate(X509Certificate2 cert, X509Chain? chain) { // Nalaganje zaupanja vrednega CA za odjemalce var trustedClientCa = new X509Certificate2("client-int-ca.crt.pem"); // Gradnja prilagojene verige var customChain = new X509Chain(); customChain.ChainPolicy.CustomTrustStore.Add(trustedClientCa); customChain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; customChain.ChainPolicy.RevocationMode = X509RevocationMode.Online; // Preverjanje razširjene uporabe ključa: clientAuth customChain.ChainPolicy.ApplicationPolicy.Add( new Oid("1.3.6.1.5.5.7.3.2")); return customChain.Build(cert); } ---- ===== 3. Konfiguracija odjemalca ===== public HttpClient CreateMtlsClient(string clientCertPath, string clientKeyPath, string password) { using var ctx = PqCryptoContext.Initialize(); // Nalaganje odjemalčevega certifikata var clientCert = ctx.LoadCertificateWithPrivateKey( clientCertPath, clientKeyPath, password ); // Shramba zaupanja za strežnik 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; // Razširjena uporaba ključa: 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 povratni posrednik ===== server { listen 443 ssl http2; server_name api.example.com; # Strežniški certifikat ssl_certificate /etc/nginx/ssl/server-chain.pem; ssl_certificate_key /etc/nginx/ssl/server.key.pem; # Avtentikacija odjemalca ssl_client_certificate /etc/nginx/ssl/client-ca-chain.pem; ssl_verify_client on; ssl_verify_depth 2; # Preverjanje CRL ssl_crl /etc/nginx/ssl/client-ca.crl; # TLS 1.3 ssl_protocols TLSv1.3; ssl_prefer_server_ciphers off; # OCSP Stapling za strežniški certifikat ssl_stapling on; ssl_stapling_verify on; location / { # Posredovanje informacij o odjemalcu zaledni storitvi 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 vse storitve v imenskem prostoru apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: production spec: mtls: mode: STRICT # mTLS obvezen --- # DestinationRule - mTLS za izhodne povezave 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 - Avtorizacija na podlagi certifikatov 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. Nadzor in beleženje ===== public class MtlsLoggingMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; public MtlsLoggingMiddleware(RequestDelegate next, ILogger logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { var clientCert = context.Connection.ClientCertificate; if (clientCert != null) { _logger.LogInformation( "mTLS zahteva: Subject={Subject}, Thumbprint={Thumbprint}, " + "Serial={Serial}, NotAfter={NotAfter}", clientCert.Subject, clientCert.Thumbprint, clientCert.SerialNumber, clientCert.NotAfter ); // Opozorilo pri certifikatih, ki kmalu potečejo var daysUntilExpiry = (clientCert.NotAfter - DateTime.UtcNow).Days; if (daysUntilExpiry < 30) { _logger.LogWarning( "Odjemalčev certifikat poteče čez {Days} dni: {Subject}", daysUntilExpiry, clientCert.Subject ); } } await _next(context); } } ---- ===== Panožna uvajanja mTLS ===== ^ Panoga ^ Infrastruktura ^ Rotacija certifikatov ^ Posebnost ^ | **Cloud Native** | Istio/Linkerd | Samodejno (SPIFFE) | Service Mesh | | **Finančni sektor** | Strojni uravnalniki obremenitve | 90 dni | Podprto s HSM | | **Zdravstvo** | On-Premise | 1 leto | Air-Gap možen | | **IoT** | Robni prehod | 2-5 let | Brez povezave zmožno | ---- ===== Povezani scenariji ===== ^ Povezava ^ Scenarij ^ Opis ^ | **Predpogoj** | [[.:server_setup|10.1 TLS strežnik]] | Strežniška stran | | **Predpogoj** | [[.:client_config|10.2 TLS odjemalec]] | Odjemalčeva stran | | **Povezano** | [[sl:int:pqcrypt:szenarien:authentifizierung:mtls_client_auth|9.1 mTLS avtentikacija]] | Avtentikacija | | **Razširitev** | [[.:hybrid_tls|10.4 Hibridni TLS]] | PQ nadgradnja | ---- << [[.:client_config|← 10.2 TLS odjemalec]] | [[.:start|↑ Pregled TLS]] | [[.:hybrid_tls|10.4 Hibridni TLS →]] >> {{tag>scenarij tls mtls uvajanje kubernetes istio}} ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//