diff --git a/security/acme-client/Makefile b/security/acme-client/Makefile index 0820071a5..d3fbada38 100644 --- a/security/acme-client/Makefile +++ b/security/acme-client/Makefile @@ -1,5 +1,5 @@ PLUGIN_NAME= acme-client -PLUGIN_VERSION= 1.28 +PLUGIN_VERSION= 1.29 PLUGIN_COMMENT= Let's Encrypt client PLUGIN_MAINTAINER= opnsense@moov.de PLUGIN_DEPENDS= acme.sh py${PLUGIN_PYTHON}-dns-lexicon 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 1735eac4f..b0f82aada 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 @@ -184,27 +184,38 @@ header + + + header + + validation.dns_cf_email - + text + Use your CF account with full privileges. This is less secure, a API token should be used instead (see below). validation.dns_cf_key - + password + + + header + + validation.dns_cf_account_id text - Can be found in the URI after loggin into the Cloudflare dashboard. + Can be found in the URI after logging into the Cloudflare dashboard. validation.dns_cf_token password - The token needs "Read" access to Zone.Zone and "Edit" to Zone.DNS across "All zones from an account". + The token needs "Read" access to Zone.Zone and "Edit" access to Zone.DNS across all zones from an account. @@ -975,7 +986,7 @@ header - + validation.dns_acmedns_user @@ -997,4 +1008,15 @@ text Specify the custom ACME DNS Update URL, i.e. https://auth.acme-dns.io/update (optional) + + + header + + + + validation.dns_variomedia_key + + password + You need to obtain your API key from variomedia's customer support. + 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 293f0d7b7..5cd40331c 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 @@ -408,6 +408,7 @@ selectel.com / selectel.ru domain API Servercow API v1 UnoEuro API + Variomedia.de API Vscale API Yandex PDD API Zilore DNS API @@ -843,6 +844,9 @@ N + + N + 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 aee1e5611..ef55528c4 100755 --- a/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient/certhelper.php +++ b/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient/certhelper.php @@ -587,16 +587,34 @@ function run_acme_validation($certObj, $valObj, $acctObj) } } + // Check wether IPv6 support is enabled + $configObj = Config::getInstance()->object(); + if (isset($configObj->system->ipv6allow) && ($configObj->system->ipv6allow == "1")) { + $_ipv6_enabled = true; + } else { + $_ipv6_enabled = false; + } + // Generate rules for all IP addresses $anchor_rules = ""; if (!empty($iplist)) { $dedup_iplist = array_unique($iplist); // Add one rule for every IP foreach ($dedup_iplist as $ip) { - if ($ip == '.') { - continue; // skip broken entries + if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + // IPv4 + $_dst = '127.0.0.1'; + $_family = 'inet'; + log_error("AcmeClient: using IPv4 address: ${ip}"); + } elseif (($_ipv6_enabled == true) && (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))) { + // IPv6 + $_dst = 'fe80::1'; + $_family = 'inet6'; + log_error("AcmeClient: using IPv6 address: ${ip}"); + } else { + continue; // skip broken entries } - $anchor_rules .= "rdr pass inet proto tcp from any to ${ip} port 80 -> 127.0.0.1 port ${local_http_port}\n"; + $anchor_rules .= "rdr pass ${_family} proto tcp from any to ${ip} port 80 -> ${_dst} port ${local_http_port}\n"; } } else { log_error("AcmeClient: no IP addresses found to setup port forward"); @@ -629,6 +647,12 @@ function run_acme_validation($certObj, $valObj, $acctObj) // Setup DNS hook: // Set required env variables, write secrets to files, etc. switch ((string)$valObj->dns_service) { + case 'dns_acmedns': + $proc_env['ACMEDNS_USERNAME'] = (string)$valObj->dns_acmedns_user; + $proc_env['ACMEDNS_PASSWORD'] = (string)$valObj->dns_acmedns_password; + $proc_env['ACMEDNS_SUBDOMAIN'] = (string)$valObj->dns_acmedns_subdomain; + $proc_env['ACMEDNS_UPDATE_URL'] = (string)$valObj->dns_acmedns_updateurl; + break; case 'dns_ad': $proc_env['AD_API_KEY'] = (string)$valObj->dns_ad_key; break; @@ -652,9 +676,10 @@ function run_acme_validation($certObj, $valObj, $acctObj) $proc_env['AZUREDNS_CLIENTSECRET'] = (string)$valObj->dns_azuredns_clientsecret; break; case 'dns_cf': + // Global API key (insecure) $proc_env['CF_Key'] = (string)$valObj->dns_cf_key; $proc_env['CF_Email'] = (string)$valObj->dns_cf_email; - // FIXME Only one auth method should be present in ENV + // Restricted API token (recommended) $proc_env['CF_Token'] = (string)$valObj->dns_cf_token; $proc_env['CF_Account_ID'] = (string)$valObj->dns_cf_account_id; break; @@ -754,6 +779,10 @@ function run_acme_validation($certObj, $valObj, $acctObj) $proc_env['GD_Key'] = (string)$valObj->dns_gd_key; $proc_env['GD_Secret'] = (string)$valObj->dns_gd_secret; break; + case 'dns_gdnsdk': + $proc_env['GDNSDK_Username'] = (string)$valObj->dns_gdnsdk_user; + $proc_env['GDNSDK_Password'] = (string)$valObj->dns_gdnsdk_password; + break; case 'dns_hostingde': $proc_env['HOSTINGDE_ENDPOINT'] = (string)$valObj->dns_hostingde_server; $proc_env['HOSTINGDE_APIKEY'] = (string)$valObj->dns_hostingde_apiKey; @@ -891,6 +920,9 @@ function run_acme_validation($certObj, $valObj, $acctObj) $proc_env['UNO_Key'] = (string)$valObj->dns_uno_key; $proc_env['UNO_User'] = (string)$valObj->dns_uno_user; break; + case 'dns_variomedia': + $proc_env['VARIOMEDIA_API_TOKEN'] = (string)$valObj->dns_variomedia_key; + break; case 'dns_vscale': $proc_env['VSCALE_API_KEY'] = (string)$valObj->dns_vscale_key; break; @@ -903,16 +935,6 @@ function run_acme_validation($certObj, $valObj, $acctObj) case 'dns_zonomi': $proc_env['ZM_Key'] = (string)$valObj->dns_zm_key; break; - case 'dns_gdnsdk': - $proc_env['GDNSDK_Username'] = (string)$valObj->dns_gdnsdk_user; - $proc_env['GDNSDK_Password'] = (string)$valObj->dns_gdnsdk_password; - break; - case 'dns_acmedns': - $proc_env['ACMEDNS_USERNAME'] = (string)$valObj->dns_acmedns_user; - $proc_env['ACMEDNS_PASSWORD'] = (string)$valObj->dns_acmedns_password; - $proc_env['ACMEDNS_SUBDOMAIN'] = (string)$valObj->dns_acmedns_subdomain; - $proc_env['ACMEDNS_UPDATE_URL'] = (string)$valObj->dns_acmedns_updateurl; - break; default: log_error("AcmeClient: invalid DNS-01 service specified: " . (string)$valObj->dns_service); return(1); diff --git a/security/acme-client/src/opnsense/service/templates/OPNsense/AcmeClient/lighttpd-acme-challenge.conf b/security/acme-client/src/opnsense/service/templates/OPNsense/AcmeClient/lighttpd-acme-challenge.conf index c83c827b4..d88517cad 100644 --- a/security/acme-client/src/opnsense/service/templates/OPNsense/AcmeClient/lighttpd-acme-challenge.conf +++ b/security/acme-client/src/opnsense/service/templates/OPNsense/AcmeClient/lighttpd-acme-challenge.conf @@ -64,6 +64,11 @@ server.bind = "127.0.0.1" server.port = {{OPNsense.AcmeClient.settings.challengePort}} $SERVER["socket"] == "127.0.0.1:{{OPNsense.AcmeClient.settings.challengePort}}" { } +{% if helpers.exists('system.ipv6allow') and system.ipv6allow|default("0") == "1" %} +# IPv6 +$SERVER["socket"] == "[::1]:{{OPNsense.AcmeClient.settings.challengePort}}" { } +{% endif %} + # to help the rc.scripts server.pid-file = "/var/run/lighttpd-acme-challenge.pid"