mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
security/acme-client: add support for new ACME CA's, closes #2361
This commit is contained in:
@@ -8,6 +8,15 @@ WWW: https://github.com/acmesh-official/acme.sh
|
||||
Plugin Changelog
|
||||
================
|
||||
|
||||
3.0
|
||||
|
||||
Added:
|
||||
* add support for new ACME CA's: buypass, buypass_test, sslcom, zerossl (#2361)
|
||||
|
||||
Changed:
|
||||
* rename "Let's Encrypt Environment" to "ACME CA" (#2361)
|
||||
* preserve old LE accounts/certs by adding a compatibility layer (#2361)
|
||||
|
||||
2.6
|
||||
|
||||
Added:
|
||||
|
||||
+3
-3
@@ -12,10 +12,10 @@
|
||||
<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.environment</id>
|
||||
<label>Let's Encrypt Environment</label>
|
||||
<id>acmeclient.settings.ca</id>
|
||||
<label>ACME CA</label>
|
||||
<type>dropdown</type>
|
||||
<help><![CDATA[Choose Let's Encrypts staging environment when using it for the first time or while testing new challenge types. The staging environment offers <a href="https://letsencrypt.org/docs/staging-environment/">relaxed rate limits</a>.<br/><div class="text-info"><b>NOTE:</b>Certificates signed by the staging environment are NOT valid. You need to forcefully re-sign (or delete and re-create) them after switching from staging to production environment.</div>]]></help>
|
||||
<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">acme.sh documentation</a> for a list of supported CAs.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>acmeclient.settings.haproxyIntegration</id>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 Frank Wall
|
||||
* Copyright (C) 2020-2021 Frank Wall
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -53,8 +53,8 @@ class LeAccount extends LeCommon
|
||||
// Set log level
|
||||
$this->setLoglevel();
|
||||
|
||||
// Set Let's Encrypt environment
|
||||
$this->setEnvironment();
|
||||
// Set ACME CA
|
||||
$this->setCa();
|
||||
|
||||
// Store acme filenames
|
||||
$this->acme_args[] = LeUtils::execSafe('--home %s', self::ACME_HOME_DIR);
|
||||
@@ -66,7 +66,7 @@ class LeAccount extends LeCommon
|
||||
public function generateKey()
|
||||
{
|
||||
// Collect account information
|
||||
$account_conf_dir = self::ACME_BASE_ACCOUNT_DIR . '/' . (string)$this->config->id . '_' . $this->environment;
|
||||
$account_conf_dir = self::ACME_BASE_ACCOUNT_DIR . '/' . (string)$this->config->id . '_' . $this->ca_compat;
|
||||
$account_conf_file = $account_conf_dir . '/account.conf';
|
||||
$account_key_file = $account_conf_dir . '/account.key';
|
||||
$account_json_file = $account_conf_dir . '/account.json';
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 Frank Wall
|
||||
* Copyright (C) 2020-2021 Frank Wall
|
||||
* Copyright (C) 2018 Deciso B.V.
|
||||
* Copyright (C) 2018 Franco Fichtner <franco@opnsense.org>
|
||||
* All rights reserved.
|
||||
@@ -63,8 +63,8 @@ abstract class Base extends \OPNsense\AcmeClient\LeCommon
|
||||
// Set log level
|
||||
$this->setLoglevel();
|
||||
|
||||
// Set Let's Encrypt environment
|
||||
$this->setEnvironment();
|
||||
// Set ACME CA
|
||||
$this->setCa();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+3
-3
@@ -74,8 +74,8 @@ class LeCertificate extends LeCommon
|
||||
// Set log level
|
||||
$this->setLoglevel();
|
||||
|
||||
// Set Let's Encrypt environment
|
||||
$this->setEnvironment();
|
||||
// Set ACME CA
|
||||
$this->setCa();
|
||||
|
||||
// Handle special key types
|
||||
if ($this->config->keyLength == 'key_ec256' || $this->config->keyLength == 'key_ec384') {
|
||||
@@ -528,7 +528,7 @@ class LeCertificate extends LeCommon
|
||||
LeUtils::log('revoking certificate: ' . (string)$this->config->name);
|
||||
|
||||
// Collect account information
|
||||
$account_conf_dir = self::ACME_BASE_ACCOUNT_DIR . '/' . $this->account_id . '_' . $this->environment;
|
||||
$account_conf_dir = self::ACME_BASE_ACCOUNT_DIR . '/' . $this->account_id . '_' . $this->ca_compat;
|
||||
$account_conf_file = $account_conf_dir . '/account.conf';
|
||||
|
||||
// Preparation to run acme client
|
||||
|
||||
@@ -83,7 +83,8 @@ abstract class LeCommon
|
||||
protected $cron; # Run from cron job
|
||||
protected $config; # AcmeClient config object
|
||||
protected $debug; # Debug logging (bool)
|
||||
protected $environment; # Let's Encrypt environment (uses shortnames)
|
||||
protected $ca; # ACME CA
|
||||
protected $ca_compat; # ACME CA for compat with old LE CA names
|
||||
protected $force; # Force operation
|
||||
protected $model; # AcmeClient model object
|
||||
protected $uuid; # AcmeClient config object uuid
|
||||
@@ -136,12 +137,29 @@ abstract class LeCommon
|
||||
}
|
||||
|
||||
/**
|
||||
* set Let's Encrypt environment for acme.sh
|
||||
* set ACME CA for acme.sh
|
||||
*/
|
||||
public function setEnvironment()
|
||||
public function setCa()
|
||||
{
|
||||
$this->environment = (string)$this->model->getNodeByReference('settings.environment');
|
||||
$this->acme_args[] = $this->environment == 'stg' ? '--staging' : null;
|
||||
$this->ca = (string)$this->model->getNodeByReference('settings.ca');
|
||||
$this->acme_args[] = LeUtils::execSafe('--server %s', $this->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) {
|
||||
case 'letsencrypt':
|
||||
$ca_compat = 'prod';
|
||||
break;
|
||||
case 'letsencrypt_test':
|
||||
$ca_compat = 'stg';
|
||||
break;
|
||||
default:
|
||||
$ca_compat = $this->ca;
|
||||
break;
|
||||
}
|
||||
$this->ca_compat = $ca_compat;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 Frank Wall
|
||||
* Copyright (C) 2020-2021 Frank Wall
|
||||
* Copyright (C) 2018 Deciso B.V.
|
||||
* Copyright (C) 2018 Franco Fichtner <franco@opnsense.org>
|
||||
* All rights reserved.
|
||||
@@ -73,8 +73,8 @@ abstract class Base extends \OPNsense\AcmeClient\LeCommon
|
||||
// Set log level
|
||||
$this->setLoglevel();
|
||||
|
||||
// Set Let's Encrypt environment
|
||||
$this->setEnvironment();
|
||||
// Set ACME CA
|
||||
$this->setCa();
|
||||
|
||||
// Store acme hook
|
||||
switch ((string)$this->config->method) {
|
||||
@@ -141,8 +141,8 @@ abstract class Base extends \OPNsense\AcmeClient\LeCommon
|
||||
}
|
||||
}
|
||||
|
||||
// Use individual account config for each environment
|
||||
$account_conf_dir = self::ACME_BASE_ACCOUNT_DIR . '/' . $this->account_id . '_' . $this->environment;
|
||||
// Use individual account config for each CA
|
||||
$account_conf_dir = self::ACME_BASE_ACCOUNT_DIR . '/' . $this->account_id . '_' . $this->ca_compat;
|
||||
$account_conf_file = $account_conf_dir . '/account.conf';
|
||||
|
||||
// Preparation to run acme client
|
||||
|
||||
+14
-2
@@ -1,6 +1,6 @@
|
||||
<model>
|
||||
<mount>//OPNsense/AcmeClient</mount>
|
||||
<version>2.1.0</version>
|
||||
<version>3.0.0</version>
|
||||
<description>A secure Let's Encrypt plugin</description>
|
||||
<items>
|
||||
<settings>
|
||||
@@ -27,13 +27,25 @@
|
||||
<Required>N</Required>
|
||||
</UpdateCron>
|
||||
<environment type="OptionField">
|
||||
<Required>Y</Required>
|
||||
<Required>N</Required>
|
||||
<default>prod</default>
|
||||
<OptionValues>
|
||||
<prod>Production Environment [default]</prod>
|
||||
<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>
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2021 Frank Wall
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OPNsense\AcmeClient\Migrations;
|
||||
|
||||
use OPNsense\Base\BaseModelMigration;
|
||||
|
||||
class M3_0_0 extends BaseModelMigration
|
||||
{
|
||||
public function run($model)
|
||||
{
|
||||
// Get old LE environment and map to new value
|
||||
$env = (string)$model->settings->environment;
|
||||
switch ($env) {
|
||||
case 'prod':
|
||||
$new_ca = 'letsencrypt';
|
||||
break;
|
||||
case 'stg':
|
||||
$new_ca = 'letsencrypt_test';
|
||||
break;
|
||||
}
|
||||
|
||||
// Set new CA
|
||||
$model->settings->ca = $new_ca;
|
||||
$model->settings->environment = null; // clear old value
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{#
|
||||
|
||||
Copyright (C) 2017-2019 Frank Wall
|
||||
Copyright (C) 2017-2021 Frank Wall
|
||||
OPNsense® is Copyright © 2014-2015 by Deciso B.V.
|
||||
All rights reserved.
|
||||
|
||||
@@ -247,7 +247,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
<br/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<b>{{ lang._("Please read the official %sLet's Encrypt documentation%s before using this plugin. Otherwise you will easily hit its %srate limits%s and thus all your attempts to issue a certificate will fail.") | format('<a href="https://letsencrypt.org/how-it-works/">', '</a>', '<a href="https://letsencrypt.org/docs/rate-limits/">', '</a>') }}</b>{{ lang._("Please use Let's Encrypt's %sstaging servers%s when using this plugin for the first time or while testing a new challenge type. You will have to reissue your certificates when switching from staging to production servers to get valid certificates.") | format('<a href="https://letsencrypt.org/docs/staging-environment/">', '</a>') }}
|
||||
<b>{{ lang._("Please read the official %sLet's Encrypt documentation%s before using this plugin. It should give you a good overview about how the various ACME CAs work, so you do not hit their %srate limits%s and avoid common misconfigurations, which would let all your attempts to issue a certificate fail.") | format('<a href="https://letsencrypt.org/how-it-works/">', '</a>', '<a href="https://letsencrypt.org/docs/rate-limits/">', '</a>') }}</b>{{ lang._("Please use a %stest CA%s when using this plugin for the first time or while testing a new challenge type. Note that you will have to reissue your certificates when switching from a test to a production CA to get valid certificates.") | format('<a href="https://letsencrypt.org/docs/staging-environment/">', '</a>') }}
|
||||
<br/>
|
||||
{{ lang._('Please use the %sissue tracker%s to report bugs or request new features.') | format('<a href="https://github.com/opnsense/plugins/issues">', '</a>') }}
|
||||
<br/>
|
||||
|
||||
Reference in New Issue
Block a user