~~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//