diff --git a/net/haproxy/Makefile b/net/haproxy/Makefile
index 154c6e31d..62e2febe4 100644
--- a/net/haproxy/Makefile
+++ b/net/haproxy/Makefile
@@ -1,5 +1,5 @@
PLUGIN_NAME= haproxy
-PLUGIN_VERSION= 2.6
+PLUGIN_VERSION= 2.7
PLUGIN_COMMENT= Reliable, high performance TCP/HTTP load balancer
PLUGIN_DEPENDS= haproxy-devel
PLUGIN_MAINTAINER= opnsense@moov.de
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 51589ca54..5afb37e55 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,39 @@
true
+
+
+ header
+
+
+ backend.persistence
+
+ dropdown
+
+
+
+
+ header
+
+
+
+ backend.persistence_cookiemode
+
+ dropdown
+ HAProxy documentation for a full description.]]>
+
+
+ backend.persistence_cookiename
+
+ text
+
+
+
+ backend.persistence_stripquotes
+
+ checkbox
+
+
header
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 f48700e17..10494e39a 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
@@ -1,6 +1,6 @@
//OPNsense/HAProxy
- 2.2.0
+ 2.3.0
the HAProxy load balancer
@@ -686,14 +686,40 @@
Please specify a value between 1 and 100.
N
+
+ N
+ sticktable
+
+ Stick-table persistence [default]
+ Cookie-based persistence (HTTP/HTTPS only)
+
+
+
+ Y
+ piggyback
+
+ Piggyback on existing cookie
+ Insert new cookie
+
+
+
+ SRVCOOKIE
+ N
+ /^([0-9a-zA-Z\.,_\-:]){1,1024}$/u
+ Does not look like a valid cookie name (most special characters are not allowed).
+
+
+ 1
+ Y
+
N
sourceipv4
- Stick on Source-IP [default]
- Stick on Source-IPv6
- Stick on existing Cookie value
- Stick on RDP-Cookie
+ Source-IP [default]
+ Source-IPv6
+ Existing cookie value
+ RDP-Cookie
@@ -835,6 +861,9 @@
+
+ Y
+
/^([0-9a-zA-Z._]){1,255}$/u
Should be a string between 1 and 255 characters.
diff --git a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/Migrations/M2_7_0.php b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/Migrations/M2_7_0.php
new file mode 100644
index 000000000..b76693b3b
--- /dev/null
+++ b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/Migrations/M2_7_0.php
@@ -0,0 +1,44 @@
+getNodeByReference('backends.backend')->__items as $backend) {
+ if (isset($backend->stickiness_pattern)) {
+ $backend->persistence = '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 4eeff31ca..1e730bb78 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
@@ -176,6 +176,13 @@ POSSIBILITY OF SUCH DAMAGE.
$("."+service_id).show();
});
$("#backend\\.healthCheckEnabled").change();
+
+ $("#backend\\.persistence").change(function(){
+ var persistence_id = 'table_persistence_' + $(this).val();
+ $(".persistence_table").hide();
+ $("."+persistence_id).show();
+ });
+ $("#backend\\.persistence").change();
})
// hook into on-show event for dialog to extend layout.
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 da72c7a5a..a921a54bd 100644
--- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf
+++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf
@@ -578,18 +578,28 @@
tcp-request connection track-sc0 {{proxy.stickiness_counter_key}}
{%- endif -%}
{%- endif -%}
-{# # stick-table persistence (backends only) #}
-{%- if backend == True -%}
-{%- if proxy.stickiness_pattern == "cookievalue" %}
+{% endif %}
+{# # persistence (backends only) #}
+{%- if backend == True -%}
+{%- if proxy.persistence|default("") == "cookie" %}
+{# # cookie-based persistence #}
+{%- if proxy.persistence_cookiemode|default("") == "piggyback" %}
+ cookie {{proxy.persistence_cookiename}} prefix
+{%- elif proxy.persistence_cookiemode|default("") == "new" %}
+ cookie {{proxy.persistence_cookiename}} insert indirect nocache
+{%- endif -%}
+{% elif proxy.persistence|default("") == "sticktable" %}
+{# # stick-table persistence #}
+{%- if proxy.stickiness_pattern|default("") == "cookievalue" %}
stick store-response res.cook({{proxy.stickiness_cookiename}})
stick on req.cook({{proxy.stickiness_cookiename}})
-{%- elif proxy.stickiness_pattern == "rdpcookie" %}
+{%- elif proxy.stickiness_pattern|default("") == "rdpcookie" %}
stick on req.rdp_cookie(mstshash)
-{%- elif proxy.stickiness_pattern != '' %}
+{%- elif proxy.stickiness_pattern|default("") != '' %}
stick on src
{%- endif -%}
{%- endif -%}
-{% endif %}
+{%- endif -%}
{% else %}
# ERROR: StickTableConfig called with empty data
{% endif %}
@@ -779,6 +789,11 @@ frontend {{frontend.name}}
{% if frontend.defaultBackend|default("") != "" %}
{% set backend_data = helpers.getUUID(frontend.defaultBackend) %}
default_backend {{backend_data.name}}
+{# # check if persistence-related workaround is enabled #}
+{% if backend_data.persistence|default("") == 'cookie' and backend_data.persistence_stripquotes|default("") == '1' %}
+ # remove quotes from persistence cookie
+ http-request replace-header Cookie '^(.*?; )?({{backend_data.persistence_cookiename}}=)"([^;"]*)"(;.*)?$' \1\2\3\4
+{% endif %}
{% endif %}
{% if frontend.forwardFor == '1' %}
option forwardfor
@@ -1094,6 +1109,10 @@ backend {{backend.name}}
{% do server_options.append('send-proxy-v2') %}
{% do server_options.append('check-send-proxy') %}
{% endif %}
+{# # cookie-based persistence #}
+{% if backend.persistence|default("") == "cookie" %}
+{% do server_options.append('cookie ' ~ server_data.id|replace(".", "")) %}
+{% endif %}
{# # server advanced options #}
{% if server_data.advanced|default("") != "" %}
{% do server_options.append(server_data.advanced) %}