Add default rate-limits for API endpoints and Horizon authentication
This patch adds rate limiting for any API call which results in a 4xx response by applying a common stick-table to each HAProxy backend definition. The stick table can be overridden to allow customisation of the behaviour. An additional stick-table is defined for the Horizon endpoint to enforce a 20-requests-per-10s-per-source-ip sliding window limit on the horizon /auth path. This provides some protection against credential stuffing attacks and will generate 429 response codes to the client and in the HAProxy log. The log could be used by an alerting system to detect potentially malicious traffic. The defined rate limit does not include traffic from rfc1918 addresses and this should be reviewed and overridden as necessary to protect the external API endpoint. Depends-On: https://review.opendev.org/c/openstack/openstack-ansible-haproxy_server/+/848657 Change-Id: I02ed08f9d3d12f7ad2e5dd3a45a699d766933877
This commit is contained in:
parent
8e50bfc565
commit
2ec6709eee
@ -31,6 +31,7 @@ haproxy_galera_allowlist_networks: "{{ haproxy_allowlist_networks }}"
|
||||
haproxy_nova_metadata_allowlist_networks: "{{ haproxy_allowlist_networks }}"
|
||||
haproxy_rabbitmq_management_allowlist_networks: "{{ haproxy_allowlist_networks }}"
|
||||
haproxy_opendaylight_allowlist_networks: "{{ haproxy_allowlist_networks }}"
|
||||
haproxy_stick_table_allowlist_networks: "{{ haproxy_allowlist_networks }}"
|
||||
|
||||
haproxy_security_txt_acl:
|
||||
keystone-security-txt-acl:
|
||||
@ -50,6 +51,27 @@ haproxy_security_headers:
|
||||
- 'http-response set-header Referrer-Policy "same-origin"'
|
||||
- 'http-response set-header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(self), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), navigation-override=(self), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(self), clipboard-write=(self), gamepad=(), speaker-selection=()"'
|
||||
|
||||
# haproxy default stick table
|
||||
# returns 429 when more than 20 4xx responses per 10 second window
|
||||
# from external IP addresses. Override as necessary.
|
||||
openstack_haproxy_stick_table:
|
||||
- "stick-table type ipv6 size 256k expire 10s store http_err_rate(10s)"
|
||||
- "http-request track-sc0 src"
|
||||
- "http-request deny deny_status 429 if { sc_http_err_rate(0) gt 20 } !{ src {{haproxy_stick_table_allowlist_networks | join(' } !{ src ') }} }"
|
||||
|
||||
# apply the stick table as default for all backends
|
||||
haproxy_stick_table: "{{ openstack_haproxy_stick_table }}"
|
||||
|
||||
# special haproxy stick table for horizon
|
||||
# returns 429 when more than 20 calls to /auth per 10 second window
|
||||
# returns 429 when more than 20 4xx responses per 10 second window
|
||||
# from external IP addresses. Override as necessary.
|
||||
openstack_haproxy_horizon_stick_table:
|
||||
- "stick-table type ipv6 size 256k expire 10s store http_req_rate(10s),http_err_rate(10s)"
|
||||
- "http-request track-sc0 src"
|
||||
- "http-request deny deny_status 429 if { sc_http_req_rate(0) gt 20 } { path_beg /auth } !{ src {{haproxy_stick_table_allowlist_networks | join(' } !{ src ') }} }"
|
||||
- "http-request deny deny_status 429 if { sc_http_err_rate(0) gt 20 } !{ src {{haproxy_stick_table_allowlist_networks | join(' } !{ src ') }} }"
|
||||
|
||||
haproxy_adjutant_api_service:
|
||||
haproxy_service_name: adjutant_api
|
||||
haproxy_backend_nodes: "{{ groups['adjutant_api'] | default([]) }}"
|
||||
@ -211,6 +233,7 @@ haproxy_horizon_service:
|
||||
haproxy_frontend_acls: "{{ (haproxy_ssl_letsencrypt_enable | bool and haproxy_ssl | bool) | ternary(haproxy_ssl_letsencrypt_acl, {}) }}"
|
||||
haproxy_acls: "{{ keystone_security_txt_content is defined | ternary(haproxy_security_txt_acl, {}) }}"
|
||||
haproxy_frontend_raw: "{{ (haproxy_ssl | bool and haproxy_security_headers is defined) | ternary( haproxy_security_headers + [ haproxy_horizon_csp | default(haproxy_security_headers_csp)], []) }}"
|
||||
haproxy_stick_table: "{{ openstack_haproxy_horizon_stick_table }}"
|
||||
|
||||
haproxy_ironic_api_service:
|
||||
haproxy_service_name: ironic_api
|
||||
|
Loading…
x
Reference in New Issue
Block a user