mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
security/acme-client: make it possible to use multiple CAs
This commit is contained in:
@@ -11,15 +11,19 @@ Plugin Changelog
|
||||
3.0
|
||||
|
||||
Added:
|
||||
* add support for new ACME CA's: buypass, buypass_test, sslcom, zerossl (#2361)
|
||||
* add support for new ACME CAs: buypass, buypass_test, sslcom, zerossl (#2361)
|
||||
* add CA setting to accounts, make it possible to use multiple CAs
|
||||
* add introduction pages and an option to hide them
|
||||
* add tooltips for account command buttons (#2188)
|
||||
* add support for custom ACME EAB kid/hmac when registering accounts
|
||||
|
||||
Fixed:
|
||||
* properly set/get the UUID of LE objects
|
||||
|
||||
Changed:
|
||||
* rename plugin from "Let's Encrypt client" to "ACME Client" (#2361)
|
||||
* change the suffix for imports to the certificate storage to "ACME Client" (#2361)
|
||||
* rename "Let's Encrypt Environment" to "ACME CA" (#2361)
|
||||
* rename "Let's Encrypt Environment" to "ACME CA" and move to account settings (#2361)
|
||||
* preserve old LE accounts/certs by adding a compatibility layer (#2361)
|
||||
* update tooltip style for 21.7 (#2188)
|
||||
* show more options in list view for challenge types and automations
|
||||
|
||||
+10
@@ -17,12 +17,22 @@
|
||||
<type>text</type>
|
||||
<help>Description for this account.</help>
|
||||
</field>
|
||||
<field>
|
||||
<label>NOTE: Settings below must not be changed after account registration.</label>
|
||||
<type>header</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>account.email</id>
|
||||
<label>E-Mail Address</label>
|
||||
<type>text</type>
|
||||
<help>Optional e-mail address for this account.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>account.ca</id>
|
||||
<label>ACME CA</label>
|
||||
<type>dropdown</type>
|
||||
<help><![CDATA[The ACME CA that should be used for this account and all associated certificates. Note that some of them offer paid services and may require a subscription. Check the <a href="https://github.com/acmesh-official/acme.sh/wiki/Server" target="_blank">acme.sh documentation</a> for a list of supported CAs.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<label>Optional EAB Credentials</label>
|
||||
<type>header</type>
|
||||
|
||||
-6
@@ -11,12 +11,6 @@
|
||||
<type>checkbox</type>
|
||||
<help><![CDATA[Enable automatic renewal for certificates to prevent expiration. This will add a cron job to the system. You may want to customize the cron job schedule to your needs, because re-issueing a certificate may lead to a short downtime, depending on the selected challenge type and service.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>acmeclient.settings.ca</id>
|
||||
<label>ACME CA</label>
|
||||
<type>dropdown</type>
|
||||
<help><![CDATA[The ACME CA that should be used to issue or renew certificates. Note that some of them offer paid services and may require a subscription. Check the <a href="https://github.com/acmesh-official/acme.sh/wiki/Server" target="_blank">acme.sh documentation</a> for a list of supported CAs.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>acmeclient.settings.haproxyIntegration</id>
|
||||
<label>HAProxy Integration</label>
|
||||
|
||||
@@ -54,7 +54,7 @@ class LeAccount extends LeCommon
|
||||
$this->setLoglevel();
|
||||
|
||||
// Set ACME CA
|
||||
$this->setCa();
|
||||
$this->setCa($uuid);
|
||||
|
||||
// Store acme filenames
|
||||
$this->acme_args[] = LeUtils::execSafe('--home %s', self::ACME_HOME_DIR);
|
||||
@@ -213,7 +213,7 @@ class LeAccount extends LeCommon
|
||||
LeUtils::log_debug('starting account registration for ' . (string)$this->config->name, $this->debug);
|
||||
|
||||
// Check if ACME External Account Binding (EAB) is enabled
|
||||
if (!empty((string)$this->config->eab_kid) && !empty((string)$this->config->eab_hmac) {
|
||||
if (!empty((string)$this->config->eab_kid) && !empty((string)$this->config->eab_hmac)) {
|
||||
LeUtils::log_debug('enabling ACME EAB for this account', $this->debug);
|
||||
$this->acme_args[] = LeUtils::execSafe('--eab-kid %s', $this->config->eab_kid);
|
||||
$this->acme_args[] = LeUtils::execSafe('--eab-hmac-key %s', $this->config->eab_hmac);
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ abstract class Base extends \OPNsense\AcmeClient\LeCommon
|
||||
$this->setLoglevel();
|
||||
|
||||
// Set ACME CA
|
||||
$this->setCa();
|
||||
$this->setCa($accountuuid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
-1
@@ -75,7 +75,7 @@ class LeCertificate extends LeCommon
|
||||
$this->setLoglevel();
|
||||
|
||||
// Set ACME CA
|
||||
$this->setCa();
|
||||
$this->setCa((string)$this->config->account);
|
||||
|
||||
// Handle special key types
|
||||
if ($this->config->keyLength == 'key_ec256' || $this->config->keyLength == 'key_ec384') {
|
||||
@@ -351,6 +351,7 @@ class LeCertificate extends LeCommon
|
||||
return false;
|
||||
}
|
||||
LeUtils::log("${acme_action} certificate: " . (string)$this->config->name);
|
||||
LeUtils::log('using CA: ' . $this->ca);
|
||||
|
||||
// Ensure that account is registered.
|
||||
if (!($this->setAccount())) {
|
||||
|
||||
@@ -105,7 +105,7 @@ abstract class LeCommon
|
||||
*/
|
||||
public function getUuid()
|
||||
{
|
||||
return (string)$this->config->uuid;
|
||||
return (string)$this->uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,6 +124,7 @@ abstract class LeCommon
|
||||
// Store config objects
|
||||
$this->config = $obj;
|
||||
$this->model = $model;
|
||||
$this->uuid = $uuid;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -139,16 +140,28 @@ abstract class LeCommon
|
||||
/**
|
||||
* set ACME CA for acme.sh
|
||||
*/
|
||||
public function setCa()
|
||||
public function setCa(string $uuid)
|
||||
{
|
||||
$this->ca = (string)$this->model->getNodeByReference('settings.ca');
|
||||
$this->acme_args[] = LeUtils::execSafe('--server %s', $this->ca);
|
||||
// Get account config object
|
||||
$model = new \OPNsense\AcmeClient\AcmeClient();
|
||||
$obj = $model->getNodeByReference("accounts.account.${uuid}");
|
||||
if (empty($obj) || $obj == null) {
|
||||
LeUtils::log_error("unable to set CA, account not found: ${uuid}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract ACME CA from account config
|
||||
$acme_ca = (string)$obj->ca;
|
||||
$this->ca = $acme_ca;
|
||||
|
||||
// Add CA to acme arguments
|
||||
$this->acme_args[] = LeUtils::execSafe('--server %s', $acme_ca);
|
||||
|
||||
// Evaluate how the CA should be represented in filenames.
|
||||
// This is a compatibility layer. It ensures that old files that
|
||||
// were generated for the Let's Encrypt Production/Staging CA
|
||||
// can still be used.
|
||||
switch ($this->ca) {
|
||||
switch ($acme_ca) {
|
||||
case 'letsencrypt':
|
||||
$ca_compat = 'prod';
|
||||
break;
|
||||
@@ -156,7 +169,7 @@ abstract class LeCommon
|
||||
$ca_compat = 'stg';
|
||||
break;
|
||||
default:
|
||||
$ca_compat = $this->ca;
|
||||
$ca_compat = $acme_ca;
|
||||
break;
|
||||
}
|
||||
$this->ca_compat = $ca_compat;
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ abstract class Base extends \OPNsense\AcmeClient\LeCommon
|
||||
$this->setLoglevel();
|
||||
|
||||
// Set ACME CA
|
||||
$this->setCa();
|
||||
$this->setCa($accountuuid);
|
||||
|
||||
// Store acme hook
|
||||
switch ((string)$this->config->method) {
|
||||
|
||||
+12
-12
@@ -34,18 +34,6 @@
|
||||
<stg>Staging Environment</stg>
|
||||
</OptionValues>
|
||||
</environment>
|
||||
<ca type="OptionField">
|
||||
<Required>Y</Required>
|
||||
<default></default>
|
||||
<OptionValues>
|
||||
<buypass>Buypass</buypass>
|
||||
<buypass_test>Buypass Test CA</buypass_test>
|
||||
<letsencrypt>Let's Encrypt [default]</letsencrypt>
|
||||
<letsencrypt_test>Let's Encrypt Test CA</letsencrypt_test>
|
||||
<sslcom>SSL.com</sslcom>
|
||||
<zerossl>ZeroSSL</zerossl>
|
||||
</OptionValues>
|
||||
</ca>
|
||||
<challengePort type="IntegerField">
|
||||
<default>43580</default>
|
||||
<MinimumValue>1024</MinimumValue>
|
||||
@@ -148,6 +136,18 @@
|
||||
<email type="EmailField">
|
||||
<Required>N</Required>
|
||||
</email>
|
||||
<ca type="OptionField">
|
||||
<Required>Y</Required>
|
||||
<default>letsencrypt</default>
|
||||
<OptionValues>
|
||||
<buypass>Buypass</buypass>
|
||||
<buypass_test>Buypass Test CA</buypass_test>
|
||||
<letsencrypt>Let's Encrypt [default]</letsencrypt>
|
||||
<letsencrypt_test>Let's Encrypt Test CA</letsencrypt_test>
|
||||
<sslcom>SSL.com</sslcom>
|
||||
<zerossl>ZeroSSL</zerossl>
|
||||
</OptionValues>
|
||||
</ca>
|
||||
<eab_kid type="TextField">
|
||||
<Required>N</Required>
|
||||
<mask>/^.{1,8192}$/u</mask>
|
||||
|
||||
+6
-3
@@ -46,9 +46,12 @@ class M3_0_0 extends BaseModelMigration
|
||||
$new_ca = 'letsencrypt_test';
|
||||
break;
|
||||
}
|
||||
|
||||
// Set new CA
|
||||
$model->settings->ca = $new_ca;
|
||||
$model->settings->environment = null; // clear old value
|
||||
|
||||
// Search accounts
|
||||
foreach ($model->getNodeByReference('accounts.account')->iterateItems() as $account) {
|
||||
// Set CA
|
||||
$account->ca = $new_ca;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
<p>{{ lang._("Setting up this plugin for the first time involves the following steps") }}</p>
|
||||
<ul>
|
||||
<li>{{ lang._('%sEnable%s the plugin: When enabling this plugin in the %ssettings%s, a lightweight service is started and cron jobs are added for automatic tasks.') | format('<b>', '</b>', '<a href="/ui/acmeclient#settings">', '</a>') }}</li>
|
||||
<li>{{ lang._('Create an %saccount%s: An %saccount%s is required and will be automatically at the chosen CA.') | format('<b>', '</b>', '<a href="/ui/acmeclient/accounts">', '</a>') }}</li>
|
||||
<li>{{ lang._('Create an %saccount%s: An %saccount%s is required. It determines which CA will be used for all associated certificates.') | format('<b>', '</b>', '<a href="/ui/acmeclient/accounts">', '</a>') }}</li>
|
||||
<li>{{ lang._('Set up a %schallenge type%s: Choose the %schallenge type%s that works best for you and if necessary, add the credentials for your DNS provider.') | format('<b>', '</b>', '<a href="/ui/acmeclient/validations">', '</a>') }}</li>
|
||||
<li>{{ lang._('Add %sautomations%s: This is optional, but recommended when using short-lived certificates. %sAutomations%s allow to automatically run tasks when a certificate was created or renewed.') | format('<b>', '</b>', '<a href="/ui/acmeclient/actions">', '</a>') }}</li>
|
||||
<li>{{ lang._('Create %scertificates%s: Finally create the %scertificates%s and let the CA complete the validation process.') | format('<b>', '</b>', '<a href="/ui/acmeclient/certificates">', '</a>') }}</li>
|
||||
|
||||
Reference in New Issue
Block a user