~~NOTOC~~
====== Scenario 10.1: TLS Server Setup ======
**Category:** [[.:start|TLS/mTLS]] \\
**Complexity:** ⭐⭐⭐ (Medium) \\
**Prerequisites:** Server certificate, private key \\
**Estimated Time:** 20-30 Minutes
----
===== Description =====
This scenario describes the **setup of a TLS server** with Post-Quantum secure certificates. TLS 1.3 is mandatory for modern security.
**Components:**
* Server certificate (ML-DSA or Hybrid)
* Certificate chain (Intermediate + Root)
* TLS configuration
* Cipher suites
----
===== Workflow =====
flowchart LR
CERT[Prepare Certificate] --> CHAIN[Create Chain]
CHAIN --> CONFIG[Configure TLS]
CONFIG --> TEST[Test]
TEST --> DEPLOY[Deployment]
style CONFIG fill:#e8f5e9
----
===== Code Example: 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 =>
{
// Load server certificate
httpsOptions.ServerCertificate = LoadCertificateChain(
"server.crt.pem",
"server.key.pem",
"intermediate-ca.crt.pem"
);
// Enforce TLS 1.3
httpsOptions.SslProtocols = SslProtocols.Tls13;
// Enable OCSP Stapling
httpsOptions.OnAuthenticate = (context, sslOptions) =>
{
sslOptions.CertificateRevocationCheckMode = X509RevocationMode.Online;
};
});
// Enable HTTP/2
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
});
});
var app = builder.Build();
// Enable HSTS
app.UseHsts();
app.MapGet("/", () => "TLS Server active");
app.Run();
static X509Certificate2 LoadCertificateChain(
string certPath,
string keyPath,
string chainPath)
{
using var ctx = PqCryptoContext.Initialize();
// Server certificate with private key
var cert = ctx.LoadCertificateWithPrivateKey(certPath, keyPath, null);
// Add chain (for complete chain)
var intermediate = ctx.LoadCertificate(chainPath);
// Create PFX with chain
var pfxBytes = ctx.ExportToPfx(cert, cert.GetRSAPrivateKey(), new[] { intermediate }, null);
return new X509Certificate2(pfxBytes);
}
----
===== Nginx Configuration =====
server {
listen 443 ssl http2;
server_name www.example.com;
# Server certificate (with chain)
ssl_certificate /etc/nginx/ssl/server-chain.pem;
ssl_certificate_key /etc/nginx/ssl/server.key.pem;
# TLS 1.3 only
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;
# Session configuration
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;
}
}
----
===== Apache Configuration =====
ServerName www.example.com
# Enable SSL
SSLEngine on
# Certificates
SSLCertificateFile /etc/apache2/ssl/server.crt.pem
SSLCertificateKeyFile /etc/apache2/ssl/server.key.pem
SSLCertificateChainFile /etc/apache2/ssl/intermediate-ca.crt.pem
# TLS 1.3 only
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"
# Disable compression (BREACH)
SSLCompression off
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
----
===== Create Certificate Chain =====
# Server certificate + Intermediate = Chain
cat server.crt.pem intermediate-ca.crt.pem > server-chain.pem
# Verify order
openssl crl2pkcs7 -nocrl -certfile server-chain.pem | openssl pkcs7 -print_certs -noout
# Validate chain
openssl verify -CAfile root-ca.crt.pem -untrusted intermediate-ca.crt.pem server.crt.pem
----
===== Test TLS Configuration =====
# SSL Labs API (if public)
# https://www.ssllabs.com/ssltest/
# Local test with OpenSSL
openssl s_client -connect localhost:443 -tls1_3 -brief
# Check cipher suites
openssl s_client -connect localhost:443 -cipher 'TLS_AES_256_GCM_SHA384' /dev/null | openssl x509 -text -noout
# Check OCSP Stapling
openssl s_client -connect localhost:443 -status /dev/null | grep -A 5 "OCSP Response"
# testssl.sh (comprehensive)
./testssl.sh localhost:443
----
===== C# Test Client =====
public async Task TestTlsConnection(string url)
{
var handler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
{
Console.WriteLine($"Server: {cert.Subject}");
Console.WriteLine($"Issuer: {cert.Issuer}");
Console.WriteLine($"Algorithm: {cert.SignatureAlgorithm.FriendlyName}");
Console.WriteLine($"Valid until: {cert.NotAfter}");
if (chain != null)
{
Console.WriteLine($"Chain length: {chain.ChainElements.Count}");
foreach (var element in chain.ChainElements)
{
Console.WriteLine($" - {element.Certificate.Subject}");
}
}
if (errors != SslPolicyErrors.None)
{
Console.WriteLine($"SSL Errors: {errors}");
return false;
}
return true;
}
};
using var client = new HttpClient(handler);
var response = await client.GetAsync(url);
Console.WriteLine($"Status: {response.StatusCode}");
Console.WriteLine($"Protocol: {response.Version}");
}
----
===== Industry-Specific TLS Requirements =====
^ Industry ^ Minimum TLS ^ Cipher Suites ^ Special Feature ^
| **PCI-DSS** | TLS 1.2+ | Strong ciphers | Annual audit |
| **HIPAA** | TLS 1.2+ | AES-256 | Audit logging |
| **BSI TR-02102** | TLS 1.2+ | BSI-compliant suites | PFS mandatory |
| **Energy/SCADA** | TLS 1.2+ | ICS-specific | Long-term support |
----
===== Related Scenarios =====
^ Relationship ^ Scenario ^ Description ^
| **Prerequisite** | [[en:int:pqcrypt:szenarien:zertifikate:server_cert|3.1 Server Certificate]] | Create certificate |
| **Next Step** | [[.:client_config|10.2 TLS Client]] | Configure client |
| **Extension** | [[.:mtls_deployment|10.3 mTLS Deployment]] | Mutual authentication |
----
<< [[.:start|← TLS Overview]] | [[en:int:pqcrypt:szenarien:start|↑ Scenarios]] | [[.:client_config|10.2 TLS Client →]] >>
{{tag>scenario tls server nginx kestrel https}}
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//