HAProxy 高级一点儿的玩法
在上一篇文章中,我简单的介绍了 HAProxy 的功能,并且给出了两个配置示例。相信你对 HAProxy 已经有个大概的印象了。在这篇文章中,我会直接给出 HAProxy 高级一点的用法的配置示例,包含以下内容。
- TLS/SSL 配置
访问控制列表 ACL
- 流量过滤,如禁止 TRACE 方法
- ACL 的常见写法
- 根据访问路径使用指定后端服务器
- SESSION 绑定
- 修改 HTTP 请求头
- 修改 HTTP 响应头
- URL 重定向
- URL 重写
- HTTP 服务器后端状态检查
- 黑/白名单
- 错误页面
- 权重
- 统计页面
需要注意的是,这些高级用法大多数都是 HTTP 模式才有的玩法。
TLS/SSL 配置
总所周知,TLS/SSL 是非常昂贵的,建立 SSL 会话需要非常繁琐的步骤,而通信过程中还需要对数据进行加解密操作,非常的消耗 CPU 资源。因此最佳实践是通过 HAProxy 卸载 SSL,即 HAProxy 承载用户侧发过来的 SSL 流量,HAProxy 与后端服务器走 HTTP 明文协议,这样不单止可以减轻后端服务器的压力,更能减轻 HAProxy 的压力。
全局 SSL 配置
tune.ssl.default-dh-param:设置密钥交换算法的加密强度
ssl-default-bind-ciphers:设置加密套件
global tune.ssl.default-dh-param 2048 ssl-default-bind-ciphers TLSv1+HIGH:!aNULL:!eNULL:!3DES:!RC4:!CAMELLIA:!DH:!kECDHE:@STRENGTH no-sslv3 no-tlsv10
绑定 SSL 端口
frontend xxx bind :443 ssl crt /etc/haproxy/haproxy.pem ...
bind 参数还可以指定一些附加参数,诸如 ciphers,no-sslv3,no-tlsv10 等。
访问控制列表 ACL
HAProxy 的 acl 有非常强大的功能,能实现诸如“流量过滤”、“根据访问路径使用指定后端服务器”、“黑/白名单”等功能。
使用格式
acl <aclname> <criterion> [flags] [operator] <value> ...
示例1:禁止 TRACE 方法
frontend xxx
...
acl deny_trace method TRACE
http-request deny if deny_trace
...
示例2:根据访问路径使用指定后端服务器
frontend xxx
...
acl www path_beg /www
acl blog path_reg /blog
use_backend www if www
use_backend blog if blog
default_backend default
backend www
server www1 192.168.0.100:8080
server www1 192.168.0.101:8080
backend blog
server blog1 192.168.0.102:8080
server blog2 192.168.0.103:8080
backend default
server default1 192.168.0.104:8080
server default1 192.168.0.105:8080
示例3:基于主机名的虚拟主机
frontend xxx
...
acl www hdr(host) -i www.test.com
acl blog hdr(host) -i blog.test.com
use_backend www if www
use_backend blog if blog
default_backend default
...
示例4:动静分离
frontend xxx
...
acl url_static path_beg /static /images /img /css
acl url_static path_end .gif .png .jpg .css .js
acl host_www hdr_beg(host) -i www
acl host_static hdr_beg(host) -i img. video. download. ftp.
use_backend static if host_static or host_www url_static
use_backend www if host_www
...
这个例子中使用 if host_static or host_www url_static
表达式,意思是如果匹配 host_static
或 host_www url_static
规则,则使用 backend static 。
SESSION 绑定
基本用法
appsession <cookie> len <length> timeout <holdtime>
[request-learn] [prefix] [mode <path-parameters|query-string>]
示例:
appsession PHPSESSIONID len 52 timeout 3h
修改 HTTP 请求头
示例1:添加 X-Forward-For
frontend xxx
...
option forwardfor
...
示例2:添加请求头
frontend xxx
...
http-request set-header Host www.test.com
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
...
修改 HTTP 响应头
示例1:删除响应头中的 Server: xxxxx
frontend xxx
...
rspidel ^Server.*
...
示例2::修改响应头中的 Server: xxxxx
frontend xxx
...
rspirep ^Server.* Server:\ Google\ Web\ Server
...
示例3:添加响应头
frontend xxx
...
reqadd X-Proto:\ SSL if is-ssl
...
URL 重定向
示例1:跳转至 https
frontend xxx
...
redirect scheme https if !{ ssl_fc }
...
示例2:访问特定页面重定向到首页
frontend xxx
...
acl missing_slash path_reg ^/article/[^/]*$
redirect code 301 prefix / drop-query append-slash if missing_slash
...
URL 重写
示例1:
frontend xxx
...
acl p_ext_jpg path_end -i .jpg
acl p_folder_images path_beg -i /images/
http-request set-path /images/%[path] if !p_folder_images p_ext_jpg
HTTP 服务器后端状态检查
示例:
backend xxx
option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
黑/白名单
示例1:白名单
backend zabbix
mode http
tcp-request content accept if { src 125.89.67.178 }
tcp-request content reject
示例2:黑名单
frontend xxxx
...
acl denylist src 125.89.67.178
http-request deny if denylist
...
错误页面
示例:
defaults
...
errorfile 400 /etc/haproxy/errorfiles/400badreq.http
errorfile 408 /dev/null # workaround Chrome pre-connect bug
errorfile 403 /etc/haproxy/errorfiles/403forbid.http
errorfile 503 /etc/haproxy/errorfiles/503sorry.http
权重
示例:
backend xxxx
...
server www1 192.168.0.100:8080 weight 3
server www1 192.168.0.100:8080 weight 1
统计页面
示例:
backend stats_auth
stats enable
stats auth admin:AdMiN123
stats admin if TRUE