
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;
}

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

双向 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")

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 年 |