From d777a605920921249ec120c8679f0e50215a0266 Mon Sep 17 00:00:00 2001 From: Monviech <79600909+Monviech@users.noreply.github.com> Date: Wed, 10 Jul 2024 11:38:46 +0200 Subject: [PATCH] www/caddy: Cleanup model, php (PSR-12), python (PEP 8) and jinja2 files (#4060) * www/caddy: Remove unsused code in validation. * www/caddy: Cleanup Caddyfile template for better readability with improved indentation. * www/caddy: Cleanup rc.conf.d/caddy * www/caddy: Cleanup model. * www/caddy: Cleanup Caddyfile template some more. * www/caddy: Roll back changes to Caddyfile structure, don't fix what ain't broken. * www/caddy: Fix caddy_certs.php style warning. A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute logic with side effects, but should not do both. * www/caddy: Ignore php style warnings for migration scripts, since the class names have to ignore PascalCase. * www/caddy: Correct style of php files so that no lines exceed 120 characters. * www/caddy: Refactor caddy_diagnostics.py and caddy_control.py for Python PEP 8. Fix: Shadows name 'action' from outer scope * www/caddy: Changelog add code cleanup. * www/caddy: Fix minor regression in refactored caddy_control.py script. * www/caddy: Fix indentation of Caddyfile template for better code readability. The template gets edited and read a lot so this fix really helps with maintainability. * www/caddy: Add changelog. * www/caddy: Fix caddy_certs.php style issue by removing the declared function and execute logic with side effects directly. * www/caddy: Re-add ValidationMessage to IntegerField because there are custom constraints that are not displayed by the default validation message. * www/caddy: Add error handling to caddy_control.py when action is empty. Make use of service_action and cmd_action clearer. * www/caddy: Remove unnecessary variable in caddy_diagnostics.py * www/caddy: Add validation message since there is a no IP constraint. Add same constraint to subdomains. * www/caddy: Re-add validation message to ToDomain field since multiple are allowed * www/caddy: Re-add validation message to clientIps field since multiple are allowed --- www/caddy/pkg-descr | 6 +- .../Caddy/Api/DiagnosticsController.php | 4 +- .../Caddy/Api/ReverseProxyController.php | 30 +- .../mvc/app/models/OPNsense/Caddy/Caddy.php | 51 ++- .../mvc/app/models/OPNsense/Caddy/Caddy.xml | 60 +--- .../OPNsense/Caddy/Migrations/M1_1_3.php | 2 + .../OPNsense/Caddy/Migrations/M1_1_8.php | 2 + .../scripts/OPNsense/Caddy/caddy_certs.php | 68 ++-- .../scripts/OPNsense/Caddy/caddy_control.py | 51 +-- .../OPNsense/Caddy/caddy_diagnostics.py | 19 +- .../templates/OPNsense/Caddy/Caddyfile | 334 +++++++++--------- .../templates/OPNsense/Caddy/rc.conf.d/caddy | 11 +- 12 files changed, 331 insertions(+), 307 deletions(-) diff --git a/www/caddy/pkg-descr b/www/caddy/pkg-descr index 94e47d2bd..530635276 100644 --- a/www/caddy/pkg-descr +++ b/www/caddy/pkg-descr @@ -28,7 +28,11 @@ Plugin Changelog 1.6.0 * Add: New Dashboard widgets for 24.7, showing domain status and certificate validity status. -* Fix: Caddyfile template fixed for IPv6 addresses and custom port. +* Cleanup: PHP files refactored for PSR-12, Python files refactored for PEP-8. +* Cleanup: Templates Caddyfile and rc.conf.d/caddy refactored for maintainability. +* Cleanup: Spurious keys removed from Caddy.xml model. +* Cleanup: Unused code removed from Caddy.php. +* Fix: Caddyfile template fixed when IPv6 addresses and ports are used in Upstream. IPv6 address wraps into brackets now. * Add: forward_auth directive with Authelia as Authz Provider. * Add: Default HTTP and HTTPS ports can be changed in general settings. * Add: Introduce HTTP version to handler. HTTP/1.1, HTTP/2 and HTTP/3 can be chosen. diff --git a/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/Api/DiagnosticsController.php b/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/Api/DiagnosticsController.php index bda64cb5e..edcb55389 100644 --- a/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/Api/DiagnosticsController.php +++ b/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/Api/DiagnosticsController.php @@ -50,7 +50,7 @@ class DiagnosticsController extends ApiMutableModelControllerBase // Decode JSON to PHP array $responseArray = json_decode($response, true); - // Since errors are handled by the caddy_diagnostics script and returned as json, check for an error key in the response + // Errors are handled by the caddy_diagnostics script and returned, check for an error key in the response if (isset($responseArray['error'])) { return ["status" => "failed", "message" => $responseArray['message']]; } @@ -74,7 +74,6 @@ class DiagnosticsController extends ApiMutableModelControllerBase // Decode JSON to PHP array $responseArray = json_decode($response, true); - // Since errors are handled by the caddy_diagnostics script and returned as json, check for an error key in the response if (isset($responseArray['error'])) { return ["status" => "failed", "message" => $responseArray['message']]; } @@ -94,7 +93,6 @@ class DiagnosticsController extends ApiMutableModelControllerBase // Decode JSON to PHP array $responseArray = json_decode($response, true); - // Since errors are handled by the caddy_diagnostics script and returned as json, check for an error key in the response if (isset($responseArray['error'])) { return ["status" => "failed", "message" => $responseArray['message']]; } diff --git a/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/Api/ReverseProxyController.php b/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/Api/ReverseProxyController.php index 5f32443d0..193aa298b 100644 --- a/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/Api/ReverseProxyController.php +++ b/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/Api/ReverseProxyController.php @@ -26,7 +26,6 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - * */ namespace OPNsense\Caddy\Api; @@ -70,14 +69,15 @@ class ReverseProxyController extends ApiMutableModelControllerBase } /** - * Centralized and generalized helper function for searching across different sections of the reverse proxy setup. + * Generalized helper function for searching across different sections of the reverse proxy setup. * This function mostly helps when model relation fields are used. * It filters entries based on UUIDs provided as an argument. The section or key used for the UUID * can be specified, allowing for direct or indirect UUID referencing. * - * @param string $modelPath The data model path identifier, pointing to the section of the model being searched. - * @param string $uuidSearchBase The request parameter name for the comma-separated list of UUIDs to filter the search results. - * @param string|null $uuidReferenceKey The specific attribute key used to fetch the UUID for filtering. If null, defaults to the item's own UUID. + * @param string $modelPath The data model path identifier, pointing to section of model being searched. + * @param string $uuidSearchBase The request parameter name for the comma-separated list of UUIDs. + * @param string|null $uuidReferenceKey Attribute key used to fetch the UUID for filtering. + * If null, uses item's own UUID. * @return array Filtered search results. */ private function searchActionHelper($modelPath, $uuidSearchBase, $uuidReferenceKey = null) @@ -89,8 +89,12 @@ class ReverseProxyController extends ApiMutableModelControllerBase // Define a filter function to determine which items to include based on the UUID. $filterFunction = function ($modelItem) use ($uuidArray, $uuidReferenceKey) { - // Extract UUID from the item, using the specified UUID key if provided, otherwise default to direct UUID access. - $modelUUID = ($uuidReferenceKey !== null) ? (string)$modelItem->$uuidReferenceKey : (string)$modelItem->getAttributes()['uuid']; + // Extract UUID from the item, using the specified UUID key if provided, else default to direct UUID access. + if ($uuidReferenceKey !== null) { + $modelUUID = (string)$modelItem->$uuidReferenceKey; + } else { + $modelUUID = (string)$modelItem->getAttributes()['uuid']; + } // Include the item if the UUID array is empty or if the item's UUID is in the array. return empty($uuidArray) || in_array($modelUUID, $uuidArray, true); }; @@ -245,8 +249,10 @@ class ReverseProxyController extends ApiMutableModelControllerBase { if ($this->request->isPost()) { $postData = $this->request->getPost(); - - if (isset($postData['basicauth']['basicauthpass']) && !empty(trim($postData['basicauth']['basicauthpass']))) { + if ( + isset($postData['basicauth']['basicauthpass']) + && !empty(trim($postData['basicauth']['basicauthpass'])) + ) { $plainPassword = $postData['basicauth']['basicauthpass']; $hashedPassword = password_hash($plainPassword, PASSWORD_BCRYPT); $_POST['basicauth']['basicauthpass'] = $hashedPassword; @@ -260,8 +266,10 @@ class ReverseProxyController extends ApiMutableModelControllerBase { if ($this->request->isPost()) { $postData = $this->request->getPost(); - - if (isset($postData['basicauth']['basicauthpass']) && !empty(trim($postData['basicauth']['basicauthpass']))) { + if ( + isset($postData['basicauth']['basicauthpass']) + && !empty(trim($postData['basicauth']['basicauthpass'])) + ) { $plainPassword = $postData['basicauth']['basicauthpass']; $hashedPassword = password_hash($plainPassword, PASSWORD_BCRYPT); $_POST['basicauth']['basicauthpass'] = $hashedPassword; diff --git a/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Caddy.php b/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Caddy.php index 9f76fe20e..42972f8d1 100644 --- a/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Caddy.php +++ b/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Caddy.php @@ -59,9 +59,15 @@ class Caddy extends BaseModel if (isset($combos[$comboKey])) { // Use dynamic $key for message referencing $messages->appendMessage(new Message( - sprintf(gettext("Duplicate entry: The combination of '%s' and port '%s' is already used. Each combination of domain and port must be unique."), $fromDomain, $port), - $key . ".FromDomain", // Adjusted to use dynamic key - "DuplicateDomainPort" + sprintf( + gettext( + 'Duplicate entry: The combination of %s and port %s is already used. ' . + 'Each combination of domain and port must be unique.' + ), + $fromDomain, + $port + ), + $key . ".FromDomain" )); } else { $combos[$comboKey] = true; @@ -98,9 +104,14 @@ class Caddy extends BaseModel if (!$isValid) { $key = $subdomain->__reference; // Dynamic key based on subdomain reference $messages->appendMessage(new Message( - sprintf(gettext("Invalid subdomain configuration: '%s' does not fall under any configured wildcard domain."), $subdomainName), - $key . ".FromDomain", // Use dynamic key for message referencing - "InvalidSubdomain" + sprintf( + gettext( + 'Invalid subdomain configuration: %s does not fall ' . + 'under any configured wildcard domain.' + ), + $subdomainName + ), + $key . ".FromDomain" )); } } @@ -140,7 +151,18 @@ class Caddy extends BaseModel if (!empty($overlap) && $tlsAutoHttpsSetting !== 'off') { $portOverlap = implode(', ', $overlap); $messages->appendMessage(new Message( - sprintf(gettext('To use "Auto HTTPS", resolve these conflicting ports (%s) that are currently configured for the OPNsense WebGUI. Go to "System - Settings - Administration". To release port 80, enable "Disable web GUI redirect rule". To release port %s, change "TCP port" to a non-standard port, e.g., 8443.'), $portOverlap, $httpsPort), + sprintf( + gettext( + 'To use "Auto HTTPS", resolve these conflicting ports %s ' . + 'that are currently configured for the OPNsense WebGUI. ' . + 'Go to "System - Settings - Administration". ' . + 'To release port 80, enable "Disable web GUI redirect rule". ' . + 'To release port %s, change "TCP port" to a non-standard port, ' . + 'e.g., 8443.' + ), + $portOverlap, + $httpsPort + ), "general.TlsAutoHttps" )); } @@ -193,12 +215,23 @@ class Caddy extends BaseModel public function performValidation($validateFullModel = false) { $messages = parent::performValidation($validateFullModel); + // 1. Check domain-port combinations - $this->checkForUniquePortCombos($this->reverseproxy->reverse->iterateItems(), $messages); + $this->checkForUniquePortCombos( + $this->reverseproxy->reverse->iterateItems(), + $messages + ); + // 2. Check that subdomains are under a wildcard or exact domain - $this->checkSubdomainsAgainstDomains($this->reverseproxy->subdomain->iterateItems(), $this->reverseproxy->reverse->iterateItems(), $messages); + $this->checkSubdomainsAgainstDomains( + $this->reverseproxy->subdomain->iterateItems(), + $this->reverseproxy->reverse->iterateItems(), + $messages + ); + // 3. Check WebGUI conflicts $this->checkWebGuiSettings($messages); + // 4. Check for ACME Email requirement $this->checkAcmeEmailAutoHttps($messages); // 5. Check for TLS conflicts in Domain 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 2650cb267..f70f54857 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 @@ -10,9 +10,7 @@ - - Please enter a valid email address. - + On (default) @@ -106,9 +104,7 @@ FATAL - - Please enter a valid URL, starting with http or https. - + 1 @@ -150,17 +146,11 @@ Y - Please enter a valid 'from' domain. N - Y Y - N + Please enter a valid domain name. - - Please enter a valid 'from' port number. - Y - N - + @@ -189,10 +179,7 @@ - - Please enter a valid 'to' domain or IP address. - Y - + @@ -213,8 +200,8 @@ Y - Please enter a valid 'from' Subdomain that is based upon the wildcard domain. - N + N + Please enter a valid domain name. @@ -241,10 +228,7 @@ Y - - Please enter a valid 'to' domain or IP address. - Y - + @@ -282,7 +266,7 @@ /^(\/.*)?$/u - Please enter a valid 'Handle Path' that starts with '/'. + Please enter a valid Path that starts with '/'.
@@ -297,19 +281,14 @@
Y - Please enter a valid 'to' domain or IP address. - Y , Y + Please enter one or multiple valid IP addresses, hostnames or FQDNs. - - Please enter a valid 'to' port number. - Y - N - + /^(\/.*)?$/u - Please enter a valid 'Backend Path' that starts with '/'. + Please enter a valid Path that starts with '/'. 1 @@ -351,30 +330,21 @@ ca - - Please enter a valid hostname or IP address. - Y - Y - Y - N - + Y
- + Y - /^([\t\n\v\f\r 0-9a-zA-Z.,_*-\x{00A0}-\x{FFFF}]){1,255}$/u - Please provide a valid Access List Name. Y - Y , Y Y - Please enter valid IP address(es) or network(s), separated by commas. + Please enter one or multiple valid IP addresses or networks. diff --git a/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Migrations/M1_1_3.php b/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Migrations/M1_1_3.php index c103f8d48..649408dbc 100644 --- a/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Migrations/M1_1_3.php +++ b/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Migrations/M1_1_3.php @@ -31,7 +31,9 @@ namespace OPNsense\Caddy\Migrations; use OPNsense\Base\BaseModelMigration; use OPNsense\Core\Config; +// @codingStandardsIgnoreStart class M1_1_3 extends BaseModelMigration +// @codingStandardsIgnoreEnd { public function run($model) { diff --git a/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Migrations/M1_1_8.php b/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Migrations/M1_1_8.php index 0687d49ab..c506375a1 100644 --- a/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Migrations/M1_1_8.php +++ b/www/caddy/src/opnsense/mvc/app/models/OPNsense/Caddy/Migrations/M1_1_8.php @@ -31,7 +31,9 @@ namespace OPNsense\Caddy\Migrations; use OPNsense\Base\BaseModelMigration; use OPNsense\Core\Config; +// @codingStandardsIgnoreStart class M1_1_8 extends BaseModelMigration +// @codingStandardsIgnoreEnd { public function run($model) { 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 0f6078b46..f65ef168c 100755 --- a/www/caddy/src/opnsense/scripts/OPNsense/Caddy/caddy_certs.php +++ b/www/caddy/src/opnsense/scripts/OPNsense/Caddy/caddy_certs.php @@ -2,8 +2,7 @@ object(); $temp_dir = '/var/db/caddy/data/caddy/certificates/temp/'; -function extract_and_save_certificates($configObj, $temp_dir) -{ - // Traverse through certificates - foreach ($configObj->cert as $cert) { - $cert_refid = (string)$cert->refid; - $cert_content = base64_decode((string)$cert->crt); - $key_content = base64_decode((string)$cert->prv); - $cert_chain = $cert_content; +// Traverse through certificates +foreach ($configObj->cert as $cert) { + $cert_refid = (string) $cert->refid; + $cert_content = base64_decode((string) $cert->crt); + $key_content = base64_decode((string) $cert->prv); + $cert_chain = $cert_content; - // Handle CA and possible intermediate CA to create a certificate bundle - if (!empty($cert->caref)) { - foreach ($configObj->ca as $ca) { - if ((string)$cert->caref == (string)$ca->refid) { - $ca_content = base64_decode((string)$ca->crt); - $cert_chain .= "\n" . $ca_content; + // Handle CA and possible intermediate CA to create a certificate bundle + if (!empty($cert->caref)) { + foreach ($configObj->ca as $ca) { + if ((string) $cert->caref === (string) $ca->refid) { + $ca_content = base64_decode((string) $ca->crt); + $cert_chain .= "\n" . $ca_content; - if (!empty($ca->caref)) { - foreach ($configObj->ca as $parent_ca) { - if ((string)$ca->caref == (string)$parent_ca->refid) { - $parent_ca_content = base64_decode((string)$parent_ca->crt); - $cert_chain .= "\n" . $parent_ca_content; - break; - } + if (!empty($ca->caref)) { + foreach ($configObj->ca as $parent_ca) { + if ((string) $ca->caref === (string) $parent_ca->refid) { + $parent_ca_content = base64_decode((string) $parent_ca->crt); + $cert_chain .= "\n" . $parent_ca_content; + break; } } } } } - - // Save the certificate chain and private key - file_put_contents($temp_dir . $cert_refid . '.pem', $cert_chain); - file_put_contents($temp_dir . $cert_refid . '.key', $key_content); } - // Traverse through CA certificates and save them - foreach ($configObj->ca as $ca) { - $ca_refid = (string)$ca->refid; - $ca_content = base64_decode((string)$ca->crt); - - // Save the CA certificate - file_put_contents($temp_dir . $ca_refid . '.pem', $ca_content); - } + // Save the certificate chain and private key + file_put_contents($temp_dir . $cert_refid . '.pem', $cert_chain); + file_put_contents($temp_dir . $cert_refid . '.key', $key_content); } -extract_and_save_certificates($configObj, $temp_dir); +// Traverse through CA certificates and save them +foreach ($configObj->ca as $ca) { + $ca_refid = (string) $ca->refid; + $ca_content = base64_decode((string) $ca->crt); + + // Save the CA certificate + file_put_contents($temp_dir . $ca_refid . '.pem', $ca_content); +} diff --git a/www/caddy/src/opnsense/scripts/OPNsense/Caddy/caddy_control.py b/www/caddy/src/opnsense/scripts/OPNsense/Caddy/caddy_control.py index 79e9a8226..add576358 100755 --- a/www/caddy/src/opnsense/scripts/OPNsense/Caddy/caddy_control.py +++ b/www/caddy/src/opnsense/scripts/OPNsense/Caddy/caddy_control.py @@ -30,19 +30,23 @@ import subprocess import json import sys -def run_service_command(action, action_message): + +def run_service_command(service_action, action_message): result = {"message": action_message} - if action == "validate": + if service_action == "validate": try: # Validate the Caddyfile with explicit --config flag, capturing both stdout and stderr - validation_output = subprocess.check_output(["caddy", "validate", "--config", "/usr/local/etc/caddy/Caddyfile"], stderr=subprocess.STDOUT, text=True) + validation_output = subprocess.check_output( + ["caddy", "validate", "--config", "/usr/local/etc/caddy/Caddyfile"], stderr=subprocess.STDOUT, + text=True) if "Valid configuration" in validation_output: result["status"] = "ok" result["message"] = "Caddy configuration is valid." else: # Search for the specific error message - error_msg = next((line for line in validation_output.split('\n') if line.startswith("Error:")), "Caddy configuration is not valid.") + error_msg = next((line for line in validation_output.split('\n') if line.startswith("Error:")), + "Caddy configuration is not valid.") result["status"] = "failed" result["message"] = error_msg except subprocess.CalledProcessError as e: @@ -52,7 +56,7 @@ def run_service_command(action, action_message): result["message"] = error_msg else: try: - subprocess.run(["service", "caddy", action], check=True) + subprocess.run(["service", "caddy", service_action], check=True) result["status"] = "ok" except subprocess.CalledProcessError as e: result["status"] = "failed" @@ -60,29 +64,36 @@ def run_service_command(action, action_message): return json.dumps(result) -# Updated actions dictionary + +# "cmd_action": "service_action" actions = { "start": "start", "stop": "stop", "restart": "restart", - "reload": "reloadssl", # Forces the reload even if the config in the Caddyfile is unchanged, using an extra command of the rc.d script, forcing certificates in the filesystem to reload. + "reload": "reloadssl", + # Reloadssl reloads even if the config in the Caddyfile is unchanged, using an extra command of the rc.d script, + # forcing certificates in the filesystem to be reloaded. "validate": "validate" # Validate action } if __name__ == "__main__": - action = sys.argv[1] # Get the action from the command-line argument - if action in actions: - service_action = actions[action] - message = f"{action.capitalize()}ing Caddy service" if action != "validate" else "Validating Caddy configuration" + if len(sys.argv) > 1: + action = sys.argv[1] # Get the action from the command-line argument + if action in actions: + cmd_action = action + service_action = actions[action] + message = f"{cmd_action.capitalize()} Caddy service" - # Call setup script for 'validate' and 'reloadssl' actions - # This is needed because the setup script triggers the caddy_certs.php script, which exports all certificates into the filesystem. - # Caddy reloads certificates when reloadssl is used. Because it is a non standard command, the caddy_setup script will not be triggered in /etc/rc.conf.d/caddy. - # The validate command needs it to make sure all certificates are in the filesystem, because otherwise the validation fails. - if service_action in ["validate", "reloadssl"]: - subprocess.run(["/usr/local/opnsense/scripts/OPNsense/Caddy/setup.sh"], check=True) + # Call setup script for 'validate' and 'reloadssl' actions. This is needed because the setup script triggers + # the caddy_certs.php script, which exports all certificates into the filesystem. Caddy reloads certificates + # when reloadssl is used. Because it is a non standard command, the caddy_setup script will not be triggered + # in /etc/rc.conf.d/caddy. The validate command needs it to make sure all certificates are in the filesystem, + # because otherwise the validation fails. + if service_action in ["validate", "reloadssl"]: + subprocess.run(["/usr/local/opnsense/scripts/OPNsense/Caddy/setup.sh"], check=True) - # Continue with the service action - print(run_service_command(service_action, message)) + print(run_service_command(service_action, message)) + else: + print(json.dumps({"status": "failed", "message": f"Unknown action: {action}"})) else: - print(json.dumps({"status": "failed", "message": f"Unknown action: {action}"})) + print(json.dumps({"status": "failed", "message": "No action provided"})) diff --git a/www/caddy/src/opnsense/scripts/OPNsense/Caddy/caddy_diagnostics.py b/www/caddy/src/opnsense/scripts/OPNsense/Caddy/caddy_diagnostics.py index f42fd6065..ab55778a6 100755 --- a/www/caddy/src/opnsense/scripts/OPNsense/Caddy/caddy_diagnostics.py +++ b/www/caddy/src/opnsense/scripts/OPNsense/Caddy/caddy_diagnostics.py @@ -33,6 +33,7 @@ import subprocess import asyncio from datetime import datetime + # Function to show the Caddy configuration from a JSON file def show_caddy_config(): config_path = "/var/db/caddy/config/caddy/autosave.json" @@ -48,10 +49,12 @@ def show_caddy_config(): except FileNotFoundError: print(json.dumps({"error": "File not found", "message": "Caddy autosave.json configuration file not found"})) except json.JSONDecodeError: - print(json.dumps({"error": "Invalid JSON", "message": "Error decoding the Caddy autosave.json, the file is not valid JSON"})) + print(json.dumps( + {"error": "Invalid JSON", "message": "Error decoding the Caddy autosave.json, the file is not valid JSON"})) except Exception as e: print(json.dumps({"error": "General Error", "message": str(e)})) + def show_caddyfile(): caddyfile_path = "/usr/local/etc/caddy/Caddyfile" @@ -65,6 +68,7 @@ def show_caddyfile(): except Exception as e: print(json.dumps({"error": "General Error", "message": str(e)})) + # Function to extract certificate information using openssl command async def extract_certificate_info(cert_path): try: @@ -105,6 +109,7 @@ async def extract_certificate_info(cert_path): except Exception as e: raise RuntimeError(f"Error extracting certificate info for {cert_path}: {str(e)}") + # Function to find certificates and create tasks to extract info async def find_certificates(base_dir): tasks = [] @@ -123,6 +128,7 @@ async def find_certificates(base_dir): results = await asyncio.gather(*tasks, return_exceptions=True) return [result for result in results if not isinstance(result, Exception)] + # Function to show certificates, processing all found in the given directory async def show_certificates(): # Function to show certificates, processing all found in the given directory @@ -136,25 +142,26 @@ async def show_certificates(): except Exception as e: print(json.dumps({"error": "General Error", "message": str(e)})) + # Action handler -def perform_action(action): +def perform_action(cmd_action): actions = { "config": show_caddy_config, "caddyfile": show_caddyfile, "certificate": lambda: asyncio.run(show_certificates()) } - action_func = actions.get(action) + action_func = actions.get(cmd_action) if action_func: action_func() else: # Output error details in JSON format if action is unknown - print(json.dumps({"error": "Unknown Action", "message": f"Unknown action: {action}"})) + print(json.dumps({"error": "Unknown Action", "message": f"Unknown action: {cmd_action}"})) + if __name__ == "__main__": if len(sys.argv) > 1: - action = sys.argv[1] - perform_action(action) + perform_action(sys.argv[1]) else: # Output error details in JSON format if no action is specified print(json.dumps({"error": "No Action Specified", "message": "No action specified"})) diff --git a/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/Caddyfile b/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/Caddyfile index eb4ce0ad8..c06342fc9 100644 --- a/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/Caddyfile +++ b/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/Caddyfile @@ -37,11 +37,11 @@ #} log { {% if generalSettings.LogAccessPlain|default("0") == "0" %} - {% for reverse in helpers.toList('Pischem.caddy.reverseproxy.reverse') %} - {% if reverse.enabled|default("0") == "1" and reverse.AccessLog|default("0") == "1" %} - include http.log.access.{{ reverse['@uuid'] }} - {% endif %} - {% endfor %} + {% for reverse in helpers.toList('Pischem.caddy.reverseproxy.reverse') %} + {% if reverse.enabled|default("0") == "1" and reverse.AccessLog|default("0") == "1" %} + include http.log.access.{{ reverse['@uuid'] }} + {% endif %} + {% endfor %} {% endif %} output net unixgram//var/caddy/var/run/log { } @@ -49,7 +49,7 @@ time_format rfc3339 } {% if generalSettings.LogLevel %} - level {{ generalSettings.LogLevel }} + level {{ generalSettings.LogLevel }} {% endif %} } @@ -89,10 +89,10 @@ {% if hasAccessList or hasLogCredentials %} servers { {% if hasAccessList %} - trusted_proxies static {{ accessList.clientIps.split(',') | join(' ') }} + trusted_proxies static {{ accessList.clientIps.split(',') | join(' ') }} {% endif %} {% if hasLogCredentials %} - log_credentials + log_credentials {% endif %} } {% endif %} @@ -175,11 +175,11 @@ {% endif %} domains { {% for domain in dynDnsDomains %} - {{ domain }} + {{ domain }} {% endfor %} } {% if dynDnsSimpleHttp %} - ip_source simple_http {{ dynDnsSimpleHttp }} + ip_source simple_http {{ dynDnsSimpleHttp }} {% endif %} {% if dynDnsInterface %} {% set physicalInterfaceNames = [] %} @@ -189,16 +189,16 @@ ip_source interface {{ physicalInterfaceNames | join(',') }} {% endif %} {% if dynDnsCheckInterval %} - check_interval {{ dynDnsCheckInterval }}s + check_interval {{ dynDnsCheckInterval }}s {% endif %} {% if dynDnsIpVersions %} - versions {{ dynDnsIpVersions }} + versions {{ dynDnsIpVersions }} {% endif %} {% if dynDnsTtl %} - ttl {{ dynDnsTtl }}s + ttl {{ dynDnsTtl }}s {% endif %} {% if dynDnsUpdateOnly|default("0") == "1" %} - update_only + update_only {% endif %} } {% endif %} @@ -211,11 +211,11 @@ #} {% set emailValue = helpers.toList('Pischem.caddy.general.TlsEmail') | first %} {% if emailValue %} - email {{ emailValue }} + email {{ emailValue }} {% endif %} {% set autoHttpsValue = helpers.toList('Pischem.caddy.general.TlsAutoHttps') | first %} {% if autoHttpsValue %} - auto_https {{ autoHttpsValue }} + auto_https {{ autoHttpsValue }} {% endif %} {# # Important: Grace Period influences how fast the server can finish reloads with open connections, by forcing termination. @@ -299,8 +299,8 @@ # It uses a 'handle' object that specifies which headers to manipulate based on their @UUIDs. # Each handle can have multiple of these HTTP headers assigned. # Parameters: -# @param handle (@object): -# - @uuid (@string) +# @param handle (object): +# - @uuid (string) # - HeaderUpDown (string): Determines the direction of the header. # - HeaderType (string): Specifies the name of the header. # - HeaderValue (string, optional): The new value to set for the header, if any. @@ -341,15 +341,15 @@ # Purpose: Sets up the handle with the reverse proxy configurations. The TLS Settings are generated here for the Upstream. # Integrated Macros: header_manipulation # Parameters: -# @param handle (@object): -# - @uuid (@string) +# @param handle (object): +# - @uuid (string) # - HandleType (string): Specifies the handling strategy. # - HandlePath (string, optional): The path the handle should match on. # - ToDomain (string): Target domain for the reverse proxy. # - ToPort (string, optional): Target port on the ToDomain. # - ToPath (string, optional): Destination path on the ToDomain. # - HttpTls (boolean, optional): Enable TLS for the connection. -# - HttpNtlm (boolean, optional): Enable NTLM authentication for the connection. +# - HttpNtlm (boolean, optional): Enable NTLM authentication for the connection. Not all HTTP options apply to NTLM. # - 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. @@ -363,7 +363,7 @@ {% include "OPNsense/Caddy/includeAuthProvider" %} {% endif %} {% if handle.ToPath|default("") != "" %} - rewrite * {{ handle.ToPath }}{uri} + rewrite * {{ handle.ToPath }}{uri} {% endif %} reverse_proxy {% for domain in handle.ToDomain.split(',') %} {# Check if the domain is IPv6 and wrap in square brackets if necessary #} @@ -373,22 +373,22 @@ {% endfor %} { {{ header_manipulation(handle) }} {% if handle.PassiveHealthFailDuration|default("") %} - fail_duration {{ handle.PassiveHealthFailDuration }}s + fail_duration {{ handle.PassiveHealthFailDuration }}s {% endif %} {% if handle.HttpTls|default("0") == "1" or handle.HttpTlsInsecureSkipVerify|default("0") == "1" or handle.HttpTlsTrustedCaCerts or handle.HttpTlsServerName or handle.HttpVersion or handle.HttpKeepalive %} {% if handle.HttpNtlm|default("0") == "1" %} transport http_ntlm { {% if handle.HttpTls|default("0") == "1" %} - tls + tls {% endif %} {% if handle.HttpTlsInsecureSkipVerify|default("0") == "1" %} - tls_insecure_skip_verify + tls_insecure_skip_verify {% endif %} {% if handle.HttpTlsTrustedCaCerts %} - tls_trust_pool file /var/db/caddy/data/caddy/certificates/temp/{{ handle.HttpTlsTrustedCaCerts }}.pem + tls_trust_pool file /var/db/caddy/data/caddy/certificates/temp/{{ handle.HttpTlsTrustedCaCerts }}.pem {% endif %} {% if handle.HttpTlsServerName %} - tls_server_name {{ handle.HttpTlsServerName }} + tls_server_name {{ handle.HttpTlsServerName }} {% endif %} } {% else %} @@ -406,16 +406,16 @@ {% endif %} {% endif %} {% if handle.HttpTls|default("0") == "1" %} - tls + tls {% endif %} {% if handle.HttpTlsInsecureSkipVerify|default("0") == "1" %} - tls_insecure_skip_verify + tls_insecure_skip_verify {% endif %} {% if handle.HttpTlsTrustedCaCerts %} - tls_trust_pool file /var/db/caddy/data/caddy/certificates/temp/{{ handle.HttpTlsTrustedCaCerts }}.pem + tls_trust_pool file /var/db/caddy/data/caddy/certificates/temp/{{ handle.HttpTlsTrustedCaCerts }}.pem {% endif %} {% if handle.HttpTlsServerName %} - tls_server_name {{ handle.HttpTlsServerName }} + tls_server_name {{ handle.HttpTlsServerName }} {% endif %} } {% endif %} @@ -431,10 +431,10 @@ # only get to the reverse proxy, when the access list matches. Invert is also possible, to explicitely deny IPs. # The assembly is handled by the "Section: Reverse Proxy Configurations". # Parameters: -# @param accesslist (@object): -# - @uuid (@string) -# - clientIps (@string): A comma-separated list of client IP addresses -# - invert (@boolean): A flag that inverts the logic of the access list +# @param accesslist (object): +# - uuid (string) +# - clientIps (string): A comma-separated list of client IP addresses +# - invert (boolean): A flag that inverts the logic of the access list #} {% macro access_list_configuration(accesslist, invert) %} {% set client_ips = accesslist.clientIps.split(',') %} @@ -448,11 +448,11 @@ # Macro: basicauth_configuration # Purpose: Implements basic authentication with a username and password for access. # Parameters: -# @param basicauth_uuids (@string): A comma-separated list of UUIDs, each UUID corresponding to +# @param basicauth_uuids (string): A comma-separated list of UUIDs, each UUID corresponding to # a specific user credentials (username and password). -# - @uuid (@string) -# - basicauthuser (@string): The username required for authentication. -# - basicauthpass (@string): The password associated with the username. +# - @uuid (string) +# - basicauthuser (string): The username required for authentication. +# - basicauthpass (string): The password associated with the username. #} {% macro basicauth_configuration(basicauth_uuids) %} {% if basicauth_uuids %} @@ -482,139 +482,139 @@ # - Order of Wildcard Domains and Subdomains: Handles for wildcard domains come after all subdomains. #} {% for reverse in helpers.toList('Pischem.caddy.reverseproxy.reverse') %} -{% if reverse.enabled|default("0") == "1" %} -# Reverse Proxy Domain: "{{ reverse['@uuid'] }}" -{# The default are encrypted connections, uncencrypted connections have to render http:// #} -{% if reverse.DisableTls|default("0") == "1" %}http://{% endif %}{{ reverse.FromDomain|default("") }}{% if reverse.FromPort %}:{{ reverse.FromPort }}{% endif %} { - {% if reverse.AccessLog|default("0") == "1" %} - {% if generalSettings.LogAccessPlain|default("0") == "0" %} - log {{ reverse['@uuid'] }} - {% else %} - log { - output file /var/log/caddy/access/{{ reverse['@uuid'] }}.log { - roll_keep_for {{ generalSettings.LogAccessPlainKeep|default("10") }}d - } - } - {% endif %} - {% endif %} - {% set customCert = reverse.CustomCertificate|default("") %} - {% set dnsChallenge = reverse.DnsChallenge|default("0") %} - {{ tls_configuration(dnsProvider, dnsApiKey, customCert, dnsChallenge, dnsSecretApiKey, TlsDnsOptionalField1, TlsDnsOptionalField2, TlsDnsOptionalField3, TlsDnsOptionalField4) }} - - {% if not reverse.accesslist %} - {% set basicauth_uuids = reverse.basicauth %} - {{ basicauth_configuration(basicauth_uuids) }} - {% endif %} - - {% for subdomain in helpers.toList('Pischem.caddy.reverseproxy.subdomain') %} - {% if subdomain.enabled|default("0") == "1" and subdomain.reverse == reverse['@uuid'] %} - @{{ subdomain['@uuid'] }} { - host {{ subdomain.FromDomain }} - } - handle @{{ subdomain['@uuid'] }} { - - {% if not subdomain.accesslist %} - {% set subdomain_basicauth_uuids = subdomain.basicauth %} - {{ basicauth_configuration(subdomain_basicauth_uuids) }} - {% endif %} - - {% if subdomain.accesslist %} - {% set accesslist = helpers.toList('Pischem.caddy.reverseproxy.accesslist') | selectattr('@uuid', 'equalto', subdomain.accesslist) | first %} - {{ access_list_configuration(accesslist, accesslist.accesslistInvert|default("0") == "1") }} - handle @{{ accesslist['@uuid'] }} { - - {% set subdomain_basicauth_uuids = subdomain.basicauth %} - {{ basicauth_configuration(subdomain_basicauth_uuids) }} - - {% set subdomain_handles = helpers.toList('Pischem.caddy.reverseproxy.handle') | selectattr('subdomain', 'equalto', subdomain['@uuid']) | list %} - {% for handle in subdomain_handles %} - {% if handle.enabled|default("0") == "1" and handle.HandlePath %} - {{ reverse_proxy_configuration(handle) }} + {% if reverse.enabled|default("0") == "1" %} + # Reverse Proxy Domain: "{{ reverse['@uuid'] }}" + {# The default are encrypted connections, uncencrypted connections have to render http:// #} + {% if reverse.DisableTls|default("0") == "1" %}http://{% endif %}{{ reverse.FromDomain|default("") }}{% if reverse.FromPort %}:{{ reverse.FromPort }}{% endif %} { + {% if reverse.AccessLog|default("0") == "1" %} + {% if generalSettings.LogAccessPlain|default("0") == "0" %} + log {{ reverse['@uuid'] }} + {% else %} + log { + output file /var/log/caddy/access/{{ reverse['@uuid'] }}.log { + roll_keep_for {{ generalSettings.LogAccessPlainKeep|default("10") }}d + } + } + {% endif %} {% endif %} + {% set customCert = reverse.CustomCertificate|default("") %} + {% set dnsChallenge = reverse.DnsChallenge|default("0") %} + {{ tls_configuration(dnsProvider, dnsApiKey, customCert, dnsChallenge, dnsSecretApiKey, TlsDnsOptionalField1, TlsDnsOptionalField2, TlsDnsOptionalField3, TlsDnsOptionalField4) }} + + {% if not reverse.accesslist %} + {% set basicauth_uuids = reverse.basicauth %} + {{ basicauth_configuration(basicauth_uuids) }} + {% endif %} + + {% for subdomain in helpers.toList('Pischem.caddy.reverseproxy.subdomain') %} + {% if subdomain.enabled|default("0") == "1" and subdomain.reverse == reverse['@uuid'] %} + @{{ subdomain['@uuid'] }} { + host {{ subdomain.FromDomain }} + } + handle @{{ subdomain['@uuid'] }} { + + {% if not subdomain.accesslist %} + {% set subdomain_basicauth_uuids = subdomain.basicauth %} + {{ basicauth_configuration(subdomain_basicauth_uuids) }} + {% endif %} + + {% if subdomain.accesslist %} + {% set accesslist = helpers.toList('Pischem.caddy.reverseproxy.accesslist') | selectattr('@uuid', 'equalto', subdomain.accesslist) | first %} + {{ access_list_configuration(accesslist, accesslist.accesslistInvert|default("0") == "1") }} + handle @{{ accesslist['@uuid'] }} { + + {% set subdomain_basicauth_uuids = subdomain.basicauth %} + {{ basicauth_configuration(subdomain_basicauth_uuids) }} + + {% set subdomain_handles = helpers.toList('Pischem.caddy.reverseproxy.handle') | selectattr('subdomain', 'equalto', subdomain['@uuid']) | list %} + {% for handle in subdomain_handles %} + {% if handle.enabled|default("0") == "1" and handle.HandlePath %} + {{ reverse_proxy_configuration(handle) }} + {% endif %} + {% endfor %} + {% for handle in subdomain_handles %} + {% if handle.enabled|default("0") == "1" and not handle.HandlePath %} + {{ reverse_proxy_configuration(handle) }} + {% endif %} + {% endfor %} + } + {% else %} + {% set subdomain_handles = helpers.toList('Pischem.caddy.reverseproxy.handle') | selectattr('subdomain', 'equalto', subdomain['@uuid']) | list %} + {% for handle in subdomain_handles %} + {% if handle.enabled|default("0") == "1" and handle.HandlePath %} + {{ reverse_proxy_configuration(handle) }} + {% endif %} + {% endfor %} + {% for handle in subdomain_handles %} + {% if handle.enabled|default("0") == "1" and not handle.HandlePath %} + {{ reverse_proxy_configuration(handle) }} + {% endif %} + {% endfor %} + {% endif %} + + {% if subdomain.accesslist %} + {% if accesslist.HttpResponseCode or accesslist.HttpResponseMessage %} + respond {{ '"' + accesslist.HttpResponseMessage|default('') + '"' if accesslist.HttpResponseMessage else '' }} {{ accesslist.HttpResponseCode|default(403) }} + {% elif Pischem.caddy.general.abort|default("0") == "1" %} + abort + {% endif %} + {% else %} + {% if Pischem.caddy.general.abort|default("0") == "1" %} + abort + {% endif %} + {% endif %} + } + {% endif %} {% endfor %} - {% for handle in subdomain_handles %} - {% if handle.enabled|default("0") == "1" and not handle.HandlePath %} - {{ reverse_proxy_configuration(handle) }} + + {% if reverse.accesslist %} + {% set accesslist = helpers.toList('Pischem.caddy.reverseproxy.accesslist') | selectattr('@uuid', 'equalto', reverse.accesslist) | first %} + {{ access_list_configuration(accesslist, accesslist.accesslistInvert|default("0") == "1") }} + handle @{{ accesslist['@uuid'] }} { + + {% set basicauth_uuids = reverse.basicauth %} + {{ basicauth_configuration(basicauth_uuids) }} + + {% set wildcard_handles = helpers.toList('Pischem.caddy.reverseproxy.handle') | selectattr('reverse', 'equalto', reverse['@uuid']) | selectattr('subdomain', 'undefined') | list %} + {% for handle in wildcard_handles %} + {% if handle.enabled|default("0") == "1" and handle.HandlePath %} + {{ reverse_proxy_configuration(handle) }} + {% endif %} + {% endfor %} + {% for handle in wildcard_handles %} + {% if handle.enabled|default("0") == "1" and not handle.HandlePath %} + {{ reverse_proxy_configuration(handle) }} + {% endif %} + {% endfor %} + } + {% else %} + {% set wildcard_handles = helpers.toList('Pischem.caddy.reverseproxy.handle') | selectattr('reverse', 'equalto', reverse['@uuid']) | selectattr('subdomain', 'undefined') | list %} + {% for handle in wildcard_handles %} + {% if handle.enabled|default("0") == "1" and handle.HandlePath %} + {{ reverse_proxy_configuration(handle) }} + {% endif %} + {% endfor %} + {% for handle in wildcard_handles %} + {% if handle.enabled|default("0") == "1" and not handle.HandlePath %} + {{ reverse_proxy_configuration(handle) }} + {% endif %} + {% endfor %} + {% endif %} + + {% set accesslist = helpers.toList('Pischem.caddy.reverseproxy.accesslist') | selectattr('@uuid', 'equalto', reverse.accesslist) | first %} + {% if accesslist %} + {% if accesslist.HttpResponseCode or accesslist.HttpResponseMessage %} + respond {{ '"' + accesslist.HttpResponseMessage|default('') + '"' if accesslist.HttpResponseMessage else '' }} {{ accesslist.HttpResponseCode|default(403) }} + {% elif Pischem.caddy.general.abort|default("0") == "1" %} + abort + {% endif %} + {% else %} + {% if Pischem.caddy.general.abort|default("0") == "1" %} + abort + {% endif %} {% endif %} - {% endfor %} } - {% else %} - {% set subdomain_handles = helpers.toList('Pischem.caddy.reverseproxy.handle') | selectattr('subdomain', 'equalto', subdomain['@uuid']) | list %} - {% for handle in subdomain_handles %} - {% if handle.enabled|default("0") == "1" and handle.HandlePath %} - {{ reverse_proxy_configuration(handle) }} - {% endif %} - {% endfor %} - {% for handle in subdomain_handles %} - {% if handle.enabled|default("0") == "1" and not handle.HandlePath %} - {{ reverse_proxy_configuration(handle) }} - {% endif %} - {% endfor %} - {% endif %} - - {% if subdomain.accesslist %} - {% if accesslist.HttpResponseCode or accesslist.HttpResponseMessage %} - respond {{ '"' + accesslist.HttpResponseMessage|default('') + '"' if accesslist.HttpResponseMessage else '' }} {{ accesslist.HttpResponseCode|default(403) }} - {% elif Pischem.caddy.general.abort|default("0") == "1" %} - abort - {% endif %} - {% else %} - {% if Pischem.caddy.general.abort|default("0") == "1" %} - abort - {% endif %} - {% endif %} - } {% endif %} - {% endfor %} - - {% if reverse.accesslist %} - {% set accesslist = helpers.toList('Pischem.caddy.reverseproxy.accesslist') | selectattr('@uuid', 'equalto', reverse.accesslist) | first %} - {{ access_list_configuration(accesslist, accesslist.accesslistInvert|default("0") == "1") }} - handle @{{ accesslist['@uuid'] }} { - - {% set basicauth_uuids = reverse.basicauth %} - {{ basicauth_configuration(basicauth_uuids) }} - - {% set wildcard_handles = helpers.toList('Pischem.caddy.reverseproxy.handle') | selectattr('reverse', 'equalto', reverse['@uuid']) | selectattr('subdomain', 'undefined') | list %} - {% for handle in wildcard_handles %} - {% if handle.enabled|default("0") == "1" and handle.HandlePath %} - {{ reverse_proxy_configuration(handle) }} - {% endif %} - {% endfor %} - {% for handle in wildcard_handles %} - {% if handle.enabled|default("0") == "1" and not handle.HandlePath %} - {{ reverse_proxy_configuration(handle) }} - {% endif %} - {% endfor %} - } - {% else %} - {% set wildcard_handles = helpers.toList('Pischem.caddy.reverseproxy.handle') | selectattr('reverse', 'equalto', reverse['@uuid']) | selectattr('subdomain', 'undefined') | list %} - {% for handle in wildcard_handles %} - {% if handle.enabled|default("0") == "1" and handle.HandlePath %} - {{ reverse_proxy_configuration(handle) }} - {% endif %} - {% endfor %} - {% for handle in wildcard_handles %} - {% if handle.enabled|default("0") == "1" and not handle.HandlePath %} - {{ reverse_proxy_configuration(handle) }} - {% endif %} - {% endfor %} - {% endif %} - - {% set accesslist = helpers.toList('Pischem.caddy.reverseproxy.accesslist') | selectattr('@uuid', 'equalto', reverse.accesslist) | first %} - {% if accesslist %} - {% if accesslist.HttpResponseCode or accesslist.HttpResponseMessage %} - respond {{ '"' + accesslist.HttpResponseMessage|default('') + '"' if accesslist.HttpResponseMessage else '' }} {{ accesslist.HttpResponseCode|default(403) }} - {% elif Pischem.caddy.general.abort|default("0") == "1" %} - abort - {% endif %} - {% else %} - {% if Pischem.caddy.general.abort|default("0") == "1" %} - abort - {% endif %} - {% endif %} -} -{% endif %} {% endfor %} import /usr/local/etc/caddy/caddy.d/*.conf diff --git a/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/rc.conf.d/caddy b/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/rc.conf.d/caddy index 503f7da6f..d8ab2eda2 100644 --- a/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/rc.conf.d/caddy +++ b/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/rc.conf.d/caddy @@ -1,13 +1,8 @@ # DO NOT EDIT THIS FILE -- OPNsense auto-generated file -{% if helpers.exists('Pischem.caddy.general.enabled') %} - {%- set general_enabled = helpers.toList('Pischem.caddy.general.enabled') | first %} - {%- if general_enabled == '1' %} +{% set generalSettings = helpers.getNodeByTag('Pischem.caddy.general') %} +{% if generalSettings.enabled|default("0") == "1" %} caddy_enable="YES" -# Path to the Caddy setup script caddy_setup="/usr/local/opnsense/scripts/OPNsense/Caddy/setup.sh" - {%- else %} -caddy_enable="NO" - {%- endif %} -{%- else %} +{% else %} caddy_enable="NO" {% endif %}