net/haproxy: refactoring for full HTTP/2 support, refs #1047 #1089

This commit is contained in:
Frank Wall
2019-09-15 22:21:18 +02:00
parent b1104aa032
commit 13b5fc0865
5 changed files with 110 additions and 14 deletions
@@ -105,6 +105,32 @@
<help><![CDATA[The number of consecutive successful health checks before a server is considered as available.]]></help>
<advanced>true</advanced>
</field>
<field>
<label>HTTP(S) settings</label>
<type>header</type>
<style>mode_table table_http</style>
</field>
<field>
<id>backend.http2Enabled</id>
<label>Enable HTTP/2</label>
<type>checkbox</type>
<help><![CDATA[Enable support for end-to-end HTTP/2 communication.]]></help>
</field>
<field>
<id>backend.http2Enabled_nontls</id>
<label>HTTP/2 without TLS</label>
<type>checkbox</type>
<help><![CDATA[Enable support for HTTP/2 even if TLS is not enabled.]]></help>
</field>
<field>
<id>backend.ba_advertised_protocols</id>
<label>Advertise Protocols (ALPN)</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<sortable>true</sortable>
<help><![CDATA[When using the TLS ALPN extension, HAProxy advertises the specified protocol list as supported on top of ALPN. TLS must be enabled.]]></help>
</field>
<field>
<label>Persistence</label>
<type>header</type>
@@ -270,11 +270,26 @@
<style>mode_table table_http</style>
</field>
<field>
<id>frontend.ssl_http2Enabled</id>
<id>frontend.http2Enabled</id>
<label>Enable HTTP/2</label>
<type>checkbox</type>
<help><![CDATA[Enable support for HTTP/2.]]></help>
</field>
<field>
<id>frontend.http2Enabled_nontls</id>
<label>HTTP/2 without TLS</label>
<type>checkbox</type>
<help><![CDATA[Enable support for HTTP/2 even if TLS (SSL offloading) is not enabled.]]></help>
</field>
<field>
<id>frontend.advertised_protocols</id>
<label>Advertise Protocols (ALPN)</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<sortable>true</sortable>
<help><![CDATA[When using the TLS ALPN extension, HAProxy advertises the specified protocol list as supported on top of ALPN. SSL offloading must be enabled.]]></help>
</field>
<field>
<id>frontend.forwardFor</id>
<label>X-Forwarded-For header</label>
@@ -443,10 +443,6 @@
<default>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</default>
<Required>N</Required>
</ssl_cipherList>
<http2Enabled type="BooleanField">
<default>0</default>
<Required>N</Required>
</http2Enabled>
<ssl_hstsEnabled type="BooleanField">
<default>1</default>
<Required>Y</Required>
@@ -667,6 +663,25 @@
<ValidationMessage>Should be a number between 1 and 8 characters, optionally followed by either "d", "h", "m", "s", "ms" or "us".</ValidationMessage>
<Required>N</Required>
</stickiness_bytesOutRatePeriod>
<http2Enabled type="BooleanField">
<default>0</default>
<Required>N</Required>
</http2Enabled>
<http2Enabled_nontls type="BooleanField">
<default>0</default>
<Required>N</Required>
</http2Enabled_nontls>
<advertised_protocols type="OptionField">
<Required>N</Required>
<default>http2,http11</default>
<Sorted>Y</Sorted>
<Multiple>Y</Multiple>
<OptionValues>
<http2>HTTP/2</http2>
<http11>HTTP/1.1</http11>
<http10>HTTP/1.0</http10>
</OptionValues>
</advertised_protocols>
<forwardFor type="BooleanField">
<default>0</default>
<Required>Y</Required>
@@ -817,6 +832,25 @@
<ValidationMessage>Please specify a value between 1 and 100.</ValidationMessage>
<Required>N</Required>
</healthCheckRise>
<http2Enabled type="BooleanField">
<default>0</default>
<Required>N</Required>
</http2Enabled>
<http2Enabled_nontls type="BooleanField">
<default>0</default>
<Required>N</Required>
</http2Enabled_nontls>
<ba_advertised_protocols type="OptionField">
<Required>N</Required>
<default>http2,http11</default>
<Sorted>Y</Sorted>
<Multiple>Y</Multiple>
<OptionValues>
<http2>HTTP/2</http2>
<http11>HTTP/1.1</http11>
<http10>HTTP/1.0</http10>
</OptionValues>
</ba_advertised_protocols>
<persistence type="OptionField">
<Required>N</Required>
<default>sticktable</default>
@@ -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();
@@ -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("") != "" %}