From 13b5fc08651024cfd1f0299125a75df9e552ab68 Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Sun, 15 Sep 2019 22:21:18 +0200 Subject: [PATCH] net/haproxy: refactoring for full HTTP/2 support, refs #1047 #1089 --- .../OPNsense/HAProxy/forms/dialogBackend.xml | 26 ++++++++++++ .../OPNsense/HAProxy/forms/dialogFrontend.xml | 17 +++++++- .../app/models/OPNsense/HAProxy/HAProxy.xml | 42 +++++++++++++++++-- .../mvc/app/views/OPNsense/HAProxy/index.volt | 7 ++++ .../templates/OPNsense/HAProxy/haproxy.conf | 32 ++++++++++---- 5 files changed, 110 insertions(+), 14 deletions(-) diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml index 155592a74..0af01e120 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml @@ -105,6 +105,32 @@ true + + + header + + + + backend.http2Enabled + + checkbox + + + + backend.http2Enabled_nontls + + checkbox + + + + backend.ba_advertised_protocols + + select_multiple + + true + true + + header diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml index 336c7938e..3aa40fb28 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml @@ -270,11 +270,26 @@ - frontend.ssl_http2Enabled + frontend.http2Enabled checkbox + + frontend.http2Enabled_nontls + + checkbox + + + + frontend.advertised_protocols + + select_multiple + + true + true + + frontend.forwardFor diff --git a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml index eebc03b2f..bb080b736 100644 --- a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml +++ b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml @@ -443,10 +443,6 @@ ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 N - - 0 - N - 1 Y @@ -667,6 +663,25 @@ Should be a number between 1 and 8 characters, optionally followed by either "d", "h", "m", "s", "ms" or "us". N + + 0 + N + + + 0 + N + + + N + http2,http11 + Y + Y + + HTTP/2 + HTTP/1.1 + HTTP/1.0 + + 0 Y @@ -817,6 +832,25 @@ Please specify a value between 1 and 100. N + + 0 + N + + + 0 + N + + + N + http2,http11 + Y + Y + + HTTP/2 + HTTP/1.1 + HTTP/1.0 + + N sticktable diff --git a/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt b/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt index 5471daace..6cc446097 100644 --- a/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt +++ b/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt @@ -222,6 +222,13 @@ POSSIBILITY OF SUCH DAMAGE. // hook into on-show event for dialog to extend layout. $('#DialogBackend').on('shown.bs.modal', function (e) { + $("#backend\\.mode").change(function(){ + var service_id = 'table_' + $(this).val(); + $(".mode_table").hide(); + $("."+service_id).show(); + }); + $("#backend\\.mode").change(); + $("#backend\\.healthCheckEnabled").change(function(){ var service_id = 'table_healthcheck_' + $(this).is(':checked'); $(".healthcheck_table").hide(); diff --git a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf index 0bd3cef3e..b6401e74d 100644 --- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf +++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf @@ -985,6 +985,7 @@ userlist stats_auth frontend {{frontend.name}} {% set ssl_certs = [] %} {% set ssl_options = [] %} +{% set adv_options = [] %} {% if frontend.ssl_enabled == '1' %} {# # check if ssl certs are configured #} {% if frontend.ssl_certificates|default("") != "" or frontend.ssl_default_certificate|default("") != "" %} @@ -1006,8 +1007,10 @@ frontend {{frontend.name}} {% do ssl_options.append('ciphers ' ~ frontend.ssl_cipherList) %} {% endif %} {# # HTTP/2 #} -{% if frontend.ssl_http2Enabled|default("") == '1' and frontend.mode == 'http' %} -{% do ssl_options.append('alpn h2,http/1.1') %} +{% if frontend.http2Enabled|default("") == '1' and frontend.advertised_protocols|default("") != "" %} +{# # convert protocols to HAProxy-compatible format #} +{% set alpn_options = frontend.advertised_protocols|replace('http10', 'http/1.0')|replace('http11', 'http/1.1') %} +{% do ssl_options.append('alpn ' ~ alpn_options) %} {% endif %} {# # HSTS #} {% if frontend.ssl_hstsEnabled|default("") == '1' and frontend.mode == 'http' %} @@ -1039,10 +1042,12 @@ frontend {{frontend.name}} {% endif %} {% endif %} {% endif %} +{# # HTTP/2 without TLS #} +{% elif frontend.http2Enabled|default("") == '1' and frontend.http2Enabled_nontls|default("") == '1' %} +{% do adv_options.append('proto h2') %} {% endif %} {# # CPU affinity configuration #} {% set bind_process = [] %} -{% set process_thread = [] %} {% if frontend.linkedCpuAffinityRules|default('') != '' %} {% for cpu_map in frontend.linkedCpuAffinityRules.split(',') %} {% set cpu_map_data = helpers.getUUID(cpu_map) %} @@ -1050,7 +1055,7 @@ frontend {{frontend.name}} {# # Limit visibility to a certain set of processes #} {% do bind_process.append(cpu_map_data.process_id|replace('x', '')) %} {# # Restrict the list of processes/threads on which this listener is allowed to run #} -{% do process_thread.append('process ' ~ cpu_map_data.process_id|replace('x', '') ~ '/' ~ cpu_map_data.thread_id|replace('x', '')) %} +{% do adv_options.append('process ' ~ cpu_map_data.process_id|replace('x', '') ~ '/' ~ cpu_map_data.thread_id|replace('x', '')) %} {% endif %} {% endfor %} {% if bind_process|length > 0 %} @@ -1060,7 +1065,7 @@ frontend {{frontend.name}} {# # bind/listen configuration #} {% if frontend.bind|default("") != "" %} {% for bind in frontend.bind.split(",") %} - bind {{bind}} name {{bind}} {% if frontend.bindOptions|default("") != "" %}{{ frontend.bindOptions }} {% endif %}{% if frontend.ssl_enabled == '1' and ssl_certs|default("") != "" %}ssl {{ ssl_options|join(' ') }} {{ ssl_certs|join(' ') }} {% endif %}{% if process_thread|length > 0 %} {{ process_thread|join(' ') }} {% endif %} + bind {{bind}} name {{bind}} {% if frontend.bindOptions|default("") != "" %}{{ frontend.bindOptions }} {% endif %}{% if frontend.ssl_enabled == '1' and ssl_certs|default("") != "" %}ssl {{ ssl_options|join(' ') }} {{ ssl_certs|join(' ') }} {% endif %}{% if adv_options|length > 0 %} {{ adv_options|join(' ') }} {% endif %} {% endfor %} {% endif %} @@ -1259,10 +1264,10 @@ backend {{backend.name}} # health checking is DISABLED {% set healthcheck_enabled = '0' %} {% endif %} -{# # XXX: Usually the frontend and the backend are in the same mode, #} -{# # but we have no way to know what frontend uses this backend. #} -{# # Hence we can't automatically set the mode and thus need a #} -{# # (redundant) GUI option for this. #} +{# # NOTE: Usually the frontend and the backend are in the same mode, #} +{# # but we have no way to know what frontend uses this backend. #} +{# # Hence we can't automatically set the mode and thus need a #} +{# # (redundant) GUI option for this. #} mode {{backend.mode}} balance {{backend.algorithm}} {# # call macro to evaluate stickiness config #} @@ -1400,6 +1405,15 @@ backend {{backend.name}} {% else %} {% do server_options.append('verify none') %} {% endif %} +{# # HTTP/2 #} +{% if backend.http2Enabled|default("") == '1' and backend.ba_advertised_protocols|default("") != "" %} +{# # convert protocols to HAProxy-compatible format #} +{% set alpn_options = backend.ba_advertised_protocols|replace('http10', 'http/1.0')|replace('http11', 'http/1.1') %} +{% do server_options.append('alpn ' ~ alpn_options) %} +{% endif %} +{# # HTTP/2 without TLS #} +{% elif backend.http2Enabled|default("") == '1' and backend.http2Enabled_nontls|default("") == '1' %} +{% do server_options.append('proto h2') %} {% endif %} {# # source address #} {% if backend.source|default("") != "" %}