Skip to content

SSL/TLS 配置

HAProxy 原生支持 SSL 终止(SSL Termination),无需在每台后端服务器上配置证书。

基础 SSL 配置

单证书配置

haproxy
frontend https_front
    bind *:443 ssl crt /etc/ssl/certs/example.com.pem
    mode http
    default_backend web_pool

证书格式可以是:

  • 合并文件(推荐):cert.pem 包含公钥 + 私钥
  • 分离文件:使用 crt + key 分别指定
haproxy
bind *:443 ssl crt /etc/ssl/certs/example.com.crt key /etc/ssl/private/example.com.key

合并 PEM 文件

bash
# 按序拼接:证书 → CA证书(可选)→ 私钥
cat server.crt ca-bundle.crt server.key > example.com.pem
chmod 600 example.com.pem

多证书(SNI 场景)

haproxy
frontend https_front
    bind *:443 ssl \
        crt /etc/ssl/certs/example.com.pem \
        crt /etc/ssl/certs/api.example.com.pem \
        crt /etc/ssl/certs/*.example.com.pem    # 通配符
    mode http

HAProxy 会根据请求的 SNI(Server Name Indication)自动匹配对应证书。

最低 TLS 版本

haproxy
global
    ssl-default-bind-options no-sslv3 no-tlsv10 no-tls-tickets
    ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384

前端 SSL 选项

haproxy
frontend https_front
    bind *:443 ssl \
        crt /etc/ssl/certs/ \
        no-sslv3 \
        no-tlsv10 \
        no-tls-tickets \
        ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256
        strict-sni
    mode http

常用参数:

参数说明
no-sslv3禁用 SSLv3(防止 POODLE 攻击)
no-tlsv10禁用 TLS 1.0
no-tls-tickets禁用 TLS Session Ticket,禁用前向保密恢复
strict-sniSNI 必传,否则拒绝连接
alpn h2,http/1.1启用 ALPN(协商 HTTP/2)

强制 HTTPS

haproxy
frontend http_front
    bind *:80
    http-request redirect scheme https if !{ ssl_fc }

或者用 redirect 通用写法:

haproxy
frontend http_front
    bind *:80
    http-request redirect code 301 location https://%[hdr(host)]%[uri] if !{ ssl_fc }

HTTP/2 配置

haproxy
frontend https_front
    bind *:443 ssl crt /etc/ssl/certs/ alpn h2,http/1.1
    mode http

⚠️ HAProxy 本身支持 HTTP/2,但后端只能使用 HTTP/1.1。HTTP/2 到后端的升级需要 http/2 后端选项或其他方案。

OCSP Stapling

自动获取并缓存证书的 OCSP 响应,减少客户端验证延迟:

haproxy
frontend https_front
    bind *:443 ssl crt /etc/ssl/certs/example.com.pem ocsp-response enable

启用前需先提取 OCSP 响应:

bash
# 安装 ocsp-updater 或手动提取
openssl ocsp \
    -no_nonce \
    -respout /tmp/ocsp-response.der \
    -issuer /etc/ssl/certs/ca.pem \
    -cert /etc/ssl/certs/example.com.pem \
    -url http://ocsp.example.com/

后端 SSL(到真实服务器)

如果后端服务器使用 HTTPS,HAProxy 需要验证并可选地转发 SSL:

haproxy
backend web_pool
    mode http
    balance roundrobin

    # 后端 SSL 配置
    server web1 192.168.1.101:443 ssl verify required ca-file /etc/ssl/certs/ca-bundle.crt
    server web2 192.168.1.102:443 ssl verify required ca-file /etc/ssl/certs/ca-bundle.crt

    # 或者跳过验证(测试环境)
    # server web1 192.168.1.101:443 ssl verify none

常用参数:

参数说明
ssl启用 SSL 到后端
verify required验证后端证书
verify none不验证(测试环境)
ca-fileCA 证书文件
check定期检查后端 SSL 连接

SSL 证书更新与重载

无需重启 HAProxy,发送 SIGUSR1 或使用 reload 即可热重载:

bash
systemctl reload haproxy
# 或
killall -USR1 haproxy

💡 如果证书 PEM 文件包含完整证书链,重载时 HAProxy 会自动刷新 OCSP 缓存。

HSTS 安全头

通过 http-response 添加 HSTS 响应头:

haproxy
frontend https_front
    bind *:443 ssl crt /etc/ssl/certs/
    mode http

    http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    http-response set-header X-Content-Type-Options nosniff
    http-response set-header X-Frame-Options SAMEORIGIN

Let's Encrypt 自动化

配合 Certbot 自动更新证书:

bash
# 安装 certbot
apt-get install -y certbot

# 生成证书(webroot 方式,需要 HAProxy 80 端口响应 .well-known)
certbot certonly --webroot -w /var/www/html -d example.com --deploy-hook "systemctl reload haproxy"

配置 HAProxy 提供 .well-known 路径:

haproxy
frontend http_front
    bind *:80
    acl is_letsencrypt path_beg /.well-known/acme-challenge/
    use_backend letsencrypt_backend if is_letsencrypt

backend letsencrypt_backend
    mode http
    server letsencrypt 127.0.0.1:8888