diff --git a/security/acme-client/pkg-descr b/security/acme-client/pkg-descr
index bfec3433c..2a5039e66 100644
--- a/security/acme-client/pkg-descr
+++ b/security/acme-client/pkg-descr
@@ -8,8 +8,84 @@ WWW: https://github.com/acmesh-official/acme.sh
Plugin Changelog
================
+4.0
+
+NOTE: This is a new major release with backwards-incompatible changes.
+Downgrade to older releases is not supported. Be sure to create a
+full backup and include /var/etc/acme-client.
+
+NOTE: Lexicon is deprecated and most configurations are converted
+to native acme.sh DNS APIs. However, in some case manual reconfiguration
+may be necessary.
+
+Added:
+* add nic.ru DNS API (#3684)
+* add Aurora DNS API
+* add ConoHa DNS API
+* add Constellix DNS API
+* add Exoscale DNS API
+* add internetbs.net DNS API
+* add PointHQ DNS API
+* add Rackspace DNS API
+* add rage4 DNS API
+
+Changed:
+* use a dedicated acme.sh runtime directory for every cert (#3127)
+* migrate lexicon provider aliyun to acme.sh DNS API (#2920)
+* migrate lexicon provider aurora to acme.sh DNS API (#2920)
+* migrate lexicon provider azure to acme.sh DNS API (#2920)
+* migrate lexicon provider cloudflare to acme.sh DNS API (#2920)
+* migrate lexicon provider cloudns to acme.sh DNS API (#2920)
+* migrate lexicon provider cloudxns to acme.sh DNS API (#2920)
+* migrate lexicon provider conoha to acme.sh DNS API (#2920)
+* migrate lexicon provider constellix to acme.sh DNS API (#2920)
+* migrate lexicon provider digitalocean to acme.sh DNS API (#2920)
+* migrate lexicon provider directadmin to acme.sh DNS API (#2920)
+* migrate lexicon provider dnsimple to acme.sh DNS API (#2920)
+* migrate lexicon provider dnsmadeeasy to acme.sh DNS API (#2920)
+* migrate lexicon provider dnspod to acme.sh DNS API (#2920)
+* migrate lexicon provider dreamhost to acme.sh DNS API (#2920)
+* migrate lexicon provider easydns to acme.sh DNS API (#2920)
+* migrate lexicon provider exoscale to acme.sh DNS API (#2920)
+* migrate lexicon provider gandi to acme.sh DNS API (#2920)
+* migrate lexicon provider godaddy to acme.sh DNS API (#2920)
+* migrate lexicon provider googleclouddns to acme.sh DNS API (#2920)
+* migrate lexicon provider gratisdns to acme.sh DNS API (#2920)
+* migrate lexicon provider henet to acme.sh DNS API (#2920)
+* migrate lexicon provider hetzner to acme.sh DNS API (#2920)
+* migrate lexicon provider infoblox to acme.sh DNS API (#2920)
+* migrate lexicon provider internetbs to acme.sh DNS API (#2920)
+* migrate lexicon provider inwx to acme.sh DNS API (#2920)
+* migrate lexicon provider linode to acme.sh DNS API (#2920)
+* migrate lexicon provider linode4 to acme.sh DNS API (#2920)
+* migrate lexicon provider luadns to acme.sh DNS API (#2920)
+* migrate lexicon provider namecheap to acme.sh DNS API (#2920)
+* migrate lexicon provider namesilo to acme.sh DNS API (#2920)
+* migrate lexicon provider netcup to acme.sh DNS API (#2920)
+* migrate lexicon provider nfsn to acme.sh DNS API (#2920)
+* migrate lexicon provider nsone to acme.sh DNS API (#2920)
+* migrate lexicon provider online to acme.sh DNS API (#2920)
+* migrate lexicon provider ovh to acme.sh DNS API (#2920)
+* migrate lexicon provider plesk to acme.sh DNS API (#2920)
+* migrate lexicon provider pointhq to acme.sh DNS API (#2920)
+* migrate lexicon provider powerdns to acme.sh DNS API (#2920)
+* migrate lexicon provider rackspace to acme.sh DNS API (#2920)
+* migrate lexicon provider rage4 to acme.sh DNS API (#2920)
+* migrate lexicon provider route53 to acme.sh DNS API (#2920)
+* migrate lexicon provider transip to acme.sh DNS API (#2920)
+* migrate lexicon provider vultr to acme.sh DNS API (#2920)
+* migrate lexicon provider yandex to acme.sh DNS API (#2920)
+* migrate lexicon provider zeit to acme.sh DNS API (#2920)
+* migrate lexicon provider zilore to acme.sh DNS API (#2920)
+* migrate lexicon provider zonomi to acme.sh DNS API (#2920)
+
Fixed:
* fix sporadic command failure with gcloud DNS API (#3745)
+* fix errors when the same Common Name is used multiple times (#3127)
+* fix crash on invalid automations (#3752)
+
+Deprecated:
+* deprecate support for lexicon DNS APIs (no removal date yet)
3.20
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 c714ce8ed..98fdc7e56 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
@@ -788,12 +788,7 @@
Specify the location of the generated TSIG Key inside the TSIG file using grep and cut, example: grep \# /etc/knot/acme.key | cut -d' ' -f2
-
- header
-
-
-
-
+
header
@@ -1702,4 +1697,134 @@
password
-
\ No newline at end of file
+
+
+ header
+
+
+
+ validation.dns_aurora_key
+
+ text
+
+
+ validation.dns_aurora_secret
+
+ password
+
+
+
+ header
+
+
+
+ validation.dns_conoha_user
+
+ text
+
+
+ validation.dns_conoha_password
+
+ password
+
+
+ validation.dns_conoha_tenantid
+
+ text
+
+
+ validation.dns_conoha_idapi
+
+ text
+
+
+
+ header
+
+
+
+ validation.dns_constellix_key
+
+ text
+
+
+ validation.dns_constellix_secret
+
+ password
+
+
+
+ header
+
+
+
+ validation.dns_exoscale_key
+
+ text
+
+
+ validation.dns_exoscale_secret
+
+ password
+
+
+
+ header
+
+
+
+ validation.dns_internetbs_key
+
+ text
+
+
+ validation.dns_internetbs_password
+
+ password
+
+
+
+ header
+
+
+
+ validation.dns_pointhq_key
+
+ password
+
+
+ validation.dns_pointhq_email
+
+ text
+
+
+
+ header
+
+
+
+ validation.dns_rackspace_user
+
+ text
+
+
+ validation.dns_rackspace_key
+
+ password
+
+
+
+ header
+
+
+
+ validation.dns_rage4_user
+
+ text
+
+
+ validation.dns_rage4_token
+
+ password
+
+
diff --git a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeAccount.php b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeAccount.php
index 1186dbccb..7ff90ceda 100644
--- a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeAccount.php
+++ b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeAccount.php
@@ -224,6 +224,9 @@ class LeAccount extends LeCommon
return false;
}
+ // Fix account config
+ $this->fixConfig();
+
// Update account status.
LeUtils::log_error('account registration successful for ' . $this->config->name);
$this->setStatus(200);
@@ -233,4 +236,34 @@ class LeAccount extends LeCommon
return true;
}
+
+ /**
+ * Remove CERT_HOME property from account config,
+ * otherwise --cert-home will be ignored by acme.sh.
+ */
+ public function fixConfig()
+ {
+ $account_conf_dir = self::ACME_BASE_ACCOUNT_DIR . '/' . (string)$this->config->id . '_' . $this->ca_compat;
+ $account_conf_file = $account_conf_dir . '/account.conf';
+
+ if (is_dir($account_conf_dir)) {
+ if (is_file($account_conf_file)) {
+ // Parse config file and remove property
+ $account_conf = parse_ini_file($account_conf_file);
+ if (isset($account_conf['CERT_HOME'])) {
+ unset($account_conf['CERT_HOME']);
+ }
+
+ // Convert array back to ini file format
+ $new_account_conf = array();
+ foreach ($account_conf as $key => $value) {
+ $new_account_conf[] = "${key}='${value}'";
+ }
+
+ // Write changes back to file
+ file_put_contents($account_conf_file, implode("\n", $new_account_conf) . "\n");
+ chmod($account_conf_file, 0600);
+ }
+ }
+ }
}
diff --git a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeAutomation/Base.php b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeAutomation/Base.php
index fc3119580..f85a23d14 100644
--- a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeAutomation/Base.php
+++ b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeAutomation/Base.php
@@ -71,6 +71,7 @@ abstract class Base extends \OPNsense\AcmeClient\LeCommon
// Store acme filenames
$this->acme_args[] = LeUtils::execSafe('--home %s', self::ACME_HOME_DIR);
+ $this->acme_args[] = LeUtils::execSafe('--cert-home %s', sprintf(self::ACME_CERT_HOME_DIR, $this->cert_id));
$this->acme_args[] = LeUtils::execSafe('--certpath %s', sprintf(self::ACME_CERT_FILE, $this->cert_id));
$this->acme_args[] = LeUtils::execSafe('--keypath %s', sprintf(self::ACME_KEY_FILE, $this->cert_id));
$this->acme_args[] = LeUtils::execSafe('--capath %s', sprintf(self::ACME_CHAIN_FILE, $this->cert_id));
diff --git a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeCertificate.php b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeCertificate.php
index 177651853..0b319d34b 100644
--- a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeCertificate.php
+++ b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeCertificate.php
@@ -95,6 +95,7 @@ class LeCertificate extends LeCommon
// Store acme filenames
$this->acme_args[] = LeUtils::execSafe('--home %s', self::ACME_HOME_DIR);
+ $this->acme_args[] = LeUtils::execSafe('--cert-home %s', sprintf(self::ACME_CERT_HOME_DIR, $this->config->id));
$this->acme_args[] = LeUtils::execSafe('--certpath %s', $this->cert_file);
$this->acme_args[] = LeUtils::execSafe('--keypath %s', $this->cert_key_file);
$this->acme_args[] = LeUtils::execSafe('--capath %s', $this->cert_chain_file);
diff --git a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeCommon.php b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeCommon.php
index bf278b7aa..f7237bfcc 100644
--- a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeCommon.php
+++ b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeCommon.php
@@ -1,7 +1,7 @@
acme_args[] = LeUtils::execSafe('--home %s', self::ACME_HOME_DIR);
+ $this->acme_args[] = LeUtils::execSafe('--cert-home %s', sprintf(self::ACME_CERT_HOME_DIR, $this->cert_id));
$this->acme_args[] = LeUtils::execSafe('--certpath %s', sprintf(self::ACME_CERT_FILE, $this->cert_id));
$this->acme_args[] = LeUtils::execSafe('--keypath %s', sprintf(self::ACME_KEY_FILE, $this->cert_id));
$this->acme_args[] = LeUtils::execSafe('--capath %s', sprintf(self::ACME_CHAIN_FILE, $this->cert_id));
diff --git a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsAurora.php b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsAurora.php
new file mode 100644
index 000000000..64dd25622
--- /dev/null
+++ b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsAurora.php
@@ -0,0 +1,44 @@
+acme_env['AURORA_Key'] = (string)$this->config->dns_aurora_key;
+ $this->acme_env['AURORA_Secret'] = (string)$this->config->dns_aurora_secret;
+ }
+}
diff --git a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsConoha.php b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsConoha.php
new file mode 100644
index 000000000..f1c46fc51
--- /dev/null
+++ b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsConoha.php
@@ -0,0 +1,46 @@
+acme_env['CONOHA_Username'] = (string)$this->config->dns_conoha_user;
+ $this->acme_env['CONOHA_Password'] = (string)$this->config->dns_conoha_password;
+ $this->acme_env['CONOHA_TenantId'] = (string)$this->config->dns_conoha_tenantid;
+ $this->acme_env['CONOHA_IdentityServiceApi'] = (string)$this->config->dns_conoha_idapi;
+ }
+}
diff --git a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsConstellix.php b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsConstellix.php
new file mode 100644
index 000000000..6d6e53699
--- /dev/null
+++ b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsConstellix.php
@@ -0,0 +1,44 @@
+acme_env['CONSTELLIX_Key'] = (string)$this->config->dns_constellix_key;
+ $this->acme_env['CONSTELLIX_Secret'] = (string)$this->config->dns_constellix_secret;
+ }
+}
diff --git a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsExoscale.php b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsExoscale.php
new file mode 100644
index 000000000..f3204e216
--- /dev/null
+++ b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsExoscale.php
@@ -0,0 +1,44 @@
+acme_env['EXOSCALE_API_KEY'] = (string)$this->config->dns_exoscale_key;
+ $this->acme_env['EXOSCALE_SECRET_KEY'] = (string)$this->config->dns_exoscale_secret;
+ }
+}
diff --git a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsInternetbs.php b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsInternetbs.php
new file mode 100644
index 000000000..3d9f40e80
--- /dev/null
+++ b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsInternetbs.php
@@ -0,0 +1,44 @@
+acme_env['INTERNETBS_API_KEY'] = (string)$this->config->dns_internetbs_key;
+ $this->acme_env['INTERNETBS_API_PASSWORD'] = (string)$this->config->dns_internetbs_password;
+ }
+}
diff --git a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsPointhq.php b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsPointhq.php
new file mode 100644
index 000000000..6abc9deb9
--- /dev/null
+++ b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsPointhq.php
@@ -0,0 +1,44 @@
+acme_env['PointHQ_Key'] = (string)$this->config->dns_pointhq_key;
+ $this->acme_env['exportPointHQ_Email'] = (string)$this->config->dns_pointhq_email;
+ }
+}
diff --git a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsRackspace.php b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsRackspace.php
new file mode 100644
index 000000000..1b4c1e6a1
--- /dev/null
+++ b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsRackspace.php
@@ -0,0 +1,44 @@
+acme_env['RACKSPACE_Username'] = (string)$this->config->dns_rackspace_user;
+ $this->acme_env['RACKSPACE_Apikey'] = (string)$this->config->dns_rackspace_key;
+ }
+}
diff --git a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsRage4.php b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsRage4.php
new file mode 100644
index 000000000..86e598a72
--- /dev/null
+++ b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeValidation/DnsRage4.php
@@ -0,0 +1,44 @@
+acme_env['RAGE4_TOKEN'] = (string)$this->config->dns_rage4_user;
+ $this->acme_env['RAGE4_USERNAME'] = (string)$this->config->dns_rage4_token;
+ }
+}
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 a174304f8..a583d068b 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
@@ -1,6 +1,6 @@
//OPNsense/AcmeClient
- 3.5.0
+ 4.1.0
A secure ACME Client plugin
@@ -426,6 +426,7 @@
aliyun.com
All-Inkl.com
ArvanCloud
+ Aurora (PCextreme/Versio)
AutoDNS (InterNetX)
AWS Route 53
Azure DNS
@@ -434,6 +435,8 @@
CloudFlare.com
CloudXNS.com
Core-Networks
+ ConoHa
+ Constellix
cPanel
cyon.ch
DDNSS
@@ -455,6 +458,7 @@
dynv6
EasyDNS
EUserv
+ Exoscale
FreeDNS
Gandi LiveDNS
GoDaddy.com
@@ -467,6 +471,7 @@
Hurricane Electric
Infoblox
Infomaniak
+ internetbs.net
INWX XMLRPC
IONOS domain
IPv64.net
@@ -476,7 +481,7 @@
KingHost
Knot (knsupdate)
LeaseWeb
- lexicon
+ lexicon (DEPRECATED)
Linode (v3 / Deprecated)
Linode (v4)
Loopia
@@ -497,7 +502,10 @@
OVH, kimsufi, soyoustart and runabove
PowerDNS.com
Plesk
+ PointHQ
Porkbun
+ Rackspace
+ rage4
RegRu
SchlundTech
selectel.com / selectel.ru
@@ -779,67 +787,67 @@
N
cloudflare
- Aliyun.com
- AuroraDNS
+ Aliyun.com (UNSUPPORTED)
+ AuroraDNS (UNSUPPORTED)
Auto API
- Azure
- CloudFlare
- ClouDNS
- CloudXNS
- ConoHa
- Constellix
- DigitalOcean
- Dinahosting
- DirectAdmin
- DNSimple
- DnsMadeEasy
+ Azure (UNSUPPORTED)
+ CloudFlare (UNSUPPORTED)
+ ClouDNS (UNSUPPORTED)
+ CloudXNS (UNSUPPORTED)
+ ConoHa (UNSUPPORTED)
+ Constellix (UNSUPPORTED)
+ DigitalOcean (UNSUPPORTED)
+ Dinahosting (UNSUPPORTED)
+ DirectAdmin (UNSUPPORTED)
+ DNSimple (UNSUPPORTED)
+ DnsMadeEasy (UNSUPPORTED)
DNSPark
- DNSPod
- Dreamhost
- EasyDNS
+ DNSPod (UNSUPPORTED)
+ Dreamhost (UNSUPPORTED)
+ EasyDNS (UNSUPPORTED)
Easyname
- ExoScale
- Gandi
+ ExoScale (UNSUPPORTED)
+ Gandi (UNSUPPORTED)
Gehirn
Glesys
- GoDaddy
- Google Cloud
- GratisDNS
- Hurricane Electric
- Hetzner
+ GoDaddy (UNSUPPORTED)
+ Google Cloud (UNSUPPORTED)
+ GratisDNS (UNSUPPORTED)
+ Hurricane Electric (UNSUPPORTED)
+ Hetzner (UNSUPPORTED)
Hover
- Infoblox
- Internet.bs
- INWX
- Linode (v3 / Deprecated)
- Linode (v4)
+ Infoblox (UNSUPPORTED)
+ Internet.bs (UNSUPPORTED)
+ INWX (UNSUPPORTED)
+ Linode v3 (UNSUPPORTED)
+ Linode v4 (UNSUPPORTED)
Localzone
- LuaDNS
+ LuaDNS (UNSUPPORTED)
Memset
- Namecheap
- Namesilo
- Netcup
- NFSN
- NS1
+ Namecheap (UNSUPPORTED)
+ Namesilo (UNSUPPORTED)
+ Netcup (UNSUPPORTED)
+ NFSN (UNSUPPORTED)
+ NS1 (UNSUPPORTED)
OnApp
- Online
- OVH
- Plesk
- PointHQ
- PowerDNS
- Rackspace
- Rage4
- Route 53
+ Online (UNSUPPORTED)
+ OVH (UNSUPPORTED)
+ Plesk (UNSUPPORTED)
+ PointHQ (UNSUPPORTED)
+ PowerDNS (UNSUPPORTED)
+ Rackspace (UNSUPPORTED)
+ Rage4 (UNSUPPORTED)
+ Route 53 (UNSUPPORTED)
SafeDNS
SakuraCloud
Softlayer
Subreg
- Transip
- Vultr
- Yandex
- Zeit
- Zilore
- Zonomi
+ Transip (UNSUPPORTED)
+ Vultr (UNSUPPORTED)
+ Yandex (UNSUPPORTED)
+ Zeit (UNSUPPORTED)
+ Zilore (UNSUPPORTED)
+ Zonomi (UNSUPPORTED)
@@ -1195,6 +1203,61 @@
N
+
+ N
+
+
+ N
+
+
+ N
+
+
+ N
+
+
+ N
+
+
+ N
+ https://identity.xxxx.conoha.io/v2.0
+
+
+ N
+
+
+ N
+
+
+ N
+
+
+ N
+
+
+ N
+
+
+ N
+
+
+ N
+
+
+ N
+
+
+ N
+
+
+ N
+
+
+ N
+
+
+ N
+
diff --git a/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/Migrations/M1_6_0.php b/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/Migrations/M1_6_0.php
index 22bb91001..f6982d236 100644
--- a/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/Migrations/M1_6_0.php
+++ b/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/Migrations/M1_6_0.php
@@ -75,7 +75,7 @@ class M1_6_0 extends BaseModelMigration
}
// Write changes back to file
- file_put_contents($account_file, implode("\r\n", $new_account_conf) . "\n");
+ file_put_contents($account_file, implode("\n", $new_account_conf) . "\n");
chmod($account_file, 0600);
// Finally, rename account directory
diff --git a/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/Migrations/M4_0_0.php b/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/Migrations/M4_0_0.php
new file mode 100644
index 000000000..2a776cbe9
--- /dev/null
+++ b/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/Migrations/M4_0_0.php
@@ -0,0 +1,107 @@
+ $value) {
+ $new_account_conf[] = "${key}='${value}'";
+ }
+
+ // Write changes back to file
+ file_put_contents($account_file, implode("\n", $new_account_conf) . "\n");
+ chmod($account_file, 0600);
+ }
+ }
+ }
+
+ // Create new acme home directory
+ if (!is_dir($new_acme_home)) {
+ mkdir($new_acme_home, 0750);
+ }
+
+ // Migrate all certificates to new directory
+ // OLD: /var/etc/acme-client/home/opnsense.example.com
+ // NEW: /var/etc/acme-client/cert-home/659971be677b69.19708532/opnsense.example.com
+ foreach ($model->getNodeByReference('certificates.certificate')->iterateItems() as $cert) {
+ $cert_id = (string)$cert->id;
+ $cert_name = (string)$cert->name;
+
+ $old_cert_home = $old_acme_home . $cert_name;
+ $new_cert_home = $new_acme_home . $cert_id . '/' . $cert_name;
+ $old_cert_home_ecc = $old_acme_home . $cert_name . '_ecc';
+ $new_cert_home_ecc = $new_acme_home . $cert_id . '/' . $cert_name . '_ecc';
+ $_parent_dir = $new_acme_home . $cert_id;
+
+ // Check if cert home directory exists
+ // Certs that haven't been issued yet don't need to be migrated.
+ if (is_dir($old_cert_home)) {
+ // Create parent directory
+ if (!is_dir($_parent_dir)) {
+ mkdir($_parent_dir, 0750);
+ }
+ // Rename cert home directory
+ rename($old_cert_home, $new_cert_home);
+ }
+
+ // Migrate ECC certs
+ if (is_dir($old_cert_home_ecc)) {
+ // Create parent directory
+ if (!is_dir($_parent_dir)) {
+ mkdir($_parent_dir, 0750);
+ }
+ // Rename cert home directory
+ rename($old_cert_home_ecc, $new_cert_home_ecc);
+ }
+ }
+ }
+}
diff --git a/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/Migrations/M4_1_0.php b/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/Migrations/M4_1_0.php
new file mode 100644
index 000000000..a28ae71f4
--- /dev/null
+++ b/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/Migrations/M4_1_0.php
@@ -0,0 +1,266 @@
+getNodeByReference('validations.validation')->iterateItems() as $validation) {
+ $dns_service = (string)$validation->dns_service;
+ $dns_lexicon_provider = (string)$validation->dns_lexicon_provider;
+
+ if (!empty($dns_lexicon_provider) && ($dns_service === 'dns_lexicon')) {
+ // Migrate old lexicon values to DNS API values.
+ switch ($dns_lexicon_provider) {
+ case 'aliyun':
+ $validation->dns_service = 'dns_ali';
+ $validation->dns_ali_key = (string)$validation->dns_lexicon_user;
+ $validation->dns_ali_secret = (string)$validation->dns_lexicon_token;
+ break;
+ case 'aurora':
+ $validation->dns_service = 'dns_aurora';
+ $validation->dns_aurora_key = (string)$validation->dns_lexicon_user;
+ $validation->dns_aurora_secret = (string)$validation->dns_lexicon_token;
+ break;
+ case 'cloudflare':
+ $validation->dns_service = 'dns_cf';
+ $validation->dns_cf_key = (string)$validation->dns_lexicon_user;
+ $validation->dns_cf_token = (string)$validation->dns_lexicon_token;
+ break;
+ case 'cloudns':
+ $validation->dns_service = 'dns_cloudns';
+ $validation->dns_cloudns_auth_id = (string)$validation->dns_lexicon_user;
+ $validation->dns_cloudns_auth_password = (string)$validation->dns_lexicon_token;
+ break;
+ case 'cloudxns':
+ $validation->dns_service = 'dns_cx';
+ $validation->dns_cx_key = (string)$validation->dns_lexicon_user;
+ $validation->dns_cx_secret = (string)$validation->dns_lexicon_token;
+ break;
+ case 'conoha':
+ $validation->dns_service = 'dns_conoha';
+ $validation->dns_conoha_user = (string)$validation->dns_lexicon_user;
+ $validation->dns_conoha_password = (string)$validation->dns_lexicon_token;
+ break;
+ case 'constellix':
+ $validation->dns_service = 'dns_constellix';
+ $validation->dns_constellix_key = (string)$validation->dns_lexicon_user;
+ $validation->dns_constellix_secret = (string)$validation->dns_lexicon_token;
+ break;
+ case 'digitalocean':
+ $validation->dns_service = 'dns_dgon';
+ $validation->dns_dgon_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'directadmin':
+ $validation->dns_service = 'dns_da';
+ $validation->dns_da_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'dnsimple':
+ $validation->dns_service = 'dns_dnsimple';
+ $validation->dns_dnsimple_token = (string)$validation->dns_lexicon_token;
+ break;
+ case 'dnsmadeeasy':
+ $validation->dns_service = 'dns_me';
+ $validation->dns_me_key = (string)$validation->dns_lexicon_user;
+ $validation->dns_me_secret = (string)$validation->dns_lexicon_token;
+ break;
+ case 'dnspod':
+ $validation->dns_service = 'dns_dp';
+ $validation->dns_dp_id = (string)$validation->dns_lexicon_user;
+ $validation->dns_dp_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'dreamhost':
+ $validation->dns_service = 'dns_dreamhost';
+ // FIXME: parameter prefix should match $dns_service
+ $validation->dns_dh_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'easydns':
+ $validation->dns_service = 'dns_easydns';
+ $validation->dns_easydns_apikey = (string)$validation->dns_lexicon_user;
+ $validation->dns_easydns_apitoken = (string)$validation->dns_lexicon_token;
+ break;
+ case 'exoscale':
+ $validation->dns_service = 'dns_exoscale';
+ $validation->dns_exoscale_key = (string)$validation->dns_lexicon_user;
+ $validation->dns_exoscale_secret = (string)$validation->dns_lexicon_token;
+ break;
+ case 'gandi':
+ $validation->dns_service = 'dns_gandi_livedns';
+ $validation->dns_gandi_livedns_key = (string)$validation->dns_lexicon_user;
+ $validation->dns_gandi_livedns_token = (string)$validation->dns_lexicon_token;
+ break;
+ case 'godaddy':
+ $validation->dns_service = 'dns_gd';
+ $validation->dns_gd_key = (string)$validation->dns_lexicon_user;
+ $validation->dns_gd_secret = (string)$validation->dns_lexicon_token;
+ break;
+ case 'googleclouddns':
+ $validation->dns_service = 'dns_gcloud';
+ $validation->dns_gcloud_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'gratisdns':
+ $validation->dns_service = 'dns_gdnsdk';
+ $validation->dns_gdnsdk_user = (string)$validation->dns_lexicon_user;
+ $validation->dns_gdnsdk_password = (string)$validation->dns_lexicon_token;
+ break;
+ case 'henet':
+ $validation->dns_service = 'dns_he';
+ $validation->dns_he_user = (string)$validation->dns_lexicon_user;
+ $validation->dns_he_password = (string)$validation->dns_lexicon_token;
+ break;
+ case 'hetzner':
+ $validation->dns_service = 'dns_hetzner';
+ $validation->dns_hetzner_token = (string)$validation->dns_lexicon_token;
+ break;
+ case 'infoblox':
+ $validation->dns_service = 'dns_infoblox';
+ $validation->dns_infoblox_credentials = (string)$validation->dns_lexicon_token;
+ break;
+ case 'internetbs':
+ $validation->dns_service = 'dns_internetbs';
+ $validation->dns_internetbs_key = (string)$validation->dns_lexicon_user;
+ $validation->dns_internetbs_password = (string)$validation->dns_lexicon_token;
+ break;
+ case 'inwx':
+ $validation->dns_service = 'dns_inwx';
+ $validation->dns_inwx_user = (string)$validation->dns_lexicon_user;
+ $validation->dns_inwx_password = (string)$validation->dns_lexicon_token;
+ break;
+ case 'linode':
+ $validation->dns_service = 'dns_linode';
+ $validation->dns_linode_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'linode4':
+ $validation->dns_service = 'dns_linode_v4';
+ $validation->dns_linode_v4_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'luadns':
+ $validation->dns_service = 'dns_lua';
+ $validation->dns_lua_email = (string)$validation->dns_lexicon_user;
+ $validation->dns_lua_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'namecheap':
+ $validation->dns_service = 'dns_namecheap';
+ $validation->dns_namecheap_user = (string)$validation->dns_lexicon_user;
+ $validation->dns_namecheap_api = (string)$validation->dns_lexicon_token;
+ break;
+ case 'namesilo':
+ $validation->dns_service = 'dns_namesilo';
+ $validation->dns_namesilo_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'netcup':
+ $validation->dns_service = 'dns_netcup';
+ $validation->dns_netcup_key = (string)$validation->dns_lexicon_user;
+ $validation->dns_netcup_pw = (string)$validation->dns_lexicon_token;
+ break;
+ case 'nfsn':
+ $validation->dns_service = 'dns_njalla';
+ $validation->dns_njalla_token = (string)$validation->dns_lexicon_token;
+ break;
+ case 'nsone':
+ $validation->dns_service = 'dns_nsone';
+ $validation->dns_nsone_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'online':
+ $validation->dns_service = 'dns_online';
+ $validation->dns_online_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'ovh':
+ $validation->dns_service = 'dns_ovh';
+ $validation->dns_ovh_app_key = (string)$validation->dns_lexicon_user;
+ $validation->dns_ovh_app_secret = (string)$validation->dns_lexicon_token;
+ break;
+ case 'plesk':
+ $validation->dns_service = 'dns_pleskxml';
+ $validation->dns_pleskxml_user = (string)$validation->dns_lexicon_user;
+ $validation->dns_pleskxml_pass = (string)$validation->dns_lexicon_token;
+ break;
+ case 'pointhq':
+ $validation->dns_service = 'dns_pointhq';
+ $validation->dns_pointhq_email = (string)$validation->dns_lexicon_user;
+ $validation->dns_pointhq_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'powerdns':
+ $validation->dns_service = 'dns_pdns';
+ $validation->dns_pdns_serverid = (string)$validation->dns_lexicon_user;
+ $validation->dns_pdns_token = (string)$validation->dns_lexicon_token;
+ break;
+ case 'rackspace':
+ $validation->dns_service = 'dns_rackspace';
+ $validation->dns_rackspace_user = (string)$validation->dns_lexicon_user;
+ $validation->dns_rackspace_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'rage4':
+ $validation->dns_service = 'dns_rage4';
+ $validation->dns_rage4_user = (string)$validation->dns_lexicon_user;
+ $validation->dns_rage4_token = (string)$validation->dns_lexicon_token;
+ break;
+ case 'route53':
+ $validation->dns_service = 'dns_aws';
+ $validation->dns_aws_id = (string)$validation->dns_lexicon_user;
+ $validation->dns_aws_secret = (string)$validation->dns_lexicon_token;
+ break;
+ case 'transip':
+ $validation->dns_service = 'dns_transip';
+ $validation->dns_transip_username = (string)$validation->dns_lexicon_user;
+ $validation->dns_transip_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'vultr':
+ $validation->dns_service = 'dns_vultr';
+ $validation->dns_vultr_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'yandex':
+ $validation->dns_service = 'dns_yandex';
+ $validation->dns_yandex_token = (string)$validation->dns_lexicon_token;
+ break;
+ case 'zeit':
+ // URL points to zilore, so we'll use this DNS API as a replacement.
+ $validation->dns_service = 'dns_zilore';
+ $validation->dns_zilore_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'zilore':
+ $validation->dns_service = 'dns_zilore';
+ $validation->dns_zilore_key = (string)$validation->dns_lexicon_token;
+ break;
+ case 'zonomi':
+ $validation->dns_service = 'dns_zonomi';
+ // FIXME: parameter prefix should match $dns_service
+ $validation->dns_zm_key = (string)$validation->dns_lexicon_token;
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient/setup.sh b/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient/setup.sh
index fd9b73425..20a65224b 100755
--- a/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient/setup.sh
+++ b/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient/setup.sh
@@ -1,9 +1,9 @@
#!/bin/sh
ACME_BASE="/var/etc/acme-client"
-ACME_DIRS="/var/etc/acme-client/certs /var/etc/acme-client/keys /var/etc/acme-client/configs /var/etc/acme-client/challenges /var/etc/acme-client/home"
+ACME_DIRS="/var/etc/acme-client/certs /var/etc/acme-client/keys /var/etc/acme-client/configs /var/etc/acme-client/challenges /var/etc/acme-client/home /var/etc/acme-client/cert-home"
-# Generate required directories and set owner/mode recursively.
+# Create required directories and set owner/mode recursively.
for directory in ${ACME_DIRS}; do
mkdir -p ${directory}
chown -R root:wheel ${directory}