HAProxy 安全加固实战:负载均衡器防护配置指南

HAProxy 安全加固是保障负载均衡层安全的关键环节。HAProxy 通常部署在流量入口处,一旦被攻击者获取管理权限或利用配置缺陷,可能导致流量劫持、配置篡改甚至后端服务被直接渗透。本教程面向在生产环境维护 HAProxy 的运维与安全人员,提供一套可直接落地的加固方案。

适用场景

本方案适用于以下场景:

  • HAProxy 直接暴露在公网,需要限制管理端口访问
  • 站点已启用 HTTPS,需要禁用弱 TLS 协议与加密套件
  • 需要限制特定来源 IP 或 User-Agent 访问后端服务
  • 需要为 stats 监控页面设置访问控制并开启审计日志

前置条件

  • 已安装 HAProxy 2.x 及以上版本,使用 haproxy -v 确认版本
  • 具备 root 或 sudo 权限,可修改 /etc/haproxy/haproxy.cfg
  • 已有合法 TLS 证书(如由 Certbot 签发)
  • 修改配置前建议执行 haproxy -c -f /etc/haproxy/haproxy.cfg 校验语法

原理说明

HAProxy 的安全风险主要来自三个方面:管理面暴露(stats 页面默认无认证且可远程访问)、传输层弱化(允许 TLS 1.0/1.1 或 RC4 等弱套件)、访问控制缺失(不限制来源即可请求后端)。加固思路是:对管理面启用 HTTP Basic Auth 并绑定本机或内网地址,对传输面强制 TLS 1.2+ 与安全套件,对业务面通过 ACL 做来源与行为限制,最后配合日志审计形成闭环。

操作步骤

步骤一:生成 stats 页面认证口令

使用 openssl 生成加密后的口令(避免明文写死在配置中):

# 生成 SHA-256 加密口令,替换 admin123 为强密码
printf "admin123" | openssl passwd -6 -salt $(openssl rand -hex 4)
# 输出类似:$6$abcd1234$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

步骤二:编写加固后的主配置

编辑 /etc/haproxy/haproxy.cfg,完整示例如下:

global
    log /dev/log local0
    maxconn 50000
    # 降低权限运行,避免 root 提权风险
    user haproxy
    group haproxy
    # stats socket 仅允许本机管理
    stats socket /var/run/haproxy.sock mode 600 level admin

defaults
    log global
    mode http
    option httplog
    option dontlognull
    timeout connect 5s
    timeout client  30s
    timeout server  30s
    # 隐藏后端服务器信息
    server-state-file /var/run/haproxy.state

# 管理页面:仅本机可访问 + Basic Auth
listen stats
    bind 127.0.0.1:8404
    mode http
    stats enable
    stats uri /stats
    stats refresh 10s
    stats auth admin:xxxxxx
    stats admin if LOCALHOST

# 前端:TLS 加固 + ACL 限制
frontend web_front
    bind *:443 ssl crt /etc/haproxy/certs/wafai.pem
    # 仅启用 TLS 1.2 与 1.3
    ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11
    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384
    # 限制后台爬虫 UA
    acl is_bad_ua hdr_sub(User-Agent) -i sqlmap nikto nmap
    http-request deny if is_bad_ua
    # 限制单个来源 IP 的并发连接
    stick-table type ip size 100k expire 30s store http_req_rate(10s)
    http-request track-sc0 src
    http-request deny if { sc_http_req_rate(0) gt 100 }
    default_backend web_back

backend web_back
    balance roundrobin
    server web1 192.168.1.10:8080 check inter 3s fall 3 rise 2
    server web2 192.168.1.11:8080 check inter 3s fall 3 rise 2

关键参数说明:stats auth 使用步骤一生成的密文;no-tlsv10/no-tlsv11 禁用旧协议;stick-table 结合 http_req_rate 实现每 IP 10 秒内最多 100 请求的限速。

步骤三:校验配置并重载

# 语法校验,出现 Errors found 需修正后再执行
haproxy -c -f /etc/haproxy/haproxy.cfg
# 平滑重载不中断连接
systemctl reload haproxy

配置验证

# 验证 TLS 版本:应仅显示 TLSv1.2 或 TLSv1.3
openssl s_client -connect 127.0.0.1:443 -tls1_1 </dev/null 2>&1 | grep -i "protocol"
# 验证 stats 页面需要认证
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8404/stats
# 未带凭据应返回 401;带凭据返回 200
curl -s -u admin:password -o /dev/null -w "%{http_code}" http://127.0.0.1:8404/stats
# 验证外部访问管理端口被拒绝(从其他主机执行)
nc -vz 你的服务器IP 8404

常见问题

FAQ 1:stats 页面无法从管理机访问怎么办?

确认 bind 地址是否为内网或本机地址(如 bind 10.0.0.5:8404),并在系统防火墙放行该端口:firewall-cmd --add-port=8404/tcp --permanent && firewall-cmd --reload。生产环境不建议将 stats 直接绑定 0.0.0.0。

FAQ 2:启用 TLS 1.3 后部分旧客户端无法访问?

可同时启用 TLS 1.2 作为兼容层,并保留 ssl-default-bind-ciphers 指定 ECDHE 系套件:ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256。若仍要兼容 TLS 1.0,需评估业务风险并至少开启 HSTS 缓解降级攻击。

总结

HAProxy 加固的核心是缩小管理面、强化传输面、收紧业务面三条主线:管理端口绑定内网并加认证,TLS 强制 1.2+ 并禁用弱套件,业务层通过 ACL 与限速表拦截异常请求。配合 haproxy -c 语法校验与平滑重载,可在不影响业务的前提下快速落地。建议将本配置纳入变更管理流程,并在每次升级 HAProxy 后重新执行验证命令。