diff --git a/security/acme-client/Makefile b/security/acme-client/Makefile index 3b0807121..f61c388d5 100644 --- a/security/acme-client/Makefile +++ b/security/acme-client/Makefile @@ -1,5 +1,5 @@ PLUGIN_NAME= acme-client -PLUGIN_VERSION= 1.25 +PLUGIN_VERSION= 1.26 PLUGIN_COMMENT= Let's Encrypt client PLUGIN_MAINTAINER= opnsense@moov.de PLUGIN_DEPENDS= acme.sh diff --git a/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/Api/SettingsController.php b/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/Api/SettingsController.php index f78611844..307c98229 100644 --- a/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/Api/SettingsController.php +++ b/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/Api/SettingsController.php @@ -390,4 +390,22 @@ class SettingsController extends ApiMutableModelControllerBase return $result; } + + /** + * Check wether the BIND plugin is installed. + * @return array status action + */ + public function getBindPluginStatusAction() + { + $result = array("result" => "0"); + + $mdlAcme = $this->getModel(); + + // Check if the required plugin is installed + if ((string)$mdlAcme->isPluginInstalled('bind') == "1") { + $result['result'] = "1"; + } + + return $result; + } } diff --git a/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/forms/dialogCertificate.xml b/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/forms/dialogCertificate.xml index 4e6292142..8ec38a0c7 100644 --- a/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/forms/dialogCertificate.xml +++ b/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/forms/dialogCertificate.xml @@ -1,4 +1,8 @@
+ + + header + certificate.enabled @@ -26,6 +30,10 @@
NOTE:You need to forcefully re-issue the certificate if you change "Alt Names" after the certificate was signed by the Let's Encrypt Authority! Use the "issue" button in the Commands column in this case.
]]>
Enter FQDN here. Finish with TAB.
+ + + header + certificate.account @@ -38,6 +46,22 @@ dropdown + + certificate.autoRenewal + + checkbox + Enable automatic renewal for this certificate to prevent expiration. + + + certificate.renewInterval + + text + + + + + header + certificate.keyLength @@ -50,6 +74,10 @@ checkbox Generate and add OCSP Must Staple extension to the certificate. + + + header + certificate.restartActions @@ -59,15 +87,31 @@ Choose the automations that should be run after certificate creation and renewal. Basically every application requires a quick restart to reload the updated certificate. If you don't configure an automation, the in-memory certificate may expire and cause security warnings and other issues. - certificate.autoRenewal - - checkbox - Enable automatic renewal for this certificate to prevent expiration. + certificate.aliasmode + + dropdown + - certificate.renewInterval - + + header + + + + certificate.domainalias + text - + acme.sh documentation for further information.]]> + + + + header + + + + certificate.challengealias + + text + acme.sh documentation for further information.]]>
diff --git a/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/forms/dialogValidation.xml b/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/forms/dialogValidation.xml index 727abe3a9..27a097063 100644 --- a/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/forms/dialogValidation.xml +++ b/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/forms/dialogValidation.xml @@ -717,10 +717,6 @@ header - - - info - validation.dns_opnsense_host @@ -730,7 +726,7 @@ validation.dns_opnsense_port text - + validation.dns_opnsense_key @@ -747,6 +743,15 @@ checkbox Uncheck this box if you have a valid certificate for your OPNsense interface. + + + header + + + + + info + header diff --git a/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/AcmeClient.xml b/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/AcmeClient.xml index f03201ef4..1afa9d4f8 100644 --- a/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/AcmeClient.xml +++ b/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/AcmeClient.xml @@ -243,6 +243,22 @@ 60 60 + + Y + none + + Not using DNS alias mode + Automatic Mode (uses DNS lookups) + Domain alias mode + Challenge alias mode + + + + N + + + N + N @@ -381,7 +397,7 @@ netcup DNS API NS1.com API nsupdate (RFC 2136) - OPNsense Bind Plugin + OPNsense BIND Plugin OVH, kimsufi, soyoustart and runabove API PowerDNS.com API selectel.com / selectel.ru domain API diff --git a/security/acme-client/src/opnsense/mvc/app/views/OPNsense/AcmeClient/certificates.volt b/security/acme-client/src/opnsense/mvc/app/views/OPNsense/AcmeClient/certificates.volt index 0c7c34e1a..c2e206bd6 100644 --- a/security/acme-client/src/opnsense/mvc/app/views/OPNsense/AcmeClient/certificates.volt +++ b/security/acme-client/src/opnsense/mvc/app/views/OPNsense/AcmeClient/certificates.volt @@ -379,6 +379,16 @@ POSSIBILITY OF SUCH DAMAGE. }); + // Hide options that are irrelevant in this context. + $('#DialogCertificate').on('shown.bs.modal', function (e) { + $("#certificate\\.aliasmode").change(function(){ + $(".aliasmode").hide(); + $(".aliasmode_"+$(this).val()).show(); + }); + $("#certificate\\.aliasmode").change(); + }) + + /*********************************************************************** * Commands **********************************************************************/ diff --git a/security/acme-client/src/opnsense/mvc/app/views/OPNsense/AcmeClient/validations.volt b/security/acme-client/src/opnsense/mvc/app/views/OPNsense/AcmeClient/validations.volt index fe51b231e..cb94acec0 100644 --- a/security/acme-client/src/opnsense/mvc/app/views/OPNsense/AcmeClient/validations.volt +++ b/security/acme-client/src/opnsense/mvc/app/views/OPNsense/AcmeClient/validations.volt @@ -62,6 +62,12 @@ POSSIBILITY OF SUCH DAMAGE. $(".gcloud_plugin_warning").hide(); } }); + // Show a warning if the BIND plugin is missing. + ajaxCall(url="/api/acmeclient/settings/getBindPluginStatus", sendData={}, callback=function(data,status) { + if (data['result'] != 0) { + $(".bind_plugin_warning").hide(); + } + }); }); $("#validation\\.http_service").change(function(){ var service_id = 'table_http_' + $(this).val(); diff --git a/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient/certhelper.php b/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient/certhelper.php index dfba36492..0524053e8 100755 --- a/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient/certhelper.php +++ b/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient/certhelper.php @@ -829,6 +829,11 @@ function run_acme_validation($certObj, $valObj, $acctObj) $proc_env['NSUPDATE_SERVER'] = (string)$valObj->dns_nsupdate_server; break; case 'dns_opnsense': + # BIND plugin must be installed. + if ((string)$modelObj->isPluginInstalled('bind') != "1") { + log_error("AcmeClient: BIND plugin is NOT installed. Please install os-bind."); + return(1); + } $proc_env['OPNs_Host'] = (string)$valObj->dns_opnsense_host; $proc_env['OPNs_Port'] = (string)$valObj->dns_opnsense_port; $proc_env['OPNs_Key'] = (string)$valObj->dns_opnsense_key; @@ -887,10 +892,50 @@ function run_acme_validation($certObj, $valObj, $acctObj) // Prepare altNames $altnames = ""; + + // Main domain: Use DNS alias mode for domain validation? + // https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode + if ($val_method == 'dns01') { + switch ((string)$valObj->aliasmode) { + case 'automatic': + $name = "_acme-challenge." . ltrim((string)$certObj->name, '*.'); + if ($dst = dns_get_record($name, DNS_CNAME )) { + $altnames .= "--domain-alias " . $dst[0]['target'] . " "; + } + break; + case 'domain': + $altnames .= "--domain-alias " . (string)$certObj->domainalias . " "; + break; + case 'challenge': + $altnames .= "--challenge-alias " . (string)$certObj->challengealias . " "; + break; + } + } + if (!empty((string)$certObj->altNames)) { $_altnames = explode(",", (string)$certObj->altNames); foreach (explode(",", (string)$certObj->altNames) as $altname) { $altnames .= "--domain ${altname} "; + + // altNames: Use DNS alias mode for domain validation? + // https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode + if ($val_method == 'dns01') { + switch ((string)$valObj->aliasmode) { + case 'automatic': + $name = "_acme-challenge." . ltrim($altname, '*.'); + if ($dst = dns_get_record($name, DNS_CNAME )) { + $altnames .= "--domain-alias " . $dst[0]['target'] . " "; + } + break; + case 'domain': + $altnames .= "--domain-alias " . (string)$certObj->domainalias . " "; + break; + case 'challenge': + $altnames .= "--challenge-alias " . (string)$certObj->challengealias . " "; + break; + } + } + } } diff --git a/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient/dns_opnsense.sh b/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient/dns_opnsense.sh index 1c1f463d6..80b5f40e8 100755 --- a/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient/dns_opnsense.sh +++ b/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient/dns_opnsense.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -#OPNsense Bind API +#OPNsense Bind API #https://docs.opnsense.org/development/api.html # #OPNs_Host="opnsense.example.com" @@ -61,21 +61,19 @@ set_record() { # Update if _opns_rest "POST" "/record/setRecord/${_uuid}" "$_record_string"; then _return_str="$response" - else return 1 fi - + else #create if _opns_rest "POST" "/record/addRecord" "$_record_string"; then _return_str="$response" - else return 1 fi - fi + if echo "$_return_str" | _egrep_o "\"result\":\"saved\"" >/dev/null then _opns_rest "POST" "/service/reconfigure" "{}" @@ -85,7 +83,6 @@ set_record() { return 1 fi - return 0 } @@ -117,14 +114,12 @@ rm_record() { else _err "Error delteting record $fulldomain" return 1 - fi + fi else _info "Record not found, nothing to remove" - fi return 0 - } #################### Private functions below ################################## @@ -199,7 +194,6 @@ _build_record_string() { } _existingchallenge() { - if _opns_rest "GET" "/record/searchRecord"; then _record_response="$response" else @@ -218,8 +212,6 @@ _existingchallenge() { } _opns_check_auth() { - - OPNs_Host="${OPNs_Host:-$(_readaccountconf_mutable OPNs_Host)}" OPNs_Port="${OPNs_Port:-$(_readaccountconf_mutable OPNs_Port)}" OPNs_Key="${OPNs_Key:-$(_readaccountconf_mutable OPNs_Key)}" @@ -267,5 +259,4 @@ _opns_check_auth() { return 1 fi return 0 - -} \ No newline at end of file +} diff --git a/security/acme-client/src/opnsense/service/conf/actions.d/actions_acmeclient.conf b/security/acme-client/src/opnsense/service/conf/actions.d/actions_acmeclient.conf index 7c53c1cfd..1a335c89f 100644 --- a/security/acme-client/src/opnsense/service/conf/actions.d/actions_acmeclient.conf +++ b/security/acme-client/src/opnsense/service/conf/actions.d/actions_acmeclient.conf @@ -42,7 +42,7 @@ message:testing acme_http_challenge configuration ########################################## [sign-cert] -command:/usr/sbin/daemon -f /usr/local/opnsense/scripts/OPNsense/AcmeClient/certhelper.php -F -a sign -c +command:/usr/local/opnsense/scripts/OPNsense/AcmeClient/setup.sh; /usr/sbin/daemon -f /usr/local/opnsense/scripts/OPNsense/AcmeClient/certhelper.php -F -a sign -c parameters:%s type:script message:signing or renewing a certificate @@ -66,13 +66,13 @@ type:script message:removing a certificate private key [sign-all-certs] -command:/usr/sbin/daemon -f /usr/local/opnsense/scripts/OPNsense/AcmeClient/certhelper.php -a sign -A +command:/usr/local/opnsense/scripts/OPNsense/AcmeClient/setup.sh; /usr/sbin/daemon -f /usr/local/opnsense/scripts/OPNsense/AcmeClient/certhelper.php -a sign -A parameters: type:script message:signing or renewing a certificate [cron-auto-renew] -command:/usr/sbin/daemon -f /usr/local/opnsense/scripts/OPNsense/AcmeClient/certhelper.php -a sign -A -C +command:/usr/local/opnsense/scripts/OPNsense/AcmeClient/setup.sh; /usr/sbin/daemon -f /usr/local/opnsense/scripts/OPNsense/AcmeClient/certhelper.php -a sign -A -C parameters: type:script message:cronjob running to sign or renew certificates