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"