Serve security.txt directly from haproxy

Currently security.txt file is stored and served from keystone.
It's not necessary as haproxy is able to serve static files[1].

This patch creates security_txt haproxy service responsible for
serving security.txt static file using recently implemented maps feature.

[1] https://sleeplessbeastie.eu/2020/05/11/how-to-serve-single-file-using-haproxy/

Depends-On: https://review.opendev.org/c/openstack/openstack-ansible-haproxy_server/+/880088

Change-Id: If0ec375055abedceb13a035b9c8f5107f4659f86
This commit is contained in:
Damian Dabrowski 2023-04-11 23:00:19 +02:00
parent 507cae2465
commit 73a8bdde58
3 changed files with 27 additions and 19 deletions

View File

@ -9,9 +9,8 @@ legacy compatibility reasons the file might also be placed at "/security.txt".
.. _IETF standard: https://datatracker.ietf.org/doc/html/draft-foudil-securitytxt
In OpenStack-Ansible, ``security.txt`` is implemented in haproxy as all public
endpoints reside behind it and the text file is hosted by keystone. It defaults
to directing any request paths that end with ``/security.txt`` to the text
file using an ACL rule in haproxy.
endpoints reside behind it. It defaults to directing any request paths that
end with ``/security.txt`` to the text file using an ACL rule in haproxy.
Enabling security.txt
~~~~~~~~~~~~~~~~~~~~~
@ -22,21 +21,15 @@ using OpenStack-Ansible:
#. Write the contents of the ``security.txt`` file in accordance with the
standard.
#. Define the contents of ``security.txt`` in the variable
``keystone_security_txt_content`` in the
``haproxy_security_txt_content`` in the
``/etc/openstack_deploy/user_variables.yml`` file:
.. code-block:: yaml
keystone_security_txt_content: |
haproxy_security_txt_content: |
# This is my example security.txt file
# Please see https://securitytxt.org/ for details of the specification of this file
#. Update keystone
.. code-block:: shell-session
# openstack-ansible os-keystone-install.yml
#. Update haproxy
.. code-block:: shell-session
@ -50,5 +43,4 @@ In some cases you may need to change the haproxy ACL used to redirect requests
to the ``security.txt`` file, such as adding extra domains.
The haproxy ACL is updated by overriding the variable
``haproxy_security_txt_acl`` in the
``/etc/openstack_deploy/user_variables.yml`` file.
``haproxy_map_entries`` inside ``haproxy_security_txt_service``.

View File

@ -35,11 +35,6 @@ haproxy_stick_table_allowlist_networks: "{{ haproxy_allowlist_networks }}"
haproxy_ironic_allowlist_networks: "{{ haproxy_allowlist_networks }}"
haproxy_ironic_inspector_allowlist_networks: "{{ haproxy_allowlist_networks }}"
haproxy_security_txt_acl:
keystone-security-txt-acl:
rule: "path_end /security.txt"
backend_name: keystone_service
# Variables to set security headers used by browsers
haproxy_security_headers_max_age: 31536000
# Set CSP headers to report only for testing
@ -88,6 +83,21 @@ openstack_haproxy_horizon_stick_table:
- "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_security_txt_service:
haproxy_backend_only: true
haproxy_service_name: security_txt
haproxy_backend_nodes: []
haproxy_balance_type: http
haproxy_service_enabled: "{{ haproxy_security_txt_content is truthy }}"
# https://sleeplessbeastie.eu/2020/05/11/how-to-serve-single-file-using-haproxy/
haproxy_backend_arguments:
- 'errorfile 503 /etc/haproxy/security.txt'
haproxy_map_entries:
- name: base_regex
entries:
- '.*/security.txt security_txt-back'
# haproxy 'base' frontend-only service that is used always deployed for port 80 redirect and 443
# this potentially supports horizon dashboard, security.txt and certbot
# plus any other user defined custom backend
@ -102,7 +112,6 @@ haproxy_base_service:
haproxy_service_enabled: true
haproxy_redirect_scheme: "{{ (haproxy_ssl_letsencrypt_enable | bool and haproxy_ssl | bool) | ternary('https if !{ ssl_fc } !{ path_beg /.well-known/acme-challenge/ }', 'https if !{ ssl_fc }') }}"
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_maps:
- 'use_backend %[path,map_reg(/etc/haproxy/base_regex.map)]'
@ -634,6 +643,7 @@ haproxy_zun_console_service:
haproxy_service_enabled: "{{ groups['zun_api'] is defined and groups['zun_api'] | length > 0 }}"
haproxy_default_services:
- service: "{{ haproxy_security_txt_service | combine(haproxy_security_txt_service_overrides | default({})) }}"
- service: "{{ haproxy_base_service | combine(haproxy_base_service_overrides | default({})) }}"
- service: "{{ haproxy_adjutant_api_service | combine(haproxy_adjutant_api_service_overrides | default({})) }}"
- service: "{{ haproxy_aodh_api_service | combine(haproxy_aodh_api_service_overrides | default({})) }}"

View File

@ -0,0 +1,6 @@
---
upgrade:
- |
``keystone_security_txt_content`` variable name has changed to
``haproxy_security_txt_content``. Security.txt file is now served
directly from haproxy.