Scenarij 10.1: Nastavitev TLS strežnika

Kategorija: TLS/mTLS
Kompleksnost: ⭐⭐⭐ (Srednja)
Predpogoji: Strežniški certifikat, zasebni ključ
Predviden čas: 20-30 minut


Opis

Ta scenarij opisuje nastavitev TLS strežnika s postkvantno varnimi certifikati. TLS 1.3 je obvezen za sodobno varnost.

Komponente:


Potek dela

flowchart LR CERT[Priprava certifikata] --> CHAIN[Ustvarjanje verige] CHAIN --> CONFIG[Konfiguracija TLS] CONFIG --> TEST[Testiranje] TEST --> DEPLOY[Uvajanje] style CONFIG fill:#e8f5e9


Primer kode: ASP.NET Core Kestrel

using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Https;
 
var builder = WebApplication.CreateBuilder(args);
 
builder.WebHost.ConfigureKestrel(options =>
{
    options.ListenAnyIP(443, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            // Nalaganje strežniškega certifikata
            httpsOptions.ServerCertificate = LoadCertificateChain(
                "server.crt.pem",
                "server.key.pem",
                "intermediate-ca.crt.pem"
            );
 
            // Zahtevanje TLS 1.3
            httpsOptions.SslProtocols = SslProtocols.Tls13;
 
            // Aktivacija OCSP Stapling
            httpsOptions.OnAuthenticate = (context, sslOptions) =>
            {
                sslOptions.CertificateRevocationCheckMode = X509RevocationMode.Online;
            };
        });
 
        // Aktivacija HTTP/2
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
    });
});
 
var app = builder.Build();
 
// Aktivacija HSTS
app.UseHsts();
 
app.MapGet("/", () => "TLS strežnik aktiven");
 
app.Run();
 
static X509Certificate2 LoadCertificateChain(
    string certPath,
    string keyPath,
    string chainPath)
{
    using var ctx = PqCryptoContext.Initialize();
 
    // Strežniški certifikat z zasebnim ključem
    var cert = ctx.LoadCertificateWithPrivateKey(certPath, keyPath, null);
 
    // Dodajanje verige (za popolno verigo)
    var intermediate = ctx.LoadCertificate(chainPath);
 
    // Ustvarjanje PFX z verigo
    var pfxBytes = ctx.ExportToPfx(cert, cert.GetRSAPrivateKey(), new[] { intermediate }, null);
    return new X509Certificate2(pfxBytes);
}

Konfiguracija Nginx

server {
    listen 443 ssl http2;
    server_name www.example.com;
 
    # Strežniški certifikat (z verigo)
    ssl_certificate     /etc/nginx/ssl/server-chain.pem;
    ssl_certificate_key /etc/nginx/ssl/server.key.pem;
 
    # Samo TLS 1.3
    ssl_protocols TLSv1.3;
 
    # Šifrirni nabori (TLS 1.3 privzeti)
    # ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
    ssl_prefer_server_ciphers off;
 
    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/nginx/ssl/ca-chain.pem;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
 
    # Varnostne glave
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "DENY" always;
 
    # Konfiguracija seje
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
 
    location / {
        proxy_pass http://backend:8080;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Konfiguracija Apache

<VirtualHost *:443>
    ServerName www.example.com
 
    # Aktivacija SSL
    SSLEngine on
 
    # Certifikati
    SSLCertificateFile      /etc/apache2/ssl/server.crt.pem
    SSLCertificateKeyFile   /etc/apache2/ssl/server.key.pem
    SSLCertificateChainFile /etc/apache2/ssl/intermediate-ca.crt.pem
 
    # Samo TLS 1.3
    SSLProtocol -all +TLSv1.3
 
    # OCSP Stapling
    SSLUseStapling On
    SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
    SSLStaplingResponderTimeout 5
    SSLStaplingReturnResponderErrors off
 
    # HSTS
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
 
    # Deaktivacija kompresije (BREACH)
    SSLCompression off
 
    <Directory /var/www/html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Ustvarjanje verige certifikatov

# Strežniški certifikat + vmesni = veriga
cat server.crt.pem intermediate-ca.crt.pem > server-chain.pem
 
# Preverjanje vrstnega reda
openssl crl2pkcs7 -nocrl -certfile server-chain.pem | openssl pkcs7 -print_certs -noout
 
# Validacija verige
openssl verify -CAfile root-ca.crt.pem -untrusted intermediate-ca.crt.pem server.crt.pem

Testiranje TLS konfiguracije

# SSL Labs API (če je javno dostopen)
# https://www.ssllabs.com/ssltest/
 
# Lokalni test z OpenSSL
openssl s_client -connect localhost:443 -tls1_3 -brief
 
# Preverjanje šifrirnih naborov
openssl s_client -connect localhost:443 -cipher 'TLS_AES_256_GCM_SHA384' </dev/null
 
# Preverjanje verige certifikatov
openssl s_client -connect localhost:443 -showcerts </dev/null 2>/dev/null | openssl x509 -text -noout
 
# Preverjanje OCSP Stapling
openssl s_client -connect localhost:443 -status </dev/null 2>/dev/null | grep -A 5 "OCSP Response"
 
# testssl.sh (obsežno)
./testssl.sh localhost:443

C# testni odjemalec

public async Task TestTlsConnection(string url)
{
    var handler = new HttpClientHandler
    {
        ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
        {
            Console.WriteLine($"Strežnik: {cert.Subject}");
            Console.WriteLine($"Izdajatelj: {cert.Issuer}");
            Console.WriteLine($"Algoritem: {cert.SignatureAlgorithm.FriendlyName}");
            Console.WriteLine($"Veljavno do: {cert.NotAfter}");
 
            if (chain != null)
            {
                Console.WriteLine($"Dolžina verige: {chain.ChainElements.Count}");
                foreach (var element in chain.ChainElements)
                {
                    Console.WriteLine($"  - {element.Certificate.Subject}");
                }
            }
 
            if (errors != SslPolicyErrors.None)
            {
                Console.WriteLine($"SSL napake: {errors}");
                return false;
            }
 
            return true;
        }
    };
 
    using var client = new HttpClient(handler);
    var response = await client.GetAsync(url);
 
    Console.WriteLine($"Status: {response.StatusCode}");
    Console.WriteLine($"Protokol: {response.Version}");
}

Panožne TLS zahteve

Panoga Minimalni TLS Šifrirni nabori Posebnost
PCI-DSS TLS 1.2+ Močne šifre Letni pregled
HIPAA TLS 1.2+ AES-256 Revizijsko beleženje
BSI TR-02102 TLS 1.2+ BSI skladni nabori PFS obvezen
Energetika/SCADA TLS 1.2+ ICS specifični Dolgoročna podpora

Povezani scenariji

Povezava Scenarij Opis
Predpogoj 3.1 Strežniški certifikat Ustvarjanje certifikata
Naslednji korak 10.2 TLS odjemalec Konfiguracija odjemalca
Razširitev 10.3 Uvajanje mTLS Obojestranska avtentikacija

« ← Pregled TLS | ↑ Scenariji | 10.2 TLS odjemalec → »


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