# HAProxy SSL 配置生成器（TLS 卸载）

> 生成 HAProxy 的 TLS 配置：ssl-default-bind 套件和选项、TLS 1.2 起步、HSTS、HTTP 跳转 HTTPS，以及合并 PEM 文件的格式。

Source: https://ssl.sh/zh/tools/tls-config-generator/haproxy/
Last updated: 2026-11-10

生成 HAProxy 的全局 TLS 默认值，以及一个负责 HTTPS 卸载、带 HSTS 和 HTTP 跳转的 frontend。

[TLS 配置生成器](https://ssl.sh/zh/tools/tls-config-generator/)的 HAProxy 预设会写出 `global` 里的 TLS 默认值，以及一个负责 HTTPS 卸载、HTTP 跳转和 HSTS 的 frontend。复制到 `haproxy.cfg`，调整 backend，校验后重载。

## 示例：中级档

```text
global
    ssl-default-bind-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-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
    ssl-default-bind-options prefer-client-ciphers ssl-min-ver TLSv1.2 no-tls-tickets

frontend www
    mode http
    bind :443 ssl crt /etc/haproxy/certs/example.com.pem alpn h2,http/1.1
    bind :80
    http-request redirect scheme https code 301 unless { ssl_fc }
    http-response set-header Strict-Transport-Security "max-age=63072000; includeSubDomains"
    default_backend app

backend app
    server app1 127.0.0.1:8080
```

## 版本说明

- HAProxy 2.4 及以上、OpenSSL 1.1.1+，才有 TLS 1.3 和 `ssl-min-ver`。
- 要用 X25519MLKEM768，加上 `ssl-default-bind-curves X25519MLKEM768:X25519:prime256v1:secp384r1`（HAProxy 2.8+，链接 OpenSSL 3.5+）。
- HAProxy 2.8+ 可以在 crt-list 里用 `ocsp-update on` 自动更新 OCSP 响应，只对仍提供 OCSP 的 CA 有意义。
- 云厂商下载的 Nginx 格式证书包（证书 + 私钥）可以直接拼成 HAProxy 需要的 PEM 文件。

## 校验并重载

```bash
haproxy -c -f /etc/haproxy/haproxy.cfg && sudo systemctl reload haproxy
```

## 常见错误

- **PEM 文件里没有私钥**：HAProxy 报 “unable to load SSL private key”。把私钥追加进去，或放到证书旁边的 `.key` 文件里。
- **证书链顺序**：站点证书在前，中间证书在后，可以用[证书链补全工具](https://ssl.sh/zh/tools/chain-builder/)拿到正确的证书包。


## FAQ

**合并的 PEM 文件怎么做？**

把完整证书链和私钥拼在一起：cat fullchain.pem privkey.pem > /etc/haproxy/certs/example.com.pem，再 chmod 600。HAProxy 也支持把私钥放在同名加 .key 的单独文件里。

**多个域名怎么配？**

crt 指向一个目录（crt /etc/haproxy/certs/），HAProxy 会加载里面的所有文件，按 SNI 选择证书。

**怎么确认接受了哪些 TLS 版本？**

用 ssl.sh 的 SSL 检查测试这个 frontend，或在本地执行 openssl s_client -connect host:443 -tls1_1，中级档下 TLS 1.1 握手应该失败。
