TL;DR — Quick Summary

Master HAProxy ACLs for flexible traffic routing. Learn how to block IPs, route by domain, path, or HTTP headers, and secure your backend servers.

What are HAProxy ACLs?

In HAProxy, Access Control Lists (ACLs) are the foundation of intelligent traffic routing and security. While a basic load balancer simply forwards traffic round-robin, ACLs allow HAProxy to inspect incoming requests (IP, headers, paths) and make decisions:

  • Routing: Send /api traffic to one group of servers, and /blog to another.
  • Security: Block malicious IP addresses or deny access to admin panels.
  • Redirection: Redirect HTTP to HTTPS or redirect outdated domains.

ACL Syntax Basics

An ACL declaration looks like this:

acl <aclname> <criterion> [flags] [operator] <value>
  • aclname: A custom name you choose (e.g., is_api, bad_ip).
  • criterion: What data to check (e.g., hdr(host) for domain, path_beg for URL path, src for client IP).
  • flags: Modifiers (e.g., -i for case-insensitive).
  • value: The pattern to match against.

Common ACL Use Cases

1. Host-Based Routing (Virtual Hosts)

Route traffic depending on the domain name requested.

frontend main_frontend
    bind *:80

    # Define ACLs
    acl is_blog hdr(host) -i blog.example.com
    acl is_api  hdr(host) -i api.example.com

    # Actions based on ACLs
    use_backend blog_servers if is_blog
    use_backend api_servers  if is_api
    
    # Default fallback
    default_backend web_servers

2. Path-Based Routing

Route traffic based on the URL path.

frontend main_frontend
    bind *:80

    # Match paths that begin with /api
    acl app_api path_beg /api/
    # Match paths that end with image extensions
    acl app_static path_end .jpg .png .css .js

    use_backend api_servers    if app_api
    use_backend static_servers if app_static
    default_backend web_servers

3. IP Blocking and Whitelisting

Protect sensitive areas or block known bad IPs.

frontend main_frontend
    bind *:80

    # Define ACL for an admin path
    acl is_admin_path path_beg /admin
    
    # Define ACL for allowed office IPs
    acl is_office_ip src 192.168.100.0/24 10.0.0.5

    # Deny access to /admin if the IP is NOT (-m) from the office
    http-request deny if is_admin_path !is_office_ip

    # Block a specific bad IP globally
    acl blocked_ip src 203.0.113.50
    http-request deny if blocked_ip

4. HTTP to HTTPS Redirection

A classic ACL use case to force secure connections.

frontend http_in
    bind *:80
    
    # Redirection rule
    http-request redirect scheme https code 301 if !{ ssl_fc }

(Note: !{ ssl_fc } is an inline anonymous ACL meaning “if not an SSL frontend connection”)

5. Routing by User-Agent

Route mobile users to specific backend servers or block bad bots.

frontend main_frontend
    bind *:80

    acl is_mobile hdr_sub(User-Agent) -i android iphone
    use_backend mobile_servers if is_mobile
    
    acl is_bad_bot hdr_sub(User-Agent) -i curl wget
    http-request deny if is_bad_bot

Applying and Testing Changes

Always validate your HAProxy configuration before reloading the service. A syntax error will cause traffic to drop.

# Check configuration syntax
sudo haproxy -c -f /etc/haproxy/haproxy.cfg

# If it returns "Configuration file is valid", reload HAProxy smoothly
sudo systemctl reload haproxy

ACL Combination Logic

You can combine multiple ACLs using logical operators:

  • AND: Automatically implied if you list multiple ACL names back-to-back.
  • OR: Explicitly defined using ||.
  • NOT: Explicitly defined using !.
# Example: If path is /admin AND IP is NOT office OR User-Agent is bot
http-request deny if is_admin_path !is_office_ip || is_bad_bot

Summary

  • ACLs extract request data, match it against rules, and trigger actions.
  • Use hdr(host) for domains, path_beg for URLs, and src for IPs.
  • Actions like use_backend, http-request deny, and http-request redirect rely on ACLs to function.
  • Always test configuration syntax with haproxy -c before reloading.