diff --git a/net/haproxy/pkg-descr b/net/haproxy/pkg-descr
index 19252be16..01e41f56b 100644
--- a/net/haproxy/pkg-descr
+++ b/net/haproxy/pkg-descr
@@ -6,6 +6,14 @@ very high loads while needing persistence or Layer7 processing.
Plugin Changelog
================
+3.9
+
+Added:
+* add SSL SNI setting to servers and health checks (#2388)
+
+Changed:
+* replace "force SSL" setting with "SSL preferences" in health checks (#2388)
+
3.8
Added:
diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogHealthcheck.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogHealthcheck.xml
index a3d23ffbc..8d3ad20c8 100644
--- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogHealthcheck.xml
+++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogHealthcheck.xml
@@ -17,18 +17,24 @@
dropdown
+
+ healthcheck.ssl
+
+ dropdown
+
+
+
+ healthcheck.sslSNI
+
+ text
+
+
healthcheck.interval
text
-
- healthcheck.force_ssl
-
- checkbox
-
-
healthcheck.checkport
diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogServer.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogServer.xml
index fa2283086..30dd1a308 100644
--- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogServer.xml
+++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogServer.xml
@@ -108,6 +108,12 @@
checkbox
+
+ server.sslSNI
+
+ text
+
+
server.sslVerify
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 5efa6dff9..1a52f7e1d 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
- 3.4.0
+ 3.5.0
the HAProxy load balancer
@@ -1304,6 +1304,11 @@
0
Y
+
+ /^([0-9a-zA-Z._\-]){1,255}$/u
+ Should be a string between 1 and 255 characters.
+ N
+
1
Y
@@ -1406,6 +1411,22 @@
Should be a number between 1 and 8 characters, optionally followed by either "d", "h", "m", "s", "ms" or "us".
Y
+
+ N
+ nopref
+
+ Use server settings
+ Force SSL for health checks
+ Force SSL+SNI for health checks
+ Force no SSL for health checks
+
+
+
+ /^([0-9a-zA-Z._\-]){1,255}$/u
+ Should be a string between 1 and 255 characters.
+ N
+
+
0
N
diff --git a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/Migrations/M3_5_0.php b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/Migrations/M3_5_0.php
new file mode 100644
index 000000000..24306366e
--- /dev/null
+++ b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/Migrations/M3_5_0.php
@@ -0,0 +1,50 @@
+getNodeByReference('healthchecks.healthcheck')->iterateItems() as $healthcheck) {
+ switch ((string)$healthcheck->force_ssl) {
+ case '0':
+ $healthcheck->ssl = 'nopref';
+ break;
+ case '1':
+ $healthcheck->ssl = 'ssl';
+ break;
+ }
+ }
+ }
+}
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 b95910675..8eb29fb40 100644
--- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf
+++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf
@@ -1722,8 +1722,19 @@ backend {{backend.name}}
{% do server_options.append('port ' ~ server_data.checkport) %}
{% endif %}
{# # force SSL encryption for health checks #}
-{% if healthcheck_data.force_ssl|default('') == '1' %}
-{% do server_options.append('check-ssl ') %}
+{% if healthcheck_data.ssl|default('') == 'ssl' or healthcheck_data.ssl|default('') == 'sslsni' %}
+{% do server_options.append('check-ssl') %}
+{% elif healthcheck_data.ssl|default('') == 'nossl' %}
+{% do server_options.append('no-check-ssl') %}
+{% endif %}
+{# # add SNI header for health checks #}
+{% if healthcheck_data.ssl|default('') == 'sslsni' and healthcheck_data.sslSNI|default('') != '' %}
+{% do server_options.append('check-sni ' ~ healthcheck_data.sslSNI) %}
+{# # fallback to server SNI value #}
+{% elif healthcheck_data.ssl|default('') == 'sslsni' and server_data.sslSNI|default('') != '' %}
+{% do server_options.append('check-sni ' ~ server_data.sslSNI) %}
+{% elif healthcheck_data.ssl|default('') == 'sslsni' and (healthcheck_data.sslSNI|default('') == '' and server_data.sslSNI|default('') == '') %}
+# ERROR: missing SSL SNI value
{% endif %}
{# # add all additions from healthchecks here #}
{% do server_options.append(healthcheck_additions|join(' ')) if healthcheck_additions.length != '0' %}
@@ -1739,6 +1750,10 @@ backend {{backend.name}}
{# # server ssl communication #}
{% if server_data.ssl|default("") == '1' %}
{% do server_options.append('ssl') %}
+{# # SNI #}
+{% if server_data.sslSNI|default('') != '' %}
+{% do server_options.append('sni str(' ~ server_data.sslSNI ~ ')') %}
+{% endif %}
{# # HTTP/2 #}
{% if backend.http2Enabled|default("") == '1' and backend.ba_advertised_protocols|default("") != "" %}
{# # convert protocols to HAProxy-compatible format #}