mirror of
https://github.com/opnsense/plugins.git
synced 2026-05-28 04:34:15 -04:00
net/haproxy: support stick-table in frontends for #202
This commit is contained in:
parent
f171deba9f
commit
d060107a49
3 changed files with 244 additions and 42 deletions
|
|
@ -208,6 +208,87 @@
|
|||
<type>checkbox</type>
|
||||
<help><![CDATA[Enable insertion of the X-Forwarded-For header to requests sent to servers.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<label>Stickiness table</label>
|
||||
<type>header</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.stickiness_pattern</id>
|
||||
<label>Table type</label>
|
||||
<type>dropdown</type>
|
||||
<help><![CDATA[Choose the type of data that should be stored in this stick-table. Note that this stickiness table cannot be used for session persistence, it is only used to store additional per-connection data (select below). See the <a target="_blank" href="http://cbonte.github.io/haproxy-dconv/configuration-1.7.html#stick-table">HAProxy documentation</a> for further information.]]></help>
|
||||
<hint>Choose a stick-table type.</hint>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.stickiness_dataTypes</id>
|
||||
<label>Stored data types</label>
|
||||
<type>select_multiple</type>
|
||||
<style>tokenize</style>
|
||||
<help><![CDATA[This is used to store additional information in the stick-table. It may be used by ACLs in order to control various criteria related to the activity of the client matching the stick-table. Note that this directly impacts memory usage. See the <a target="_blank" href="http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#stick-table">HAProxy documentation</a> for a full description.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.stickiness_expire</id>
|
||||
<label>Expiration time</label>
|
||||
<type>text</type>
|
||||
<help><![CDATA[Enter a number followed by one of the supported suffixes "d" (days), "h" (hour), "m" (minute), "s" (seconds), "ms" (miliseconds). This configures the maximum duration of an entry in the stick-table since it was last created, refreshed or matched. The maximum duration is slightly above 24 days.]]></help>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.stickiness_size</id>
|
||||
<label>Size</label>
|
||||
<type>text</type>
|
||||
<help><![CDATA[Enter a number followed by one of the supported suffixes "k", "m", "g". This configures the maximum number of entries that can fit in the table. This value directly impacts memory usage. Count approximately 50 bytes per entry, plus the size of a string if any.]]></help>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.stickiness_length</id>
|
||||
<label>Max. data length</label>
|
||||
<type>text</type>
|
||||
<help><![CDATA[Specify the maximum length for a value in the stick-table. If the value is larger than this value it will be truncated before being stored. Depending on the stick-table type this repesents either characters or bytes.]]></help>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.stickiness_connRatePeriod</id>
|
||||
<label>Connection rate period</label>
|
||||
<type>text</type>
|
||||
<help><![CDATA[The length of the period over which the average is measured. It reports the average incoming connection rate over that period, in connections per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.stickiness_sessRatePeriod</id>
|
||||
<label>Session rate period</label>
|
||||
<type>text</type>
|
||||
<help><![CDATA[The length of the period over which the average is measured. It reports the average incoming session rate over that period, in sessions per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.stickiness_httpReqRatePeriod</id>
|
||||
<label>HTTP request rate period</label>
|
||||
<type>text</type>
|
||||
<help><![CDATA[The length of the period over which the average is measured. It reports the average HTTP request rate over that period, in requests per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.stickiness_httpErrRatePeriod</id>
|
||||
<label>HTTP error rate period</label>
|
||||
<type>text</type>
|
||||
<help><![CDATA[The length of the period over which the average is measured. It reports the average HTTP request error rate over that period, in requests per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.stickiness_bytesInRatePeriod</id>
|
||||
<label>Bytes in rate period</label>
|
||||
<type>text</type>
|
||||
<help><![CDATA[The length of the period over which the average is measured. It reports the average incoming bytes rate over that period, in bytes per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>frontend.stickiness_bytesOutRatePeriod</id>
|
||||
<label>Bytes out rate period</label>
|
||||
<type>text</type>
|
||||
<help><![CDATA[The length of the period over which the average is measured. It reports the average outgoing bytes rate over that period, in bytes per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<label>Advanced settings</label>
|
||||
<type>header</type>
|
||||
|
|
|
|||
|
|
@ -411,6 +411,91 @@
|
|||
<default>0</default>
|
||||
<Required>Y</Required>
|
||||
</logging_socketStats>
|
||||
<stickiness_pattern type="OptionField">
|
||||
<Required>N</Required>
|
||||
<OptionValues>
|
||||
<ipv4>only store IPv4 addresses [default]</ipv4>
|
||||
<ipv6>only store IPv6 addresses</ipv6>
|
||||
<integer>store 32bit integers</integer>
|
||||
<string>store substrings (max. 32 characters)</string>
|
||||
<binary>store binary blocks (max. 32 characters)</binary>
|
||||
</OptionValues>
|
||||
</stickiness_pattern>
|
||||
<stickiness_dataTypes type="OptionField">
|
||||
<Required>N</Required>
|
||||
<Multiple>Y</Multiple>
|
||||
<OptionValues>
|
||||
<conn_cnt>Connection count</conn_cnt>
|
||||
<conn_cur>Current connections</conn_cur>
|
||||
<conn_rate>Connection rate</conn_rate>
|
||||
<sess_cnt>Session count</sess_cnt>
|
||||
<sess_rate>Session rate</sess_rate>
|
||||
<http_req_cnt>HTTP request count</http_req_cnt>
|
||||
<http_req_rate>HTTP request rate</http_req_rate>
|
||||
<http_err_cnt>HTTP error count</http_err_cnt>
|
||||
<http_err_rate>HTTP error rate</http_err_rate>
|
||||
<bytes_in_cnt>Bytes in count (client to server)</bytes_in_cnt>
|
||||
<bytes_in_rate>Bytes in rate (client to server)</bytes_in_rate>
|
||||
<bytes_out_cnt>Bytes out count (server to client)</bytes_out_cnt>
|
||||
<bytes_out_rate>Bytes out rate (server to client)</bytes_out_rate>
|
||||
</OptionValues>
|
||||
</stickiness_dataTypes>
|
||||
<stickiness_expire type="TextField">
|
||||
<Required>Y</Required>
|
||||
<default>30m</default>
|
||||
<mask>/^([0-9]{1,5}(?:ms|s|m|h|d)?)/u</mask>
|
||||
<ChangeCase>lower</ChangeCase>
|
||||
<ValidationMessage>Should be a number between 1 and 5 characters followed by either "d", "h", "m", "s" or "ms".</ValidationMessage>
|
||||
</stickiness_expire>
|
||||
<stickiness_size type="TextField">
|
||||
<Required>Y</Required>
|
||||
<default>50k</default>
|
||||
<mask>/^([0-9]{1,5}[k|m|g]{1})*/u</mask>
|
||||
<ChangeCase>lower</ChangeCase>
|
||||
<ValidationMessage>Should be a number between 1 and 5 characters followed by either "k", "m" or "g".</ValidationMessage>
|
||||
</stickiness_size>
|
||||
<stickiness_length type="IntegerField">
|
||||
<MinimumValue>1</MinimumValue>
|
||||
<MaximumValue>16384</MaximumValue>
|
||||
<ValidationMessage>Please specify a value between 1 and 16384.</ValidationMessage>
|
||||
<Required>N</Required>
|
||||
</stickiness_length>
|
||||
<stickiness_connRatePeriod type="TextField">
|
||||
<default>10s</default>
|
||||
<mask>/^([0-9]{1,8}(?:us|ms|s|m|h|d)?)/u</mask>
|
||||
<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_connRatePeriod>
|
||||
<stickiness_sessRatePeriod type="TextField">
|
||||
<default>10s</default>
|
||||
<mask>/^([0-9]{1,8}(?:us|ms|s|m|h|d)?)/u</mask>
|
||||
<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_sessRatePeriod>
|
||||
<stickiness_httpReqRatePeriod type="TextField">
|
||||
<default>10s</default>
|
||||
<mask>/^([0-9]{1,8}(?:us|ms|s|m|h|d)?)/u</mask>
|
||||
<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_httpReqRatePeriod>
|
||||
<stickiness_httpErrRatePeriod type="TextField">
|
||||
<default>10s</default>
|
||||
<mask>/^([0-9]{1,8}(?:us|ms|s|m|h|d)?)/u</mask>
|
||||
<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_httpErrRatePeriod>
|
||||
<stickiness_bytesInRatePeriod type="TextField">
|
||||
<default>1m</default>
|
||||
<mask>/^([0-9]{1,8}(?:us|ms|s|m|h|d)?)/u</mask>
|
||||
<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_bytesInRatePeriod>
|
||||
<stickiness_bytesOutRatePeriod type="TextField">
|
||||
<default>1m</default>
|
||||
<mask>/^([0-9]{1,8}(?:us|ms|s|m|h|d)?)/u</mask>
|
||||
<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>
|
||||
<forwardFor type="BooleanField">
|
||||
<default>0</default>
|
||||
<Required>Y</Required>
|
||||
|
|
|
|||
|
|
@ -485,6 +485,80 @@
|
|||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{# Macro expects a backend or frontend object. #}
|
||||
{% macro StickTableConfig(proxy, backend=False) -%}
|
||||
{% if proxy is defined %}
|
||||
{# # check if stickiness is disabled (set to "None") #}
|
||||
{% if proxy.stickiness_pattern|default("") != "" %}
|
||||
# stickiness
|
||||
{# # check if additional data types are configured #}
|
||||
{% if proxy.stickiness_dataTypes|default("") != "" %}
|
||||
{% set stickiness_datatypes = [] %}
|
||||
{% for datatype in proxy.stickiness_dataTypes.split(",") %}
|
||||
{# # add time period to all types where this is required #}
|
||||
{% if datatype == 'conn_rate' %}
|
||||
{% do stickiness_datatypes.append(datatype ~ '(' ~ proxy.stickiness_connRatePeriod ~ ')') %}
|
||||
{% elif datatype == 'sess_rate' %}
|
||||
{% do stickiness_datatypes.append(datatype ~ '(' ~ proxy.stickiness_sessRatePeriod ~ ')') %}
|
||||
{% elif datatype == 'http_req_rate' %}
|
||||
{% do stickiness_datatypes.append(datatype ~ '(' ~ proxy.stickiness_httpReqRatePeriod ~ ')') %}
|
||||
{% elif datatype == 'http_err_rate' %}
|
||||
{% do stickiness_datatypes.append(datatype ~ '(' ~ proxy.stickiness_httpErrRatePeriod ~ ')') %}
|
||||
{% elif datatype == 'bytes_in_rate' %}
|
||||
{% do stickiness_datatypes.append(datatype ~ '(' ~ proxy.stickiness_bytesInRatePeriod ~ ')') %}
|
||||
{% elif datatype == 'bytes_out_rate' %}
|
||||
{% do stickiness_datatypes.append(datatype ~ '(' ~ proxy.stickiness_bytesOutRatePeriod ~ ')') %}
|
||||
{% else %}
|
||||
{% do stickiness_datatypes.append(datatype) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% set stickiness_store = 'store ' ~ stickiness_datatypes|join(',') %}
|
||||
{% endif %}
|
||||
{# # check stick-table type #}
|
||||
{% if proxy.stickiness_pattern == "sourceipv4" or proxy.stickiness_pattern == "ipv4" %}
|
||||
{% set table_type = 'ip' %}
|
||||
{% elif proxy.stickiness_pattern == "sourceipv6" or proxy.stickiness_pattern == "ipv6" %}
|
||||
{% set table_type = 'ipv6' %}
|
||||
{% elif proxy.stickiness_pattern == "cookievalue" or proxy.stickiness_pattern == "string" %}
|
||||
{% set table_type = 'string' %}
|
||||
{% set add_length = True %}
|
||||
{% elif proxy.stickiness_pattern == "rdpcookie" or proxy.stickiness_pattern == "binary" %}
|
||||
{% set table_type = 'binary' %}
|
||||
{% set add_length = True %}
|
||||
{% elif proxy.stickiness_pattern == "integer" %}
|
||||
{% set table_type = 'integer' %}
|
||||
{% endif %}
|
||||
{# # check data length #}
|
||||
{% if add_length is defined %}
|
||||
{% if proxy.stickiness_cookielength is defined %}
|
||||
{% set data_length = proxy.stickiness_cookielength %}
|
||||
{% elif proxy.stickiness_length is defined %}
|
||||
{% set data_length = proxy.stickiness_length %}
|
||||
{% else %}
|
||||
{% set data_length = '32' %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{# # add stick-table #}
|
||||
{% if table_type is defined %}
|
||||
stick-table type {{table_type}} {%if add_length is defined %}len {{data_length}} {% endif %}size {{proxy.stickiness_size}} expire {{proxy.stickiness_expire}} {{stickiness_store}}
|
||||
{% endif %}
|
||||
{# # stick-table persistence (backends only) #}
|
||||
{%- if backend == True -%}
|
||||
{%- if proxy.stickiness_pattern == "cookievalue" %}
|
||||
stick store-response res.cook({{proxy.stickiness_cookiename}})
|
||||
stick on req.cook({{proxy.stickiness_cookiename}})
|
||||
{%- elif proxy.stickiness_pattern == "rdpcookie" %}
|
||||
stick on req.rdp_cookie(mstshash)
|
||||
{%- elif proxy.stickiness_pattern != '' %}
|
||||
stick on src
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
# ERROR: StickTableConfig called with empty data
|
||||
{% endif %}
|
||||
{%- endmacro -%}
|
||||
|
||||
{% if not (helpers.exists('OPNsense.HAProxy.general') and OPNsense.HAProxy.general.enabled|default("0") == "1") %}
|
||||
#
|
||||
# NOTE: HAProxy is currently DISABLED
|
||||
|
|
@ -688,6 +762,8 @@ frontend {{frontend.name}}
|
|||
{% if frontend.tuning_timeoutHttpKeepAlive|default("") != "" and frontend.mode == 'http' %}
|
||||
timeout http-keep-alive {{frontend.tuning_timeoutHttpKeepAlive}}
|
||||
{% endif %}
|
||||
{# # call macro to evaluate stickiness config #}
|
||||
{{ StickTableConfig(frontend) }}
|
||||
# logging options
|
||||
{% if frontend.logging_dontLogNull=='1' %}
|
||||
option dontlognull
|
||||
|
|
@ -846,48 +922,8 @@ backend {{backend.name}}
|
|||
{# # (redundant) GUI option for this. #}
|
||||
mode {{backend.mode}}
|
||||
balance {{backend.algorithm}}
|
||||
{# # check if stickiness is disabled (set to "None") #}
|
||||
{% if backend.stickiness_pattern|default("") != "" %}
|
||||
# stickiness
|
||||
{# # check if additional data types are configured #}
|
||||
{% if backend.stickiness_dataTypes|default("") != "" %}
|
||||
{% set stickiness_datatypes = [] %}
|
||||
{% for datatype in backend.stickiness_dataTypes.split(",") %}
|
||||
{# # add time period to all types where this is required #}
|
||||
{% if datatype == 'conn_rate' %}
|
||||
{% do stickiness_datatypes.append(datatype ~ '(' ~ backend.stickiness_connRatePeriod ~ ')') %}
|
||||
{% elif datatype == 'sess_rate' %}
|
||||
{% do stickiness_datatypes.append(datatype ~ '(' ~ backend.stickiness_sessRatePeriod ~ ')') %}
|
||||
{% elif datatype == 'http_req_rate' %}
|
||||
{% do stickiness_datatypes.append(datatype ~ '(' ~ backend.stickiness_httpReqRatePeriod ~ ')') %}
|
||||
{% elif datatype == 'http_err_rate' %}
|
||||
{% do stickiness_datatypes.append(datatype ~ '(' ~ backend.stickiness_httpErrRatePeriod ~ ')') %}
|
||||
{% elif datatype == 'bytes_in_rate' %}
|
||||
{% do stickiness_datatypes.append(datatype ~ '(' ~ backend.stickiness_bytesInRatePeriod ~ ')') %}
|
||||
{% elif datatype == 'bytes_out_rate' %}
|
||||
{% do stickiness_datatypes.append(datatype ~ '(' ~ backend.stickiness_bytesOutRatePeriod ~ ')') %}
|
||||
{% else %}
|
||||
{% do stickiness_datatypes.append(datatype) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% set stickiness_store = 'store ' ~ stickiness_datatypes|join(',') %}
|
||||
{% endif %}
|
||||
{# # check stick-table type #}
|
||||
{% if backend.stickiness_pattern == "sourceipv4" %}
|
||||
stick-table type ip size {{backend.stickiness_size}} expire {{backend.stickiness_expire}} {{stickiness_store}}
|
||||
stick on src
|
||||
{% elif backend.stickiness_pattern == "sourceipv6" %}
|
||||
stick-table type ipv6 size {{backend.stickiness_size}} expire {{backend.stickiness_expire}} {{stickiness_store}}
|
||||
stick on src
|
||||
{% elif backend.stickiness_pattern == "cookievalue" %}
|
||||
stick-table type string len {{backend.stickiness_cookielength}} size {{backend.stickiness_size}} expire {{backend.stickiness_expire}} {{stickiness_store}}
|
||||
stick store-response res.cook({{backend.stickiness_cookiename}})
|
||||
stick on req.cook({{backend.stickiness_cookiename}})
|
||||
{% elif backend.stickiness_pattern == "rdpcookie" %}
|
||||
stick-table type binary len {{backend.stickiness_cookielength}} size {{backend.stickiness_size}} expire {{backend.stickiness_expire}} {{stickiness_store}}
|
||||
stick on req.rdp_cookie(mstshash)
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{# # call macro to evaluate stickiness config #}
|
||||
{{ StickTableConfig(backend,true) }}
|
||||
# tuning options
|
||||
{% if backend.tuning_timeoutConnect|default("") != "" %}
|
||||
timeout connect {{backend.tuning_timeoutConnect}}
|
||||
|
|
|
|||
Loading…
Reference in a new issue