HAProxy 的安装和使用
HAProxy 是一个可靠高性能的负载均衡器、反向代理服务器
安装 HAProxy #
apt update && apt install haproxy -y
## 检查安装
haproxy -v
SSL 直通 #
通过前置监听 443 端口,将客户端流量代理到不同的后端。此配置不处理 SSL 证书,SSL 证书的配置、拆包和解密由后端服务处理。
global
log stdout format raw daemon notice
user root
group root
daemon
defaults
log global
timeout connect 10s
timeout client 30s
timeout server 30s
frontend ft_main
mode tcp
option tcplog
bind *:443
tcp-request inspect-delay 3s
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend exp1.com if { req.ssl_sni -i exp1.com }
use_backend exp2.com if { req.ssl_sni -i exp2.com }
backend exp1.com
mode tcp
server s1 127.0.0.1:8000
backend exp2.com
mode tcp
## 多个 server 轮询
server s1 127.0.0.1:8001
server s2 127.0.0.1:8002
SSL 直通工作在 tcp 模式下,默认传递给后端的客户端 IP 是127.0.0.1,如果需要传递真实客户端 IP,可以使用 Proxy Protocol,对应参数是send-proxy
backend exp1.com
mode tcp
server s1 127.0.0.1:8000 send-proxy ## send-proxy-v2
前端 HAProxy 发送了 Proxy Protocol,你需要在后端配置接收,这里以 Nginx 为例
server {
listen 8000 ssl proxy_protocol;
server_name exp1.com;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
ssl_certificate /path/cert.pem;
ssl_certificate_key /path/key.pem;
...
}
SSL 终止 #
此配置由 HAProxy 处理 SSL 证书,将解密后的流量代理到后端
global
log stdout format raw daemon notice
user root
group root
daemon
# https://ssl-config.mozilla.org/
ssl-default-bind-curves X25519:prime256v1:secp384r1
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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-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
ssl-default-server-curves X25519:prime256v1:secp384r1
ssl-default-server-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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-server-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
timeout connect 10s
timeout client 30s
timeout server 30s
frontend ft_main
mode http
option httplog
bind *:443 ssl crt /etc/haproxy/certs/
use_backend exp1.com if { req.ssl_sni -i exp1.com }
use_backend exp2.com if { req.ssl_sni -i exp2.com }
backend exp1.com
mode http
server s1 127.0.0.1:8001
backend exp2.com
mode http
server s1 127.0.0.1:8002
/etc/haproxy/certs/为 SSL 证书存放目录,你可以使用cat命令将证书和私钥保存到一个文件里面,然后放进这个目录,HAProxy 会根据 sni 选择对应的文件名使用证书。
cat cert.pem key.pem > exp.com.pem
在客户端和 HAProxy 之间启用 HTTP2(首选H2)
frontend ft_main
mode http
bind *:443 ssl crt /etc/haproxy/certs/ alpn h2,http/1.1
use_backend exp1.com if { req.ssl_sni -i exp1.com }
use_backend exp2.com if { req.ssl_sni -i exp2.com }
SSL 终止在 http 模式下工作,传递真实客户端 IP 可以使用X-Forwarded-For,对应参数是option forwardfor
backend exp1.com
mode http
option forwardfor
server s1 127.0.0.1:8000
同时使用 SSL 直通和 SSL 终止 #
设想一下,你在 HAProxy 前置监听 443 的情况下,后端一部分服务需要后端自行处理 SSL,一部分需要前置的 HAProxy 处理 SSL,这时候应该怎么做?具体实现做了个流程图

global
log stdout format raw daemon notice
user root
group root
daemon
# https://ssl-config.mozilla.org/
ssl-default-bind-curves X25519:prime256v1:secp384r1
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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-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
ssl-default-server-curves X25519:prime256v1:secp384r1
ssl-default-server-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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-server-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
timeout connect 10s
timeout client 30s
timeout server 30s
frontend ft_main
mode tcp
option tcplog
bind *:443
tcp-request inspect-delay 3s
tcp-request content accept if { req.ssl_hello_type 1 }
## SSL 直通
use_backend exp1.com if { req.ssl_sni -i exp1.com }
use_backend exp2.com if { req.ssl_sni -i exp2.com }
## SSL 终止
use_backend bk_haproxy_ssl if { req.ssl_sni -i exp3.com }
use_backend bk_haproxy_ssl if { req.ssl_sni -i exp4.com }
backend bk_haproxy_ssl
mode tcp
server s1 127.0.0.1:8443 send-proxy-v2
frontend ft_ssl_termination
mode http
option httplog
bind *:8443 ssl crt /etc/haproxy/certs/ alpn h2,http/1.1 accept-proxy
use_backend exp3.com if { hdr(host) -i exp3.com }
use_backend exp4.com if { hdr(host) -i exp4.com }
backend exp1.com
mode tcp
server s1 127.0.0.1:8001 send-proxy
backend exp2.com
mode tcp
server s1 127.0.0.1:8002
backend exp3.com
mode http
option forwardfor
server s1 127.0.0.1:8003
backend exp4.com
mode http
option forwardfor
server s1 127.0.0.1:8004
启用 HAProxy 统计页面 #
HAProxy 自带了个信息统计页面,启用方法:
frontend ft_stats
mode http
bind *:8005
stats enable
stats uri /stats ## 配置访问网址根目录
stats refresh 60s
stats auth user:passwd ## 配置访问密码
其他 #
- 测试配置文件
haproxy -c -V -f /etc/haproxy/haproxy.cfg