正在加载,请稍候…

HTTPS、TLS 配置与 cert-manager 证书管理

掌握生产环境中的 HTTPS 和 TLS 配置,包括 TLS 1.3、双向 TLS(mTLS)、使用 cert-manager 和 Let's Encrypt

HTTPS、TLS 配置与 cert-manager 证书管理

HTTPS 与 TLS 证书管理

TLS 1.3 Nginx 配置

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 和 1.3
    ssl_protocols TLSv1.2 TLSv1.3;

    # 强密码套件
    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;

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

    # 前向安全的 DH 参数
    ssl_dhparam /etc/nginx/dhparam.pem;
}

# HTTP 重定向到 HTTPS
server {
    listen 80;
    return 301 https://$host$request_uri;
}

HTTPS、TLS 配置与 cert-manager 证书管理示意图

Kubernetes 上的 cert-manager

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

# ClusterIssuer - Let's Encrypt 生产环境
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
# 带 TLS 的 Ingress
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

HTTPS、TLS 配置与 cert-manager 证书管理示意图

双向 TLS(mTLS)

import ssl
import httpx

def create_mtls_client(
    cert_path: str,
    key_path: str,
    ca_cert_path: str,
) -> httpx.Client:
    """创建带有双向 TLS 认证的 HTTP 客户端。"""
    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)

# 服务间 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")

HTTPS、TLS 配置与 cert-manager 证书管理示意图

Istio mTLS(服务网格)

# 为命名空间启用严格 mTLS
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: production
spec:
  mtls:
    mode: STRICT  # 所有服务间流量必须使用 mTLS

---
# 允许特定服务接受明文
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: allow-plaintext
  namespace: production
spec:
  selector:
    matchLabels:
      app: legacy-service
  mtls:
    mode: PERMISSIVE

证书透明度监控

import requests
from datetime import datetime

def monitor_cert_transparency(domain: str) -> list:
    """检查证书透明度日志中已颁发的证书。"""
    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"))
        # 标记近期颁发的证书
        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

# 对意外证书发出警报
certs = monitor_cert_transparency("example.com")
if certs:
    print(f"Alert: {len(certs)} new certificates issued in last 7 days!")

TLS 最佳实践

设置
最低 TLS 版本 TLS 1.2
首选 TLS 1.3
证书类型 ECDSA P-256
密钥大小(RSA) 2048+ 位
证书有效期 90 天(Let's Encrypt)
HSTS max-age 至少 1 年