Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: apply sliding window rate limiting #509

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions pillar/base/haproxy.sls
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ haproxy:
- {{ config.server_name }}
verify_host: bugs.psf.io
check: "HEAD / HTTP/1.1\\r\\nHost:\\ {{ config.server_name }}"
rate_limit: {{ config.get('rate_limit', 10) }}
{% endfor %}

moin:
Expand Down
19 changes: 18 additions & 1 deletion salt/haproxy/config/haproxy.cfg.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ global
# Lower the amount of space we reserve for header rewriting
tune.maxrewrite 1024


defaults
log global

Expand Down Expand Up @@ -117,6 +116,24 @@ frontend main
bind :::80
bind 127.0.0.1:19001 # This is our TLS socket.

# Define a stick table for all services
stick-table type ipv6 size 100k expire 30s store http_req_rate(10s)
# Track all requests using a single counter
# We could use the 3 available (sc0,1,2) to maybe tier requests
# into say <=100, 101-500, >= 501 if we needed to?
http-request track-sc0 src
# then create the ACL for services in haproxy.sls that have a 'rate_limit' key,
# constrained to the host header using the domain key in haproxy.sls
# then adds a rule to deny via HTTP 429 if the respective ACL is matched and the stick table http request rate
# is higher than the 'rate_limit' from haproxy.sls pillar date
{%- for service, config in haproxy.services.items() %}
{%- if config.get('rate_limit') %}
# Rate limit config for {{ service }}
acl is_{{ service }} hdr(host) -i {% for domain in config.domains %}{{ domain }} {% endfor %}
http-request deny deny_status 429 if is_{{ service }} { sc_http_req_rate(0) gt {{ config.rate_limit }} }
{%- endif %}
{%- endfor %}

# Custom logging format, this is the same as the normal "httplog" in
# HAProxy except information about the TLS connection is included.
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
Expand Down
Loading