13.3.5 ACL与规则语法(http-request、use_backend)

本节聚焦 HAProxy 中 ACL(Access Control List)与规则语法的核心用法,强调 http-requestuse_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 与规则常见问题)#

  1. 规则未生效:检查 use_backend 顺序,越具体越靠前。
  2. ACL 不匹配:确认 hdr(host) 与实际 Host 头一致(注意端口与大小写)。
  3. 403/503:确认 http-request denydefault_backend 是否配置。
  4. 语法错误:使用 haproxy -c -f 检查定位行号。
  5. 反向代理后端不可达:确认后端 IP/端口与健康检查状态。

练习题(含期望结果)#

  1. 练习1:为 /api 路径创建独立后端池 api_backend,并仅允许 POST 请求。
    - 期望:非 POST 请求返回 403。
  2. 练习2:将 User-Agentcurl 的请求重定向到 /tool
    - 期望:访问首页时 302 到 /tool
  3. 练习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 命名、清晰的规则顺序与可验证的命令流程,可显著降低分流配置的维护成本与故障率。