13.6.1 SSL终止原理与部署模式
在HAProxy中,SSL终止指由HAProxy承担TLS握手与解密,将明文HTTP转发到后端,从而集中证书管理、降低后端CPU消耗并统一安全策略。其核心在于边界层完成加解密与连接复用,后端仅处理业务流量。终止后的链路需结合信任边界进行风险评估,必要时通过内网加密或双向认证补强。
原理草图(边界与加密责任划分):
常见部署模式:
- 前端SSL终止:客户端到HAProxy为TLS,HAProxy到后端为HTTP。适用于内网可信、追求性能与简化配置的场景。
- 端到端加密(TLS透传/再加密):客户端到HAProxy为TLS,HAProxy到后端仍为TLS,可在HAProxy进行SNI分发与ACL控制。适用于合规要求或跨不可信网络的场景。
- 混合模式:关键路径后端启用TLS,其余走HTTP,按服务敏感度分级。
典型流量路径与职责边界:
- 客户端:完成TLS握手、证书校验、SNI指示目标站点。
- HAProxy:终止SSL、选择后端、执行ACL与限速、记录日志与审计。
- 后端服务:处理业务请求,可选再次加密或双向认证。
示例:生成测试证书并部署SSL终止(单证书)
# 1) 生成自签证书(测试)
sudo mkdir -p /etc/haproxy/certs
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/haproxy/certs/site.key \
-out /etc/haproxy/certs/site.crt \
-subj "/C=CN/ST=Beijing/L=Beijing/O=Ops/OU=IT/CN=www.example.com"
# 2) 合并证书与私钥为HAProxy需要的PEM
sudo cat /etc/haproxy/certs/site.crt /etc/haproxy/certs/site.key \
| sudo tee /etc/haproxy/certs/site.pem > /dev/null
# 3) 权限最小化
sudo chmod 600 /etc/haproxy/certs/site.pem
示例:HAProxy配置(SSL终止+HTTP后端)
# /etc/haproxy/haproxy.cfg
global
log /dev/log local0
maxconn 20000
tune.ssl.default-dh-param 2048
defaults
mode http
timeout connect 5s
timeout client 30s
timeout server 30s
option httplog
frontend fe_https
bind *:443 ssl crt /etc/haproxy/certs/site.pem
http-request set-header X-Forwarded-Proto https
default_backend be_app
backend be_app
balance roundrobin
server app1 10.0.0.11:8080 check
server app2 10.0.0.12:8080 check
配置说明(关键命令解释):
- bind *:443 ssl crt ...:在443端口启用TLS并加载证书。
- X-Forwarded-Proto:告知后端原始协议,便于重定向与日志。
- check:启用健康检查,避免转发到故障节点。
示例:端到端加密(HAProxy再加密到后端)
# /etc/haproxy/haproxy.cfg
frontend fe_https
bind *:443 ssl crt /etc/haproxy/certs/site.pem
default_backend be_tls
backend be_tls
balance leastconn
server app1 10.0.0.21:8443 ssl verify none check
server app2 10.0.0.22:8443 ssl verify none check
说明:ssl verify none 仅用于测试。生产环境应启用CA校验(详见“证书管理与自动化更新”小节)。
安装与启停(以systemd为例)
# 安装(不同发行版包名可能略有差异)
sudo apt-get install -y haproxy # Debian/Ubuntu
# sudo yum install -y haproxy # RHEL/CentOS
# 启动与查看状态
sudo systemctl enable --now haproxy
sudo systemctl status haproxy
验证与测试
# 1) 验证配置语法
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
# 2) 使用curl验证TLS终止与后端转发
curl -k https://www.example.com/
# 3) 查看前端是否监听
ss -lntp | grep ':443'
常见故障排查
# 1) 证书格式错误(PEM缺少私钥)
# 现象:HAProxy启动失败
# 检查证书是否包含私钥
openssl pkey -in /etc/haproxy/certs/site.pem -noout
# 2) 后端连接失败
# 现象:503/504
# 检查健康检查状态
sudo journalctl -u haproxy | tail -n 50
# 或在配置中启用 stats 查看后端健康
# 3) TLS版本不兼容
# 现象:客户端握手失败
# 检查客户端支持的协议与密码套件
openssl s_client -connect www.example.com:443 -tls1_2
练习
1. 为两个域名配置SNI证书分发,验证不同域名返回不同证书(使用openssl s_client -servername)。
2. 将后端HTTP改为HTTPS并启用verify required,完成CA校验。
3. 配置http-request redirect scheme https,实现80端口到443的强制跳转并测试效果。