Scenario 10.1: Configurare server TLS

Categoria: TLS/mTLS
Complessità: Media
Prerequisiti: Certificato server, chiave privata
Tempo stimato: 20-30 minuti


Descrizione

Questo scenario descrive la configurazione di un server TLS con certificati sicuri Post-Quantum. TLS 1.3 è obbligatorio per la sicurezza moderna.

Componenti:


Workflow

flowchart LR CERT[Preparare certificato] --> CHAIN[Creare catena] CHAIN --> CONFIG[Configurare TLS] CONFIG --> TEST[Test] TEST --> DEPLOY[Deployment] style CONFIG fill:#e8f5e9


Esempio codice: 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 =>
        {
            // Caricare certificato server
            httpsOptions.ServerCertificate = LoadCertificateChain(
                "server.crt.pem",
                "server.key.pem",
                "intermediate-ca.crt.pem"
            );
 
            // Forzare TLS 1.3
            httpsOptions.SslProtocols = SslProtocols.Tls13;
 
            // Attivare OCSP Stapling
            httpsOptions.OnAuthenticate = (context, sslOptions) =>
            {
                sslOptions.CertificateRevocationCheckMode = X509RevocationMode.Online;
            };
        });
 
        // Attivare HTTP/2
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
    });
});
 
var app = builder.Build();
 
// Attivare HSTS
app.UseHsts();
 
app.MapGet("/", () => "Server TLS attivo");
 
app.Run();
 
static X509Certificate2 LoadCertificateChain(
    string certPath,
    string keyPath,
    string chainPath)
{
    using var ctx = PqCryptoContext.Initialize();
 
    // Certificato server con chiave privata
    var cert = ctx.LoadCertificateWithPrivateKey(certPath, keyPath, null);
 
    // Aggiungere chain (per catena completa)
    var intermediate = ctx.LoadCertificate(chainPath);
 
    // Creare PFX con chain
    var pfxBytes = ctx.ExportToPfx(cert, cert.GetRSAPrivateKey(), new[] { intermediate }, null);
    return new X509Certificate2(pfxBytes);
}

Configurazione Nginx

server {
    listen 443 ssl http2;
    server_name www.example.com;
 
    # Certificato server (con chain)
    ssl_certificate     /etc/nginx/ssl/server-chain.pem;
    ssl_certificate_key /etc/nginx/ssl/server.key.pem;
 
    # Solo TLS 1.3
    ssl_protocols TLSv1.3;
 
    # Cipher Suites (TLS 1.3 default)
    # 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;
 
    # Security Headers
    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;
 
    # Configurazione sessione
    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;
    }
}

Configurazione Apache

<VirtualHost *:443>
    ServerName www.example.com
 
    # Attivare SSL
    SSLEngine on
 
    # Certificati
    SSLCertificateFile      /etc/apache2/ssl/server.crt.pem
    SSLCertificateKeyFile   /etc/apache2/ssl/server.key.pem
    SSLCertificateChainFile /etc/apache2/ssl/intermediate-ca.crt.pem
 
    # Solo 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"
 
    # Disattivare compressione (BREACH)
    SSLCompression off
 
    <Directory /var/www/html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Creare catena certificati

# Certificato server + Intermediate = Chain
cat server.crt.pem intermediate-ca.crt.pem > server-chain.pem
 
# Verificare ordine
openssl crl2pkcs7 -nocrl -certfile server-chain.pem | openssl pkcs7 -print_certs -noout
 
# Validare chain
openssl verify -CAfile root-ca.crt.pem -untrusted intermediate-ca.crt.pem server.crt.pem

Testare configurazione TLS

# SSL Labs API (se pubblico)
# https://www.ssllabs.com/ssltest/
 
# Test locale con OpenSSL
openssl s_client -connect localhost:443 -tls1_3 -brief
 
# Verificare cipher suites
openssl s_client -connect localhost:443 -cipher 'TLS_AES_256_GCM_SHA384' </dev/null
 
# Verificare catena certificati
openssl s_client -connect localhost:443 -showcerts </dev/null 2>/dev/null | openssl x509 -text -noout
 
# Verificare OCSP Stapling
openssl s_client -connect localhost:443 -status </dev/null 2>/dev/null | grep -A 5 "OCSP Response"
 
# testssl.sh (completo)
./testssl.sh localhost:443

Client di test C#

public async Task TestTlsConnection(string url)
{
    var handler = new HttpClientHandler
    {
        ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
        {
            Console.WriteLine($"Server: {cert.Subject}");
            Console.WriteLine($"Emittente: {cert.Issuer}");
            Console.WriteLine($"Algoritmo: {cert.SignatureAlgorithm.FriendlyName}");
            Console.WriteLine($"Valido fino a: {cert.NotAfter}");
 
            if (chain != null)
            {
                Console.WriteLine($"Lunghezza chain: {chain.ChainElements.Count}");
                foreach (var element in chain.ChainElements)
                {
                    Console.WriteLine($"  - {element.Certificate.Subject}");
                }
            }
 
            if (errors != SslPolicyErrors.None)
            {
                Console.WriteLine($"Errori SSL: {errors}");
                return false;
            }
 
            return true;
        }
    };
 
    using var client = new HttpClient(handler);
    var response = await client.GetAsync(url);
 
    Console.WriteLine($"Stato: {response.StatusCode}");
    Console.WriteLine($"Protocollo: {response.Version}");
}

Requisiti TLS specifici per settore

Settore Min. TLS Cipher Suites Particolarità
PCI-DSS TLS 1.2+ Cipher forti Verifica annuale
HIPAA TLS 1.2+ AES-256 Logging audit
BSI TR-02102 TLS 1.2+ Suite conformi BSI PFS obbligatorio
Energia/SCADA TLS 1.2+ Specifici ICS Supporto a lungo termine

Scenari correlati

Relazione Scenario Descrizione
Prerequisito 3.1 Certificato server Creare certificato
Passo successivo 10.2 Client TLS Configurare client
Estensione 10.3 Deployment mTLS Autenticazione reciproca

« ← Panoramica TLS | ↑ Scenari | 10.2 Client TLS → »


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