13.6.3 TLS版本与密码套件优化

TLS版本与密码套件优化的目标是在兼容性与安全性之间取得平衡:优先启用TLS 1.2/1.3、禁用过时协议,并通过服务器优先策略选择更安全的套件,降低降级与弱套件风险。以下包含原理草图、安装检查、配置示例、验证、排错与练习。

原理草图(HAProxy终止TLS并向后端转发明文):

文章图片

安装与版本检查(确保HAProxy与OpenSSL支持TLS1.3):

# Debian/Ubuntu
sudo apt-get update
sudo apt-get install -y haproxy openssl

# RHEL/CentOS
sudo yum install -y haproxy openssl

# 查看HAProxy编译参数与TLS支持
haproxy -vv | egrep -i 'OpenSSL|TLS'
# 预期:显示OpenSSL版本,支持 TLSv1.3

TLS版本与套件策略配置示例(/etc/haproxy/haproxy.cfg):

global
    log /dev/log local0
    maxconn 20000
    # 推荐启用服务器优先
    ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 prefer-server-ciphers
    # TLS1.2套件列表(ECDHE + AEAD)
    ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\
ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
    # TLS1.3套件列表
    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:\
TLS_CHACHA20_POLY1305_SHA256

defaults
    log     global
    mode    http
    timeout connect 5s
    timeout client  30s
    timeout server  30s

frontend https_in
    bind *:443 ssl crt /etc/haproxy/certs/site.pem alpn h2,http/1.1 \
         ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.3
    http-request set-header X-Forwarded-Proto https
    default_backend app_pool

backend app_pool
    balance roundrobin
    server app1 10.0.0.11:8080 check
    server app2 10.0.0.12:8080 check

关键参数解释:
- ssl-min-ver/ssl-max-ver:限制协议版本范围。
- prefer-server-ciphers:让服务端优先选择更安全的套件。
- ssl-default-bind-ciphers:TLS1.2套件,需明确排除RC4/3DES/MD5等。
- ssl-default-bind-ciphersuites:TLS1.3套件列表。
- alpn:声明HTTP/2支持,保持浏览器兼容。

证书文件示例(合并证书链与私钥,/etc/haproxy/certs/site.pem):

cat /etc/ssl/certs/site.crt /etc/ssl/certs/site-chain.crt /etc/ssl/private/site.key \
  > /etc/haproxy/certs/site.pem
chmod 600 /etc/haproxy/certs/site.pem

验证与回归测试(命令+预期):

# 1) 验证TLS1.3是否可用
openssl s_client -connect 127.0.0.1:443 -tls1_3 </dev/null 2>/dev/null | grep -E 'Protocol|Cipher'
# 预期:Protocol: TLSv1.3

# 2) 验证TLS1.2是否可用(用于兼容)
openssl s_client -connect 127.0.0.1:443 -tls1_2 </dev/null 2>/dev/null | grep -E 'Protocol|Cipher'
# 预期:Protocol: TLSv1.2

# 3) 验证TLS1.0/1.1被禁用
openssl s_client -connect 127.0.0.1:443 -tls1 </dev/null
# 预期:握手失败或协议不支持

# 4) 列出服务端协商套件(快速检查)
openssl s_client -connect 127.0.0.1:443 -cipher 'ECDHE' </dev/null | grep Cipher

常见排错与定位:
- 现象:老旧客户端无法连接
排查:确认客户端不支持TLS1.2
处理:临时开独立端口兼容(仅内网或短期)

frontend https_legacy
    bind *:8443 ssl crt /etc/haproxy/certs/site.pem \
         ssl-min-ver TLSv1.0 ssl-max-ver TLSv1.2
    default_backend app_pool
  • 现象:握手失败,日志提示“no shared cipher”
    排查:客户端与服务端套件无交集
    处理:增加一条安全套件(仍需避免弱套件)
  • 现象:TLS1.3协商失败
    排查:HAProxy/OpenSSL版本不支持TLS1.3
    处理:升级HAProxy或OpenSSL,重启生效

日志与监控建议(定位握手异常):

global
    log /dev/log local0
defaults
    log global
    option httplog
# 配合系统日志搜索“SSL handshake failure”

练习(建议本地或测试环境完成):
1. 修改配置将ssl-min-ver从TLSv1.2改为TLSv1.3,仅允许TLS1.3;用openssl s_client -tls1_2验证失败。
2. 添加一条弱套件(如DES-CBC3-SHA),验证后再移除,记录日志中握手协商变化。
3. 创建独立兼容端口8443,对比TLS1.0与TLS1.2握手耗时与成功率。