1. Rate Limiting #
Rate Limiting consists of limiting the number of requests a user or an IP can make within a given time window.
Concept #
Essential for protecting APIs, Rate Limiting prevents a single client from saturating your resources, whether it is caused by a bug in a client script or a malicious denial-of-service (DoS) attempt.
HAProxy example #
HAProxy uses stick-tables to keep track of request counters.
frontend http-in
# Table of 100k entries, expiring after 30s
stick-table type ip size 100k expire 30s store http_req_rate(10s)
# Track the source IP
http-request track-sc0 src
# Deny (429 Too Many Requests) if > 20 requests in 10s
http-request deny deny_status 429 if { sc0_http_req_rate gt 20 }Traefik example #
Traefik implements this through the rateLimit middleware.
# Configuration File (YAML)
http:
middlewares:
limit-api:
rateLimit:
average: 100
period: 1m
burst: 202. Stick Tables (HAProxy) #
An advanced HAProxy feature for storing state in memory.
Why use them? #
Stick tables let you track much more than simple request rates. They can store the number of concurrent connections, the rate of HTTP errors generated by a client, or session information.
Example: blocking based on error rate #
If an IP generates too many 404 or 403 errors, it is probably scanning your application.
backend app-backend
# Store the error rate over 10s
stick-table type ip size 1m expire 1h store http_err_rate(10s)
http-request track-sc1 src
# Block the IP if it generates more than 10 errors in 10s
http-request deny if { sc1_http_err_rate gt 10 }3. Brute Force Protection #
Identifying repeated attempts to guess passwords.
Strategy #
Brute force protection usually targets sensitive entry points such as /login or /wp-login.php. A much stricter limit is applied to these URLs than to the rest of the traffic.
HAProxy example #
frontend https-in
stick-table type ip size 100k expire 1m store http_req_rate(20s)
acl is_login path_beg /login
http-request track-sc2 src if is_login
# Max 3 login attempts every 20 seconds
http-request deny if is_login { sc2_http_req_rate gt 3 }Traefik example #
Create a dedicated middleware for the router handling authentication.
http:
middlewares:
auth-bruteforce:
rateLimit:
average: 2
period: 1m
burst: 14. Anti-DDoS (Denial-of-Service Attacks) #
Preventing infrastructure saturation caused by floods of connections.
Limiting concurrent connections #
A classic DDoS attack consists of opening as many TCP connections as possible without ever closing them (Slowloris). Limiting the number of concurrent connections per IP is a fundamental protection.
HAProxy example #
Using conn_cur in a stick table.
frontend http-in
stick-table type ip size 100k expire 30s store conn_cur
tcp-request connection track-sc0 src
# Reject the connection if the IP already has 15 open connections
tcp-request connection reject if { sc0_conn_cur gt 15 }Traefik example #
Traefik provides the inFlightConn middleware.
http:
middlewares:
limit-simultaneous-conn:
inFlightConn:
amount: 10
sourceCriterion:
ipStrategy:
depth: 25. Web Application Firewall (WAF) #
A WAF performs deep inspection of HTTP traffic to block application-level attacks (OWASP Top 10).
Concept #
Unlike Rate Limiting, which relies on quantity, a WAF inspects the quality of requests. It looks for attack patterns (payloads) such as SQL injection or Cross-Site Scripting (XSS).
HAProxy example #
Integration is often done through SPOE (Stream Processing Offload Engine) to delegate analysis to an external ModSecurity agent without slowing down the main process.
frontend http-in
# Call the ModSecurity SPOE agent
filter spoe engine modsecurity config /etc/haproxy/modsec.conf
# Block (403 Forbidden) if the agent returns an attack score
http-request deny deny_status 403 if { var(txn.modsec.code) -m int gt 0 }Traefik example #
Traefik can integrate a WAF through plugins (such as modsecurity) or by using a sidecar such as Coraza.
# Example using a middleware plugin
http:
middlewares:
waf-modsec:
plugin:
modsecurity:
modsecurityUrl: http://modsecurity-agent:80806. Fail2ban and CrowdSec (Log Analysis) #
Automate banning malicious IPs by analysing logs in real time.
Concept #
Fail2ban and CrowdSec act as intrusion detection systems (IDS) based on log analysis. Their role is to identify automated malicious behaviour (brute force, vulnerability scans, application-level denial of service) that may have slipped through the first layers of defence, and to apply an automatic sanction (an IP ban).
Comparison: Fail2ban vs CrowdSec #
Although they share the same goal, their approaches differ radically:
- Fail2ban: The historical tool. It reads local log files and uses regular expressions (regex) to count failures. If a threshold is exceeded, it calls an action (often
iptables) to block the IP.- Pros: Very lightweight, stable, no external dependencies, simple to configure for basic needs.
- Cons: Local analysis only (it does not benefit from attacks suffered by others), and regexes can be CPU-hungry on very large log volumes.
- CrowdSec: A modern, collaborative approach. It uses a scenario engine to detect behaviours and relies on two key components:
- LAPI (Local API): It centralises detections from your local agents and instructs the bouncers (firewall, proxy) on the blocking actions to take within your infrastructure.
- CAPI (Central API): It receives your anonymised attack signals and sends back, in real time, the global reputation database fed by the community.
- Pros: Proactive protection, multi-layer bouncers, ideal for distributed architectures.
- Cons: More complex installation and an Internet dependency for the CAPI.
Fail2ban (example with HAProxy) #
Fail2ban monitors the HAProxy log file and bans IPs that generate too many authentication errors.
# /etc/fail2ban/jail.local
[haproxy-http-auth]
enabled = true
filter = haproxy-http-auth
logpath = /var/log/haproxy.log
maxretry = 3
bantime = 3600CrowdSec (example with HAProxy) #
For HAProxy, CrowdSec often uses a LUA bouncer that checks the IP in real time with the CrowdSec agent.
frontend http-in
# Load the CrowdSec bouncer LUA script
lua-load /var/lib/crowdsec/lua/bouncer.lua
# Call the bouncer for a check before processing
http-request lua.crowdsec_allowCrowdSec (example with Traefik) #
CrowdSec is a modern, collaborative alternative. For Traefik, a Bouncer is generally used as a middleware to block requests before they reach the backend.
# Traefik configuration (Middleware via Plugin)
http:
middlewares:
crowdsec-bouncer:
plugin:
crowdsec-bouncer:
enabled: true
crowdsecLapiHost: crowdsec-agent:8080
crowdsecLapiKey: "your_api_key"Conclusion #
The importance of defence in depth.
Going further #
In addition to local application-level protections, it is recommended to pair your architecture with third-party services (Cloudflare, AWS Shield) to handle massive volumetric attacks at the network level (Layers 3 and 4).
