HAProxy EP 4: Understanding ACL β Access Control List
Imagine you are managing a busy highway with multiple lanes, and you want to direct specific types of vehicles to particular lanes: trucks to one lane, cars to another, and motorcycles to yet another. In the world of web traffic, this is similar to what Access Control Lists (ACLs) in HAProxy doβthey help you direct incoming requests based on specific criteria.
Letβs dive into what ACLs are in HAProxy, why they are essential, and how you can use them effectively with some practical examples.
What are ACLs in HAProxy?
Access Control Lists (ACLs) in HAProxy are rules or conditions that allow you to define patterns to match incoming requests. These rules help you make decisions about how to route or manage traffic within your infrastructure.
Think of ACLs as powerful filters or guards that analyze incoming HTTP requests based on headers, IP addresses, URL paths, or other attributes. By defining ACLs, you can control how requests are handledβfor example, sending specific traffic to different backends, applying security rules, or denying access under certain conditions.
Why Use ACLs in HAProxy?
Using ACLs offers several advantages:
- Granular Control Over Traffic: You can filter and route traffic based on very specific criteria, such as the content of HTTP headers, cookies, or request methods.
- Security: ACLs can block unwanted traffic, enforce security policies, and prevent malicious access.
- Performance Optimization: By directing traffic to specific servers optimized for certain types of content, ACLs can help balance the load and improve performance.
- Flexibility and Scalability: ACLs allow dynamic adaptation to changing traffic patterns or new requirements without significant changes to your infrastructure.
How ACLs Work in HAProxy
ACLs in HAProxy are defined in the configuration file (haproxy.cfg
). The syntax is straightforward
acl <name> <criteria>
<name>
: The name you give to your ACL rule, which you will use to reference it in further configuration.<criteria>
: The condition or match pattern, such as a path, header, method, or IP address.
It either returns True or False.
Examples of ACLs in HAProxy
Letβs look at some practical examples to understand how ACLs work.
Example 1: Routing Traffic Based on URL Path
Suppose you have a web application that serves both static and dynamic content. You want to route all requests for static files (like images, CSS, and JavaScript) to a server optimized for static content, while all other requests should go to a dynamic content server.
Configuration:
frontend http_front bind *:80 acl is_static path_beg /static use_backend static_backend if is_static default_backend dynamic_backend backend static_backend server static1 127.0.0.1:5001 check backend dynamic_backend server dynamic1 127.0.0.1:5002 check
- ACL Definition:
acl is_static path_beg /static
: checks if the request URL starts with/static
. - Usage:
use_backend static_backend if is_static
routes the traffic to thestatic_backend
if the ACLis_static
matches. All other requests are routed to thedynamic_backend
.
Example 2: Blocking Traffic from Specific IP Addresses
Letβs say you want to block traffic from a range of IP addresses that are known to be malicious.
Configurations
frontend http_front bind *:80 acl block_ip src 192.168.1.0/24 http-request deny if block_ip default_backend web_backend backend web_backend server web1 127.0.0.1:5003 check
ACL Definition:acl block_ip src 192.168.1.0/24
defines an ACL that matches any source IP from the range 192.168.1.0/24
.
Usage:http-request deny if block_ip
denies the request if it matches the block_ip
ACL.
Example 4: Redirecting Traffic Based on Request Method
You might want to redirect all POST
requests to a different backend for further processing.
Configurations
frontend http_front bind *:80 acl is_post_method method POST use_backend post_backend if is_post_method default_backend general_backend backend post_backend server post1 127.0.0.1:5006 check backend general_backend server general1 127.0.0.1:5007 check
Example 5: Redirect Traffic Based on User Agent
Imagine you want to serve a different version of your website to mobile users versus desktop users. You can achieve this by using ACLs that check the User-Agent
header in the HTTP request.
Configuration:
frontend http_front bind *:80 acl is_mobile_user_agent req.hdr(User-Agent) -i -m sub Mobile use_backend mobile_backend if is_mobile_user_agent default_backend desktop_backend backend mobile_backend server mobile1 127.0.0.1:5008 check backend desktop_backend server desktop1 127.0.0.1:5009 check
ACL Definition:acl is_mobile_user_agent req.hdr(User-Agent) -i -m sub Mobile
checks if theUser-Agent
header contains the substring "Mobile" (case-insensitive).
Usage:use_backend mobile_backend if is_mobile_user_agent
directs mobile users to mobile_backend
and all other users to desktop_backend
.
Example 6: Restrict Access to Admin Pages by IP Address
Letβs say you want to allow access to the /admin
page only from a specific IP address or range, such as your companyβs internal network.
frontend http_front bind *:80 acl is_admin_path path_beg /admin acl is_internal_network src 192.168.10.0/24 http-request deny if is_admin_path !is_internal_network default_backend web_backend backend web_backend server web1 127.0.0.1:5015 check
Example with a Flask Application
Letβs see how you can use ACLs with a Flask application to enforce different rules.
Flask Application Setup
You have two Flask apps: app1.py
for general requests and app2.py
for special requests like form submissions.
app1.py
from flask import Flask app = Flask(__name__) @app.route('/') def index(): return "Welcome to the main page!" if __name__ == '__main__': app.run(host='0.0.0.0', port=5003)
app2.py:
from flask import Flask app = Flask(__name__) @app.route('/submit', methods=['POST']) def submit_form(): return "Form submitted successfully!" if __name__ == '__main__': app.run(host='0.0.0.0', port=5004)
HAProxy Configuration with ACLs
frontend http_front bind *:80 acl is_post_method method POST acl is_submit_path path_beg /submit use_backend post_backend if is_post_method is_submit_path default_backend general_backend backend post_backend server app2 127.0.0.1:5004 check backend general_backend server app1 127.0.0.1:5003 check
ACLs:
is_post_method
checks for thePOST
method.is_submit_path
checks if the path starts with/submit
.
Traffic Handling: The traffic is directed to post_backend
if both the ACLs match, otherwise, it goes to general_backend
.