diff --git a/www/caddy/pkg-descr b/www/caddy/pkg-descr
index 93d02a539..452ecabe8 100644
--- a/www/caddy/pkg-descr
+++ b/www/caddy/pkg-descr
@@ -19,6 +19,7 @@ Main features of this plugin:
* Syslog-ng integration and HTTP Access Log
* NTLM Transport
* Header manipulation with header_up and header_down
+* Simple load balancing with passive health check
DOC: https://docs.opnsense.org/manual/how-tos/caddy.html
@@ -34,6 +35,8 @@ Plugin Changelog
* Add: Header functionality added. Multiple header manipulations can be set per handler.
* Cleanup: Update searchBase() in ReverseProxyController.php for easier maintainability.
* Fix: Move selectpicker empty option to model in general.volt, using BlankDesc. This fixes the option IPv4+IPv6 not appearing in Dynamic DNS.
+* Add: Simple Load Balancing support with the default random policy, by allowing to add multiple Upstream Domains in Handlers.
+* Add: Passive Health check for load balancing (Upstream Fail Duration) in Handlers.
1.5.3
diff --git a/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/forms/dialogHandle.xml b/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/forms/dialogHandle.xml
index 51bf04077..4a6d5ee50 100644
--- a/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/forms/dialogHandle.xml
+++ b/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/forms/dialogHandle.xml
@@ -56,9 +56,11 @@
handle.ToDomain
- text
+ select_multiple
+
+ true192.168.1.1
-
+ handle.ToPort
@@ -74,6 +76,13 @@
true
+
+ handle.PassiveHealthFailDuration
+
+ text
+
+ true
+ header
diff --git a/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Caddy.xml b/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Caddy.xml
index d967254ef..acfc075d9 100644
--- a/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Caddy.xml
+++ b/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Caddy.xml
@@ -256,6 +256,8 @@
YPlease enter a valid 'to' domain or IP address.Y
+ ,
+ YPlease enter a valid 'to' port number.
@@ -266,6 +268,11 @@
/^(\/.*)?$/uPlease enter a valid 'Backend Path' that starts with '/'.
+
+ 1
+ 100
+ Please enter a value between 1 to 100.
+
diff --git a/www/caddy/src/opnsense/mvc/app/views/OPNsense/Caddy/reverse_proxy.volt b/www/caddy/src/opnsense/mvc/app/views/OPNsense/Caddy/reverse_proxy.volt
index 7f397b615..5d9ebc406 100644
--- a/www/caddy/src/opnsense/mvc/app/views/OPNsense/Caddy/reverse_proxy.volt
+++ b/www/caddy/src/opnsense/mvc/app/views/OPNsense/Caddy/reverse_proxy.volt
@@ -247,6 +247,7 @@
Upstream Domain
Upstream Port
Upstream Path
+
Fail Duration
TLS
TLS CA
TLS Server Name
diff --git a/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/Caddyfile b/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/Caddyfile
index 6a4272fb2..178c3ea78 100644
--- a/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/Caddyfile
+++ b/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/Caddyfile
@@ -500,14 +500,21 @@
# - HttpTlsInsecureSkipVerify (boolean, optional): If true, the server's SSL certificate is not verified.
# - HttpTlsTrustedCaCerts (string, optional): The config extracted name of a CA certificate.
# - HttpTlsServerName (string, optional): Specifies the server name for the TLS handshake.
+# - PassiveHealthFailDuration (integer, optional): Enables passive health checks when set > 0.
#}
{% macro reverse_proxy_configuration(handle) %}
{{ handle.HandleType }} {{ handle.HandlePath|default("") }} {
{% if handle.ToPath|default("") != "" %}
rewrite * {{ handle.ToPath }}{uri}
{% endif %}
- reverse_proxy {{ handle.ToDomain }}{% if handle.ToPort %}:{{ handle.ToPort }}{% endif %} {
+ reverse_proxy {% for domain in handle.ToDomain.split(',') %}
+ {# For each domain/IP, append the port if it's specified, followed by a space #}
+ {{- domain -}}{% if handle.ToPort %}:{{ handle.ToPort }}{% endif %}{% if not loop.last %} {% endif %}
+ {% endfor %}{
{{ header_manipulation(handle) }}
+ {% if handle.PassiveHealthFailDuration|default("") %}
+ fail_duration {{ handle.PassiveHealthFailDuration }}s
+ {% endif %}
{% if handle.HttpTls|default("0") == "1" or handle.HttpTlsInsecureSkipVerify|default("0") == "1" %}
{% if handle.HttpNtlm|default("0") == "1" %}
transport http_ntlm {