13.3.5 ACL与规则语法(http-request、use_backend)
本节聚焦 HAProxy 中 ACL(Access Control List)与规则语法的核心用法,强调 http-request 与 use_backend 在请求识别、分流与安全控制中的组合应用,并提供可执行示例、排错与练习。
原理草图:ACL 评估与规则执行顺序#
安装与环境准备(示例)#
# Ubuntu/Debian
sudo apt update
sudo apt install -y haproxy
# CentOS/RHEL
sudo yum install -y haproxy
# 查看版本
haproxy -v
命令解释:
- haproxy -v:确认 HAProxy 版本与编译特性,便于判断 ACL 功能支持情况。
ACL 基础语法与可执行示例#
配置文件路径示例:/etc/haproxy/haproxy.cfg
global
log /dev/log local0
maxconn 2000
defaults
mode http
timeout connect 5s
timeout client 30s
timeout server 30s
log global
frontend http_in
bind *:80
# ACL 定义
acl host_api hdr(host) -i api.example.com
acl host_web hdr(host) -i www.example.com
acl path_admin path_beg /admin
acl is_post method POST
acl from_office src 10.0.0.0/24
acl bad_ua hdr_sub(User-Agent) -i bot
# http-request 规则:安全与改写
http-request deny if bad_ua
http-request deny if path_admin !from_office
http-request set-header X-Forwarded-Proto http
# use_backend 分流
use_backend api_backend if host_api
use_backend web_backend if host_web
default_backend default_backend
backend api_backend
balance roundrobin
server api1 10.0.1.10:8080 check
server api2 10.0.1.11:8080 check
backend web_backend
balance roundrobin
server web1 10.0.2.10:8080 check
server web2 10.0.2.11:8080 check
backend default_backend
server default1 10.0.3.10:8080 check
http-request 常见动作示例(含说明)#
frontend http_in
bind *:80
acl is_https ssl_fc
acl bad_ua hdr_sub(User-Agent) -i bot
acl path_old path_beg /old
# 拒绝恶意 UA
http-request deny if bad_ua
# 重定向旧路径
http-request redirect location /new if path_old
# 强制标记协议
http-request set-header X-Forwarded-Proto https if is_https
说明:
- deny:直接返回 403。
- redirect location /new:客户端跳转到新路径。
- set-header:为后端应用传递协议信息。
use_backend 组合条件与优先级#
frontend http_in
bind *:80
acl host_api hdr(host) -i api.example.com
acl host_web hdr(host) -i www.example.com
acl path_img path_beg /img
acl is_admin path_beg /admin
# 优先命中更具体规则
use_backend api_backend if host_api
use_backend img_backend if host_web path_img
use_backend admin_backend if host_web is_admin
use_backend web_backend if host_web
default_backend default_backend
backend img_backend
server img1 10.0.2.20:8080 check
backend admin_backend
server admin1 10.0.2.30:8080 check
配置检查、重载与验证#
# 语法检查
haproxy -c -f /etc/haproxy/haproxy.cfg
# 解释:-c 仅检查配置;-f 指定配置文件
# 平滑重载(systemd)
sudo systemctl reload haproxy
# 查看服务状态
sudo systemctl status haproxy
验证请求分流:
# API 域名应命中 api_backend
curl -H "Host: api.example.com" http://<haproxy_ip>/
# Web 域名应命中 web_backend
curl -H "Host: www.example.com" http://<haproxy_ip>/
# 管理路径且非办公网应拒绝
curl -H "Host: www.example.com" http://<haproxy_ip>/admin
排错清单(ACL 与规则常见问题)#
- 规则未生效:检查
use_backend顺序,越具体越靠前。 - ACL 不匹配:确认
hdr(host)与实际 Host 头一致(注意端口与大小写)。 - 403/503:确认
http-request deny与default_backend是否配置。 - 语法错误:使用
haproxy -c -f检查定位行号。 - 反向代理后端不可达:确认后端 IP/端口与健康检查状态。
练习题(含期望结果)#
- 练习1:为
/api路径创建独立后端池api_backend,并仅允许POST请求。
- 期望:非 POST 请求返回 403。 - 练习2:将
User-Agent含curl的请求重定向到/tool。
- 期望:访问首页时 302 到/tool。 - 练习3:将办公网
10.0.0.0/24访问/admin放行,其它来源拒绝。
- 期望:办公网 200,其他来源 403。
参考实现(可直接放入 frontend):
acl path_api path_beg /api
acl is_post method POST
http-request deny if path_api !is_post
acl ua_curl hdr_sub(User-Agent) -i curl
http-request redirect location /tool if ua_curl
acl path_admin path_beg /admin
acl from_office src 10.0.0.0/24
http-request deny if path_admin !from_office
use_backend api_backend if path_api
小结#
ACL 定义“条件”,规则定义“动作”,二者组合是 HAProxy 进行精细流量治理的核心。通过规范化的 ACL 命名、清晰的规则顺序与可验证的命令流程,可显著降低分流配置的维护成本与故障率。