正在加载,请稍候…

HTTPS, TLS Configuration, and Certificate Management with cert-manager

Master HTTPS and TLS for production. Configure TLS 1.3, mutual TLS, certificate automation with cert-manager and Let's Encrypt, and HTTP security headers.

HTTPS and TLS Certificate Management

TLS 1.3 Nginx Configuration

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/ssl/certs/example.crt;
    ssl_certificate_key /etc/ssl/private/example.key;

    # TLS 1.2 and 1.3 only
    ssl_protocols TLSv1.2 TLSv1.3;

    # Strong cipher suites
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers off;

    # HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;

    # Session
    ssl_session_cache shared:MozSSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # DH parameters for forward secrecy
    ssl_dhparam /etc/nginx/dhparam.pem;
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    return 301 https://$host$request_uri;
}

cert-manager on Kubernetes

# Install cert-manager
# kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml

# ClusterIssuer - Let's Encrypt production
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: letsencrypt-prod-account-key
    solvers:
      - http01:
          ingress:
            class: nginx
# Ingress with TLS
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - myapp.example.com
      secretName: myapp-tls
  rules:
    - host: myapp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myapp-service
                port:
                  number: 80

Mutual TLS (mTLS)

import ssl
import httpx

def create_mtls_client(
    cert_path: str,
    key_path: str,
    ca_cert_path: str,
) -> httpx.Client:
    """Create HTTP client with mutual TLS authentication."""
    ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
    ctx.load_verify_locations(ca_cert_path)
    ctx.load_cert_chain(cert_path, key_path)
    ctx.verify_mode = ssl.CERT_REQUIRED
    ctx.check_hostname = True
    ctx.minimum_version = ssl.TLSVersion.TLSv1_2

    return httpx.Client(verify=ctx)

# Service-to-service mTLS
client = create_mtls_client(
    cert_path="/certs/client.crt",
    key_path="/certs/client.key",
    ca_cert_path="/certs/ca.crt",
)

response = client.get("https://internal-service/api/data")

Istio mTLS (Service Mesh)

# Enable strict mTLS for namespace
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: production
spec:
  mtls:
    mode: STRICT  # All service-to-service traffic must use mTLS

---
# Allow specific service to accept plaintext
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: allow-plaintext
  namespace: production
spec:
  selector:
    matchLabels:
      app: legacy-service
  mtls:
    mode: PERMISSIVE

Certificate Transparency Monitoring

import requests
from datetime import datetime

def monitor_cert_transparency(domain: str) -> list:
    """Check Certificate Transparency logs for issued certs."""
    url = f"https://crt.sh/?q={domain}&output=json"
    resp = requests.get(url, timeout=10)
    certs = resp.json()

    suspicious = []
    for cert in certs:
        issued_at = datetime.fromisoformat(cert["not_before"].replace("Z", "+00:00"))
        # Flag recently issued certs
        if (datetime.now().astimezone() - issued_at).days < 7:
            suspicious.append({
                "id": cert["id"],
                "name": cert["name_value"],
                "issuer": cert["issuer_name"],
                "issued": cert["not_before"],
            })

    return suspicious

# Alert on unexpected certificates
certs = monitor_cert_transparency("example.com")
if certs:
    print(f"Alert: {len(certs)} new certificates issued in last 7 days!")

TLS Best Practices

Setting Value
Minimum TLS version TLS 1.2
Preferred TLS 1.3
Certificate type ECDSA P-256
Key size (RSA) 2048+ bits
Certificate validity 90 days (Let's Encrypt)
HSTS max-age 1 year minimum