www/caddy: Add client auth mtls to domains (#4601)

This commit is contained in:
Monviech
2025-03-19 14:13:22 +01:00
committed by GitHub
parent 8b5dd05fd4
commit 8d5a155553
6 changed files with 70 additions and 6 deletions
+1 -1
View File
@@ -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
+4
View File
@@ -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)
@@ -104,6 +104,25 @@
<visible>false</visible>
</grid_view>
</field>
<field>
<id>reverse.ClientAuthTrustPool</id>
<label>Client Auth Trust Pool</label>
<type>select_multiple</type>
<help><![CDATA[Choose multiple CAs or self-signed certificates from "System - Trust - Authorities". Client Auth is activated as soon as at least one certificate has been chosen. Important: Certificate revocation lists are not evaluated. If you need granular control, provide individual self-signed certificates for each device, and unset them to block access. Though keep in mind that if no certificate is left in this field, Client Auth will be deactivated.]]></help>
<grid_view>
<visible>false</visible>
</grid_view>
</field>
<field>
<id>reverse.ClientAuthMode</id>
<label>Client Auth Mode</label>
<type>dropdown</type>
<advanced>true</advanced>
<help><![CDATA["request" - Ask clients for a certificate, but allow even if there isn't one; do not verify it. "require" - Require clients to present a certificate, but do not verify it. "verify_if_given" - Ask clients for a certificate; allow even if there isn't one, but verify it if there is. "require_and_verify" - Require clients to present a valid certificate that is verified.]]></help>
<grid_view>
<visible>false</visible>
</grid_view>
</field>
<field>
<id>reverse.AccessLog</id>
<label>HTTP Access Log</label>
@@ -276,6 +276,18 @@
<http value="1">http://</http>
</OptionValues>
</DisableTls>
<ClientAuthMode type="OptionField">
<BlankDesc>require_and_verify</BlankDesc>
<OptionValues>
<request>request</request>
<require>require</require>
<verify_if_given>verify_if_given</verify_if_given>
</OptionValues>
</ClientAuthMode>
<ClientAuthTrustPool type="CertificateField">
<Type>ca</Type>
<Multiple>Y</Multiple>
</ClientAuthTrustPool>
</reverse>
<subdomain type="ArrayField">
<enabled type="BooleanField">
@@ -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);
}
}
@@ -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,