From 8d5a15555320068dfd37f748c916da5164459f26 Mon Sep 17 00:00:00 2001
From: Monviech <79600909+Monviech@users.noreply.github.com>
Date: Wed, 19 Mar 2025 14:13:22 +0100
Subject: [PATCH] www/caddy: Add client auth mtls to domains (#4601)
---
www/caddy/Makefile | 2 +-
www/caddy/pkg-descr | 4 ++++
.../Caddy/forms/dialogReverseProxy.xml | 19 +++++++++++++++
.../mvc/app/models/OPNsense/Caddy/Caddy.xml | 12 ++++++++++
.../scripts/OPNsense/Caddy/caddy_certs.php | 16 +++++++++++--
.../templates/OPNsense/Caddy/Caddyfile | 23 ++++++++++++++++---
6 files changed, 70 insertions(+), 6 deletions(-)
diff --git a/www/caddy/Makefile b/www/caddy/Makefile
index ed4434653..b8195f4da 100644
--- a/www/caddy/Makefile
+++ b/www/caddy/Makefile
@@ -1,5 +1,5 @@
PLUGIN_NAME= caddy
-PLUGIN_VERSION= 1.8.3
+PLUGIN_VERSION= 1.8.4
PLUGIN_DEPENDS= caddy-custom
PLUGIN_COMMENT= Modern Reverse Proxy with Automatic HTTPS, Dynamic DNS and Layer4 Routing
PLUGIN_MAINTAINER= cedrik@pischem.com
diff --git a/www/caddy/pkg-descr b/www/caddy/pkg-descr
index 640ead7ea..67443a08c 100644
--- a/www/caddy/pkg-descr
+++ b/www/caddy/pkg-descr
@@ -13,6 +13,10 @@ DOC: https://docs.opnsense.org/manual/how-tos/caddy.html
Plugin Changelog
================
+1.8.4
+
+* Add: Client Auth (mTLS) to domains (opnsense/plugins/issues/4089)
+
1.8.3
* Add: Update DNS Providers with new optional choices (opnsense/plugins/issues/4543)
diff --git a/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/forms/dialogReverseProxy.xml b/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/forms/dialogReverseProxy.xml
index a8163b33f..86a0bd1bb 100644
--- a/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/forms/dialogReverseProxy.xml
+++ b/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/forms/dialogReverseProxy.xml
@@ -104,6 +104,25 @@
false
+
+ reverse.ClientAuthTrustPool
+
+ select_multiple
+
+
+ false
+
+
+
+ reverse.ClientAuthMode
+
+ dropdown
+ true
+
+
+ false
+
+
reverse.AccessLog
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 bf5c3cbfe..0deb5239c 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
@@ -276,6 +276,18 @@
http://
+
+ require_and_verify
+
+ request
+ require
+ verify_if_given
+
+
+
+ ca
+ Y
+
diff --git a/www/caddy/src/opnsense/scripts/OPNsense/Caddy/caddy_certs.php b/www/caddy/src/opnsense/scripts/OPNsense/Caddy/caddy_certs.php
index 67618d75a..f4b43e0de 100755
--- a/www/caddy/src/opnsense/scripts/OPNsense/Caddy/caddy_certs.php
+++ b/www/caddy/src/opnsense/scripts/OPNsense/Caddy/caddy_certs.php
@@ -87,14 +87,26 @@ foreach ((new Caddy())->reverseproxy->handle->iterateItems() as $handleItem) {
}
}
+foreach ((new Caddy())->reverseproxy->reverse->iterateItems() as $reverseItem) {
+ $caCertField = (string)$reverseItem->ClientAuthTrustPool;
+
+ if (!empty($caCertField)) {
+ $refs = array_map('trim', explode(',', $caCertField));
+ foreach ($refs as $ref) {
+
+ if (!empty($ref)) {
+ $caCertRefs[] = $ref;
+ }
+ }
+ }
+}
+
$caCertRefs = array_unique($caCertRefs);
foreach ((new Ca())->ca->iterateItems() as $caItem) {
$refid = (string)$caItem->refid;
-
if (in_array($refid, $caCertRefs, true)) {
$caCert = base64_decode((string)$caItem->crt);
-
$writeFileIfChanged($tempDir . $refid . '.pem', $caCert);
}
}
diff --git a/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/Caddyfile b/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/Caddyfile
index fe712251f..d5bdb2b66 100644
--- a/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/Caddyfile
+++ b/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/Caddyfile
@@ -306,6 +306,8 @@ http://{{ domain }} {
{% macro tls_configuration(
customCert,
dnsChallenge,
+ clientAuthTrustPool,
+ clientAuthMode,
dnsProvider,
dnsApiKey,
dnsSecretApiKey,
@@ -318,8 +320,9 @@ http://{{ domain }} {
tlsDnsPropagationDelay,
tlsDnsPropagationResolvers
) %}
- {% if customCert or (dnsChallenge == "1" and dnsProvider) %}
- tls {% if customCert %}/var/db/caddy/data/caddy/certificates/temp/{{ customCert }}.pem /var/db/caddy/data/caddy/certificates/temp/{{ customCert }}.key{% endif %} {% if not customCert and dnsChallenge == "1" and dnsProvider %}{
+ {% if customCert or (dnsChallenge == "1" and dnsProvider) or clientAuthTrustPool %}
+ tls {% if customCert %}/var/db/caddy/data/caddy/certificates/temp/{{ customCert }}.pem /var/db/caddy/data/caddy/certificates/temp/{{ customCert }}.key{% endif %} {
+ {% if not customCert and (dnsChallenge == "1" and dnsProvider) %}
issuer acme {
dns {{ dnsProvider }} {% if dnsProvider not in dnsProviderSpecialConfig %}{{ dnsApiKey }}{% else %}{
{% set context_var = 'dnsProviderSpecialLogic' %}
@@ -339,7 +342,19 @@ http://{{ domain }} {
propagation_delay {{ tlsDnsPropagationDelay }}s
{% endif %}
}
- }{% endif %}
+ {% endif %}
+
+ {% if clientAuthTrustPool %}
+ client_auth {
+ {% for ca in clientAuthTrustPool.split(',') %}
+ trust_pool file /var/db/caddy/data/caddy/certificates/temp/{{ ca.strip() }}.pem
+ {% endfor %}
+ {% if clientAuthMode %}
+ mode {{ clientAuthMode }}
+ {% endif %}
+ }
+ {% endif %}
+ }
{% endif %}
{% endmacro %}
@@ -595,6 +610,8 @@ http://{{ domain }} {
{{ tls_configuration(
reverse.CustomCertificate|default(""),
reverse.DnsChallenge|default("0"),
+ reverse.ClientAuthTrustPool|default(""),
+ reverse.ClientAuthMode|default(""),
generalSettings.TlsDnsProvider,
generalSettings.TlsDnsApiKey,
generalSettings.TlsDnsSecretApiKey,