Skip to content

Commit d8749ff

Browse files
authored
feat: apply sliding window rate limiting (#509)
1 parent 2d16f11 commit d8749ff

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

pillar/base/haproxy.sls

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ haproxy:
7575
- {{ config.server_name }}
7676
verify_host: bugs.psf.io
7777
check: "HEAD / HTTP/1.1\\r\\nHost:\\ {{ config.server_name }}"
78+
rate_limit: {{ config.get('rate_limit', 10) }}
7879
{% endfor %}
7980

8081
moin:

salt/haproxy/config/haproxy.cfg.jinja

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ global
5252
# Lower the amount of space we reserve for header rewriting
5353
tune.maxrewrite 1024
5454

55-
5655
defaults
5756
log global
5857

@@ -117,6 +116,24 @@ frontend main
117116
bind :::80
118117
bind 127.0.0.1:19001 # This is our TLS socket.
119118

119+
# Define a stick table for all services
120+
stick-table type ipv6 size 100k expire 30s store http_req_rate(10s)
121+
# Track all requests using a single counter
122+
# We could use the 3 available (sc0,1,2) to maybe tier requests
123+
# into say <=100, 101-500, >= 501 if we needed to?
124+
http-request track-sc0 src
125+
# then create the ACL for services in haproxy.sls that have a 'rate_limit' key,
126+
# constrained to the host header using the domain key in haproxy.sls
127+
# then adds a rule to deny via HTTP 429 if the respective ACL is matched and the stick table http request rate
128+
# is higher than the 'rate_limit' from haproxy.sls pillar date
129+
{%- for service, config in haproxy.services.items() %}
130+
{%- if config.get('rate_limit') %}
131+
# Rate limit config for {{ service }}
132+
acl is_{{ service }} hdr(host) -i {% for domain in config.domains %}{{ domain }} {% endfor %}
133+
http-request deny deny_status 429 if is_{{ service }} { sc_http_req_rate(0) gt {{ config.rate_limit }} }
134+
{%- endif %}
135+
{%- endfor %}
136+
120137
# Custom logging format, this is the same as the normal "httplog" in
121138
# HAProxy except information about the TLS connection is included.
122139
log-format %ci:%cp\ [%t]\ %ft\ %b/%s\ %Tq/%Tw/%Tc/%Tr/%Tt\ %sslv/%sslc\ %ST\ %B\ %CC\ %CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ %{+Q}r

0 commit comments

Comments
 (0)