From 67e19ebccd67d582e8770b1608307430d1ce5570 Mon Sep 17 00:00:00 2001 From: Dmitriy Rabotyagov Date: Wed, 16 Aug 2023 10:36:58 +0200 Subject: [PATCH] Add HTTP/2 support for frontends/backends This patch implements extra variables/keys that can be used to enable HTTP/2 protocol for frontends and backends. With that patch does not add HTTP/2 support for any redirect frontends since they can not be configured to use TLS and this it will cause such redirect backends to be HTTP/2 only, which might break old clients. With that regular frontends, that are not terminating TLS can be configured to be HTTP/2 only as well as TCP backends. Change-Id: Ib14f031f3c61f31bf7aaf345a3ba635ca5fb9ff8 --- defaults/main.yml | 8 +++++++ .../h2_initial_support-99a3277939942405.yaml | 22 +++++++++++++++++++ templates/service.j2 | 9 +++++++- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/h2_initial_support-99a3277939942405.yaml diff --git a/defaults/main.yml b/defaults/main.yml index 80e2dac..921409d 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -49,6 +49,12 @@ haproxy_backup_nodes: [] haproxy_frontend_extra_raw: [] haproxy_frontend_redirect_extra_raw: "{{ haproxy_frontend_extra_raw }}" +# Default values for enabling HTTP/2 support +# Note, that while HTTP/2 will be enabled on frontends that are covered with TLS, +# backends can be configured to use HTTP/2 regardless of TLS. +haproxy_frontend_h2: True +haproxy_backend_h2: False + haproxy_service_configs: [] # Example: # haproxy_service_configs: @@ -67,6 +73,8 @@ haproxy_service_configs: [] # allow_list: # rule: "src 127.0.0.1/8 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8" # backend_name: "mybackend" +# haproxy_frontend_h2: True +# haproxy_backend_h2: False # haproxy_frontend_acls: # letsencrypt-acl: # rule: "path_beg /.well-known/acme-challenge/" diff --git a/releasenotes/notes/h2_initial_support-99a3277939942405.yaml b/releasenotes/notes/h2_initial_support-99a3277939942405.yaml new file mode 100644 index 0000000..c8e245d --- /dev/null +++ b/releasenotes/notes/h2_initial_support-99a3277939942405.yaml @@ -0,0 +1,22 @@ +--- +features: + - | + Added new keys ``haproxy_frontend_h2`` and ``haproxy_backend_h2`` + per service definition to enable HTTP/2 for a specified service. + + This also add new variables to control default behavoir for + frontends and backends: + + * ``haproxy_frontend_h2: true`` + * ``haproxy_backend_h2: false`` + + Please mention, that double stack of HTTP/1.1 and HTTP/2 is only available + for TLS protected frontends. In case frontend is just TCP + haproxy_frontend_h2 will be ignored. + + At the same time ``haproxy_backend_h2`` will be respected regardless of + TLS/plain TCP configuration. +upgrade: + - | + HTTP/2 is enabled by default for frontends that are covered with TLS. + You can disable this behaviour by setting ``haproxy_frontend_h2: false`` diff --git a/templates/service.j2 b/templates/service.j2 index 75f8d86..69bec7a 100644 --- a/templates/service.j2 +++ b/templates/service.j2 @@ -53,7 +53,7 @@ bind {{ vip_address }}:{{ service.haproxy_redirect_http_port }}{{ (vip_interface {% else %} {% set haproxy_ssl_path=haproxy_ssl_cert_path + "/haproxy_" + (haproxy_host | default(ansible_facts['hostname'])) + "-" + ((vip_interface is truthy) | ternary(vip_address ~ '-' ~ vip_interface, vip_address)) + ".pem" %} frontend {{ service.haproxy_service_name }}-front-{{ loop.index }} - bind {{ vip_address }}:{{ service.haproxy_port }}{{ (vip_interface is truthy) | ternary(' interface ' ~ vip_interface, '') }} {% if (service.haproxy_ssl | default(false) | bool) and (loop.index == 1 or vip_address in extra_lb_tls_vip_addresses or (service.haproxy_ssl_all_vips | default(false) | bool and vip_address not in extra_lb_vip_addresses)) %}ssl crt {{ service.haproxy_ssl_path | default(haproxy_ssl_path) }} {% endif %} + bind {{ vip_address }}:{{ service.haproxy_port }}{{ (vip_interface is truthy) | ternary(' interface ' ~ vip_interface, '') }} {% if (service.haproxy_ssl | default(false) | bool) and (loop.index == 1 or vip_address in extra_lb_tls_vip_addresses or (service.haproxy_ssl_all_vips | default(false) | bool and vip_address not in extra_lb_vip_addresses)) %}ssl crt {{ service.haproxy_ssl_path | default(haproxy_ssl_path) }}{% if service.haproxy_frontend_h2 | default(haproxy_frontend_h2) and request_option == "http" %} alpn h2,http/1.1{% endif %}{% endif %} {% if request_option == "http" %} option httplog @@ -156,6 +156,13 @@ backend {{ service.haproxy_service_name }}-back {% else %} {% set _ = entry.append("verify none") %} {% endif %} +{% if service.haproxy_backend_h2 | default(haproxy_backend_h2) and request_option == "http" %} +{% set _ = entry.append("alpn h2,http/1.1") %} +{% endif %} +{% else %} +{% if service.haproxy_backend_h2 | default(haproxy_backend_h2) and request_option == "http" %} +{% set _ = entry.append("proto h2") %} +{% endif %} {% endif %} {% set backend_server_options = service.haproxy_backend_server_options|default([]) %} {% for option in backend_server_options %}