mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
Merge pull request #2647 from fraenki/acme_350
security/acme-client: release 3.5
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
PLUGIN_NAME= acme-client
|
||||
PLUGIN_VERSION= 3.4
|
||||
PLUGIN_VERSION= 3.5
|
||||
PLUGIN_COMMENT= ACME Client
|
||||
PLUGIN_MAINTAINER= opnsense@moov.de
|
||||
PLUGIN_DEPENDS= acme.sh py${PLUGIN_PYTHON}-dns-lexicon
|
||||
|
||||
@@ -8,6 +8,18 @@ WWW: https://github.com/acmesh-official/acme.sh
|
||||
Plugin Changelog
|
||||
================
|
||||
|
||||
3.5
|
||||
|
||||
Added:
|
||||
* new automation: cert upload to Synology DSM (#2236)
|
||||
* new automation: cert upload to FRITZ!Box router
|
||||
|
||||
Fixed:
|
||||
* fix logging when clog is disabled (#2555)
|
||||
|
||||
Changed:
|
||||
* refactor code to support acme.sh deploy hooks
|
||||
|
||||
3.4
|
||||
|
||||
Changed:
|
||||
|
||||
+71
-5
@@ -26,7 +26,7 @@
|
||||
<field>
|
||||
<label>Required Parameters</label>
|
||||
<type>header</type>
|
||||
<style>method_table method_table_upload_highwinds</style>
|
||||
<style>method_table method_table_configd_upload_highwinds</style>
|
||||
</field>
|
||||
<field>
|
||||
<id>action.highwinds_account_hash</id>
|
||||
@@ -43,7 +43,7 @@
|
||||
<field>
|
||||
<label>Required Parameters</label>
|
||||
<type>header</type>
|
||||
<style>method_table method_table_upload_sftp</style>
|
||||
<style>method_table method_table_configd_upload_sftp</style>
|
||||
</field>
|
||||
<field>
|
||||
<id>action.sftp_host</id>
|
||||
@@ -145,13 +145,79 @@
|
||||
<field>
|
||||
<label>Required Parameters</label>
|
||||
<type>header</type>
|
||||
<style>method_table method_table_configd</style>
|
||||
<style>method_table method_table_configd_generic</style>
|
||||
</field>
|
||||
<field>
|
||||
<id>action.configd</id>
|
||||
<id>action.configd_generic_command</id>
|
||||
<label>System Command</label>
|
||||
<type>dropdown</type>
|
||||
<help>Select a pre-defined system command which should be run.</help>
|
||||
<style>table_optional table_optional_configd</style>
|
||||
</field>
|
||||
<field>
|
||||
<label>Required Parameters</label>
|
||||
<type>header</type>
|
||||
<style>method_table method_table_acme_synology_dsm</style>
|
||||
</field>
|
||||
<field>
|
||||
<id>action.acme_synology_dsm_hostname</id>
|
||||
<label>Synology Hostname</label>
|
||||
<type>text</type>
|
||||
<help>Hostname of IP adress of the Synology DSM, i.e. synology.example.com or 192.168.0.1.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>action.acme_synology_dsm_port</id>
|
||||
<label>Synology Port</label>
|
||||
<type>text</type>
|
||||
<help>Port that will be used when connecting to Synology DSM.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>action.acme_synology_dsm_scheme</id>
|
||||
<label>Scheme</label>
|
||||
<type>dropdown</type>
|
||||
<help>Connection scheme that will be used when uploading certificates to Synology DSM.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>action.acme_synology_dsm_username</id>
|
||||
<label>Username</label>
|
||||
<type>text</type>
|
||||
<help>Username to login, must be an administrator.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>action.acme_synology_dsm_password</id>
|
||||
<label>Password</label>
|
||||
<type>password</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>action.acme_synology_dsm_deviceid</id>
|
||||
<label>Device ID</label>
|
||||
<type>text</type>
|
||||
<help>If Synology DSM has OTP enabled, then the device ID has to be provided so that no OTP is required when running the automation.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>action.acme_synology_dsm_create</id>
|
||||
<label>Create certificates</label>
|
||||
<type>checkbox</type>
|
||||
<help>This option ensures that a new certificate is created in Synology DSM if it does not exist yet. If unchecked only existing certificates will be updated.</help>
|
||||
</field>
|
||||
<field>
|
||||
<label>Required Parameters</label>
|
||||
<type>header</type>
|
||||
<style>method_table method_table_acme_fritzbox</style>
|
||||
</field>
|
||||
<field>
|
||||
<id>action.acme_fritzbox_url</id>
|
||||
<label>FRITZ!Box URL</label>
|
||||
<type>text</type>
|
||||
<help>URL of the router, i.e. https://fritzbox.example.com.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>action.acme_fritzbox_username</id>
|
||||
<label>Username</label>
|
||||
<type>text</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>action.acme_fritzbox_password</id>
|
||||
<label>Password</label>
|
||||
<type>password</type>
|
||||
</field>
|
||||
</form>
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
<?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\LeAutomation;
|
||||
|
||||
use OPNsense\AcmeClient\LeAutomationInterface;
|
||||
|
||||
/**
|
||||
* Run acme.sh deploy hook fritzbox
|
||||
* @package OPNsense\AcmeClient
|
||||
*/
|
||||
class AcmeFritzbox extends Base implements LeAutomationInterface
|
||||
{
|
||||
public function prepare()
|
||||
{
|
||||
$this->acme_env['DEPLOY_FRITZBOX_URL'] = (string)$this->config->acme_fritzbox_url;
|
||||
$this->acme_env['DEPLOY_FRITZBOX_USERNAME'] = (string)$this->config->acme_fritzbox_username;
|
||||
$this->acme_env['DEPLOY_FRITZBOX_PASSWORD'] = (string)$this->config->acme_fritzbox_password;
|
||||
$this->acme_args[] = '--deploy-hook fritzbox';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
<?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\LeAutomation;
|
||||
|
||||
use OPNsense\AcmeClient\LeAutomationInterface;
|
||||
|
||||
/**
|
||||
* Run acme.sh deploy hook synology_dsm
|
||||
* @package OPNsense\AcmeClient
|
||||
*/
|
||||
class AcmeSynologyDsm extends Base implements LeAutomationInterface
|
||||
{
|
||||
public function prepare()
|
||||
{
|
||||
$this->acme_env['SYNO_Certificate'] = 'OPNsense ACME cert ' . $this->cert_id;
|
||||
$this->acme_env['SYNO_Hostname'] = (string)$this->config->acme_synology_dsm_hostname;
|
||||
$this->acme_env['SYNO_Port'] = (string)$this->config->acme_synology_dsm_port;
|
||||
$this->acme_env['SYNO_Scheme'] = (string)$this->config->acme_synology_dsm_scheme;
|
||||
$this->acme_env['SYNO_Username'] = (string)$this->config->acme_synology_dsm_username;
|
||||
$this->acme_env['SYNO_Password'] = (string)$this->config->acme_synology_dsm_password;
|
||||
if (!empty((string)$this->config->acme_synology_dsm_create)) {
|
||||
$this->acme_env['SYNO_Create'] = (string)$this->config->acme_synology_dsm_create;
|
||||
}
|
||||
if (!empty((string)$this->config->acme_synology_dsm_deviceid)) {
|
||||
$this->acme_env['SYNO_DID'] = (string)$this->config->acme_synology_dsm_deviceid;
|
||||
}
|
||||
$this->acme_args[] = '--deploy-hook synology_dsm';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+80
-2
@@ -47,7 +47,7 @@ abstract class Base extends \OPNsense\AcmeClient\LeCommon
|
||||
* Initialize LeAutomation object by adding the required configuration.
|
||||
* @return boolean
|
||||
*/
|
||||
public function init(string $certid, string $accountuuid)
|
||||
public function init(string $certid, string $certname, string $accountuuid)
|
||||
{
|
||||
// Get config object
|
||||
$this->loadConfig(self::CONFIG_PATH, $this->uuid);
|
||||
@@ -60,12 +60,25 @@ abstract class Base extends \OPNsense\AcmeClient\LeCommon
|
||||
$this->account_id = (string)$account->id;
|
||||
$this->account_uuid = (string)$account->uuid;
|
||||
|
||||
// Teach acme.sh about DNS API hook location
|
||||
$this->acme_env['_SCRIPT_HOME'] = self::ACME_SCRIPT_HOME;
|
||||
|
||||
// Set log level
|
||||
$this->setLoglevel();
|
||||
|
||||
// Set ACME CA
|
||||
$this->setCa($accountuuid);
|
||||
|
||||
// Store acme filenames
|
||||
$this->acme_args[] = LeUtils::execSafe('--home %s', self::ACME_HOME_DIR);
|
||||
$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));
|
||||
$this->acme_args[] = LeUtils::execSafe('--fullchainpath %s', sprintf(self::ACME_FULLCHAIN_FILE, $this->cert_id));
|
||||
|
||||
// Main domain for acme
|
||||
$this->acme_args[] = LeUtils::execSafe('--domain %s', $certname);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -80,7 +93,72 @@ abstract class Base extends \OPNsense\AcmeClient\LeCommon
|
||||
return true; // not an error
|
||||
}
|
||||
|
||||
LeUtils::log('running automation: ' . $this->config->name);
|
||||
// The prefix determines which automation flavour is being used.
|
||||
if (preg_match('/acme.*/i', $this->getType())) {
|
||||
$this->runAcme();
|
||||
} elseif (preg_match('/configd_.*/i', $this->getType())) {
|
||||
$this->runConfigd();
|
||||
} else {
|
||||
LeUtils::log_error('unsupported automation flavour: ' . $this->getType());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* run acme.sh deploy hooks commands
|
||||
* @return boolean
|
||||
*/
|
||||
public function runAcme()
|
||||
{
|
||||
LeUtils::log('running automation (acme.sh): ' . $this->config->name);
|
||||
|
||||
// Preparation to run acme client
|
||||
$proc_env = $this->acme_env; // env variables for proc_open()
|
||||
$proc_env['PATH'] = $this::ACME_ENV_PATH;
|
||||
$proc_desc = array( // descriptor array for proc_open()
|
||||
0 => array("pipe", "r"), // stdin
|
||||
1 => array("pipe", "w"), // stdout
|
||||
2 => array("pipe", "w") // stderr
|
||||
);
|
||||
$proc_pipes = array();
|
||||
|
||||
// Run acme client
|
||||
$acmecmd = self::ACME_CMD
|
||||
. ' '
|
||||
. '--deploy '
|
||||
. implode(' ', $this->acme_args);
|
||||
LeUtils::log_debug('running acme.sh command: ' . (string)$acmecmd, $this->debug);
|
||||
$proc = proc_open($acmecmd, $proc_desc, $proc_pipes, null, $proc_env);
|
||||
|
||||
// Make sure the resource could be setup properly
|
||||
if (is_resource($proc)) {
|
||||
// Close all pipes
|
||||
fclose($proc_pipes[0]);
|
||||
fclose($proc_pipes[1]);
|
||||
fclose($proc_pipes[2]);
|
||||
// Get exit code
|
||||
$result = proc_close($proc);
|
||||
} else {
|
||||
LeUtils::log_error('unable to start acme client process');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check validation result
|
||||
if ($result) {
|
||||
LeUtils::log_error('running acme.sh deploy hook failed (' . $this->getMethod() . ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* run configd commands
|
||||
* @return boolean
|
||||
*/
|
||||
public function runConfigd()
|
||||
{
|
||||
LeUtils::log('running automation (configd): ' . $this->config->name);
|
||||
$backend = new \OPNsense\Core\Backend();
|
||||
$response = $backend->configdRun((string)$this->command, $this->command_args);
|
||||
return true;
|
||||
|
||||
+4
-4
@@ -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
|
||||
@@ -35,17 +35,17 @@ use OPNsense\AcmeClient\LeUtils;
|
||||
* Run selected configd command
|
||||
* @package OPNsense\AcmeClient
|
||||
*/
|
||||
class Configd extends Base implements LeAutomationInterface
|
||||
class ConfigdGeneric extends Base implements LeAutomationInterface
|
||||
{
|
||||
public function prepare()
|
||||
{
|
||||
// Make sure a configd command was specified.
|
||||
if (empty((string)$this->config->configd)) {
|
||||
if (empty((string)$this->config->configd_generic_command)) {
|
||||
LeUtils::log_error('no configd command specified for automation: ' . $this->config->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->command = (string)$this->config->configd;
|
||||
$this->command = (string)$this->config->configd_generic_command;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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
|
||||
@@ -34,7 +34,7 @@ use OPNsense\AcmeClient\LeAutomationInterface;
|
||||
* Restart OPNsense WebGUI
|
||||
* @package OPNsense\AcmeClient
|
||||
*/
|
||||
class RestartGui extends Base implements LeAutomationInterface
|
||||
class ConfigdRestartGui extends Base implements LeAutomationInterface
|
||||
{
|
||||
public function prepare()
|
||||
{
|
||||
+2
-2
@@ -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
|
||||
@@ -34,7 +34,7 @@ use OPNsense\AcmeClient\LeAutomationInterface;
|
||||
* Restart local HAProxy service
|
||||
* @package OPNsense\AcmeClient
|
||||
*/
|
||||
class RestartHaproxy extends Base implements LeAutomationInterface
|
||||
class ConfigdRestartHaproxy extends Base implements LeAutomationInterface
|
||||
{
|
||||
public function prepare()
|
||||
{
|
||||
+2
-2
@@ -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
|
||||
@@ -34,7 +34,7 @@ use OPNsense\AcmeClient\LeAutomationInterface;
|
||||
* Restart local Nginx service
|
||||
* @package OPNsense\AcmeClient
|
||||
*/
|
||||
class RestartNginx extends Base implements LeAutomationInterface
|
||||
class ConfigdRestartNginx extends Base implements LeAutomationInterface
|
||||
{
|
||||
public function prepare()
|
||||
{
|
||||
+2
-2
@@ -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
|
||||
@@ -34,7 +34,7 @@ use OPNsense\AcmeClient\LeAutomationInterface;
|
||||
* Upload certificate to Highwinds CDN API
|
||||
* @package OPNsense\AcmeClient
|
||||
*/
|
||||
class UploadHighwinds extends Base implements LeAutomationInterface
|
||||
class ConfigdUploadHighwinds extends Base implements LeAutomationInterface
|
||||
{
|
||||
public function prepare()
|
||||
{
|
||||
+2
-2
@@ -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
|
||||
@@ -34,7 +34,7 @@ use OPNsense\AcmeClient\LeAutomationInterface;
|
||||
* Upload certificate via SFTP to arbitrary hosts
|
||||
* @package OPNsense\AcmeClient
|
||||
*/
|
||||
class UploadSftp extends Base implements LeAutomationInterface
|
||||
class ConfigdUploadSftp extends Base implements LeAutomationInterface
|
||||
{
|
||||
public function prepare()
|
||||
{
|
||||
+1
-1
@@ -605,7 +605,7 @@ class LeCertificate extends LeCommon
|
||||
foreach ($automations as $auto_uuid) {
|
||||
$autoFactory = new LeAutomationFactory();
|
||||
$automation = $autoFactory->getAutomation($auto_uuid);
|
||||
$automation->init($this->getId(), (string)$this->config->account);
|
||||
$automation->init($this->getId(), (string)$this->config->name, (string)$this->config->account);
|
||||
// Ignore invalid automations.
|
||||
if ($automation->prepare()) {
|
||||
$automation->run();
|
||||
|
||||
@@ -41,11 +41,14 @@ abstract class LeCommon
|
||||
public const ACME_BASE_ACCOUNT_DIR = '/var/etc/acme-client/accounts';
|
||||
public const ACME_BASE_CERT_DIR = '/var/etc/acme-client/certs';
|
||||
public const ACME_BASE_CONFIG_DIR = '/var/etc/acme-client/configs';
|
||||
public const ACME_CMD = '/usr/local/sbin/acme.sh';
|
||||
public const ACME_HOME_DIR = '/var/etc/acme-client/home';
|
||||
|
||||
// Defaults for acme.sh
|
||||
public const ACME_ACCOUNT_KEY_LENGTH = 4096;
|
||||
public const ACME_ENV_PATH = '/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin';
|
||||
public const ACME_SCRIPT_HOME = '/usr/local/share/examples/acme.sh';
|
||||
public const ACME_WEBROOT = '/var/etc/acme-client/challenges';
|
||||
|
||||
// Filenames for certs, configs, ...
|
||||
public const ACME_CERT_DIR = '/var/etc/acme-client/certs/%s/';
|
||||
|
||||
+4
-3
@@ -68,7 +68,7 @@ abstract class Base extends \OPNsense\AcmeClient\LeCommon
|
||||
$this->account_uuid = (string)$account->getUuid();
|
||||
|
||||
// Teach acme.sh about DNS API hook location
|
||||
$this->acme_env['_SCRIPT_HOME'] = '/usr/local/share/examples/acme.sh';
|
||||
$this->acme_env['_SCRIPT_HOME'] = self::ACME_SCRIPT_HOME;
|
||||
|
||||
// Set log level
|
||||
$this->setLoglevel();
|
||||
@@ -83,7 +83,7 @@ abstract class Base extends \OPNsense\AcmeClient\LeCommon
|
||||
$this->acme_args[] = LeUtils::execSafe('--dnssleep %s', (string)$this->config->dns_sleep);
|
||||
break;
|
||||
case 'http01':
|
||||
$this->acme_args[] = '--webroot /var/etc/acme-client/challenges';
|
||||
$this->acme_args[] = '--webroot ' . self::ACME_WEBROOT;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -159,7 +159,8 @@ abstract class Base extends \OPNsense\AcmeClient\LeCommon
|
||||
// NOTE: We "export" certificates to our own directory, so we don't have to deal
|
||||
// with domain names in filesystem, but instead can use the ID of our certObj, which
|
||||
// will never change.
|
||||
$acmecmd = '/usr/local/sbin/acme.sh '
|
||||
$acmecmd = self::ACME_CMD
|
||||
. ' '
|
||||
. "--${acme_action} "
|
||||
. implode(' ', $this->acme_args) . ' '
|
||||
. LeUtils::execSafe('--accountconf %s', $account_conf_file);
|
||||
|
||||
+65
-6
@@ -1042,12 +1042,14 @@
|
||||
<type type="OptionField">
|
||||
<Required>Y</Required>
|
||||
<OptionValues>
|
||||
<restart_gui>Restart OPNsense Web UI</restart_gui>
|
||||
<restart_haproxy>Restart HAProxy (OPNsense plugin)</restart_haproxy>
|
||||
<restart_nginx>Restart Nginx (OPNsense plugin)</restart_nginx>
|
||||
<upload_highwinds>Upload certificate to Highwinds CDN</upload_highwinds>
|
||||
<upload_sftp>Upload certificate via SFTP</upload_sftp>
|
||||
<configd>System or Plugin Command</configd>
|
||||
<configd_restart_gui>Restart OPNsense Web UI</configd_restart_gui>
|
||||
<configd_restart_haproxy>Restart HAProxy (OPNsense plugin)</configd_restart_haproxy>
|
||||
<configd_restart_nginx>Restart Nginx (OPNsense plugin)</configd_restart_nginx>
|
||||
<configd_upload_highwinds>Upload certificate to Highwinds CDN</configd_upload_highwinds>
|
||||
<configd_upload_sftp>Upload certificate via SFTP</configd_upload_sftp>
|
||||
<acme_fritzbox>Upload certificate to FRITZ!Box router</acme_fritzbox>
|
||||
<acme_synology_dsm>Upload certificate to Synology DSM</acme_synology_dsm>
|
||||
<configd_generic>System or Plugin Command</configd_generic>
|
||||
</OptionValues>
|
||||
</type>
|
||||
<highwinds_account_hash type="TextField">
|
||||
@@ -1136,6 +1138,7 @@
|
||||
<ValidationMessage>Should be a string between 1 and 255 characters.
|
||||
Characters are limited to [a-z], [0-9] and [{}@./-_%] and the string must neither begin nor end with '/'.</ValidationMessage>
|
||||
</sftp_filename_fullchain>
|
||||
<!-- old value, should be removed in next major release -->
|
||||
<configd type="ConfigdActionsField">
|
||||
<filters>
|
||||
<description>/^(?!.*(Let\'s\ Encrypt|acme|[fF]irmware))([\S\s]{1,255})/</description>
|
||||
@@ -1143,6 +1146,62 @@
|
||||
<ValidationMessage>Select a command from the list.</ValidationMessage>
|
||||
<Required>N</Required>
|
||||
</configd>
|
||||
<configd_generic_command type="ConfigdActionsField">
|
||||
<filters>
|
||||
<description>/^(?!.*(Let\'s\ Encrypt|acme|[fF]irmware))([\S\s]{1,255})/</description>
|
||||
</filters>
|
||||
<ValidationMessage>Select a command from the list.</ValidationMessage>
|
||||
<Required>N</Required>
|
||||
</configd_generic_command>
|
||||
<acme_synology_dsm_hostname type="HostnameField">
|
||||
<default></default>
|
||||
<Required>N</Required>
|
||||
</acme_synology_dsm_hostname>
|
||||
<acme_synology_dsm_port type="PortField">
|
||||
<default>5000</default>
|
||||
<Required>N</Required>
|
||||
</acme_synology_dsm_port>
|
||||
<acme_synology_dsm_scheme type="OptionField">
|
||||
<default>http</default>
|
||||
<Required>N</Required>
|
||||
<OptionValues>
|
||||
<http>HTTP [default]</http>
|
||||
<https>HTTPS</https>
|
||||
</OptionValues>
|
||||
</acme_synology_dsm_scheme>
|
||||
<acme_synology_dsm_username type="TextField">
|
||||
<Required>N</Required>
|
||||
<mask>/^.{1,1024}$/u</mask>
|
||||
<ValidationMessage>Should be a string between 1 and 1024 characters.</ValidationMessage>
|
||||
</acme_synology_dsm_username>
|
||||
<acme_synology_dsm_password type="TextField">
|
||||
<Required>N</Required>
|
||||
<mask>/^.{1,1024}$/u</mask>
|
||||
<ValidationMessage>Should be a string between 1 and 1024 characters.</ValidationMessage>
|
||||
</acme_synology_dsm_password>
|
||||
<acme_synology_dsm_create type="BooleanField">
|
||||
<default>1</default>
|
||||
</acme_synology_dsm_create>
|
||||
<acme_synology_dsm_deviceid type="TextField">
|
||||
<Required>N</Required>
|
||||
<mask>/^.{1,1024}$/u</mask>
|
||||
<ValidationMessage>Should be a string between 1 and 1024 characters.</ValidationMessage>
|
||||
</acme_synology_dsm_deviceid>
|
||||
<acme_fritzbox_url type="TextField">
|
||||
<Required>N</Required>
|
||||
<mask>/^.{1,1024}$/u</mask>
|
||||
<ValidationMessage>Should be a string between 1 and 1024 characters.</ValidationMessage>
|
||||
</acme_fritzbox_url>
|
||||
<acme_fritzbox_username type="TextField">
|
||||
<Required>N</Required>
|
||||
<mask>/^.{1,1024}$/u</mask>
|
||||
<ValidationMessage>Should be a string between 1 and 1024 characters.</ValidationMessage>
|
||||
</acme_fritzbox_username>
|
||||
<acme_fritzbox_password type="TextField">
|
||||
<Required>N</Required>
|
||||
<mask>/^.{1,1024}$/u</mask>
|
||||
<ValidationMessage>Should be a string between 1 and 1024 characters.</ValidationMessage>
|
||||
</acme_fritzbox_password>
|
||||
</action>
|
||||
</actions>
|
||||
</items>
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
<?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_1_0 extends BaseModelMigration
|
||||
{
|
||||
public function run($model)
|
||||
{
|
||||
// Search actions
|
||||
foreach ($model->getNodeByReference('actions.action')->iterateItems() as $action) {
|
||||
// Field "configd" was renamed to "configd_generic_command"
|
||||
if (!empty((string)$action->configd)) {
|
||||
$action->configd_generic_command = (string)$action->configd;
|
||||
$action->configd = null; // clear old value
|
||||
}
|
||||
|
||||
// Get old type and map to new value
|
||||
$old_type = (string)$action->type;
|
||||
switch ($old_type) {
|
||||
case 'configd':
|
||||
$new_type = 'configd_generic';
|
||||
break;
|
||||
case 'restart_gui':
|
||||
$new_type = 'configd_restart_gui';
|
||||
break;
|
||||
case 'restart_haproxy':
|
||||
$new_type = 'configd_restart_haproxy';
|
||||
break;
|
||||
case 'restart_nginx':
|
||||
$new_type = 'configd_restart_nginx';
|
||||
break;
|
||||
case 'upload_highwinds':
|
||||
$new_type = 'configd_upload_highwinds';
|
||||
break;
|
||||
case 'upload_sftp':
|
||||
$new_type = 'configd_upload_sftp';
|
||||
break;
|
||||
}
|
||||
$action->type = $new_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
lighttpd-acme-challenge.conf:/var/etc/lighttpd-acme-challenge.conf
|
||||
rc.conf.d:/etc/rc.conf.d/acme_http_challenge
|
||||
syslog-filter.conf:/usr/local/opnsense/service/templates/OPNsense/Syslog/local/acmeclient.conf
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
###################################################################
|
||||
# Local syslog-ng configuration filter definition [acmeclient].
|
||||
###################################################################
|
||||
filter f_local_acmeclient {
|
||||
program("acme.sh");
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user