diff --git a/security/acme-client/pkg-descr b/security/acme-client/pkg-descr index bacc33ad1..2d89753b0 100644 --- a/security/acme-client/pkg-descr +++ b/security/acme-client/pkg-descr @@ -10,9 +10,18 @@ Plugin Changelog 2.4 +Added: +* add new page to show AcmeClient entries from system log + Fixed: * fix missing "--ecc" parameter when renewing ECC certs (#2223) * fix log file location (#2227) +* fix GUI log formatting (by using the syslog log) + +Changed: +* let acme.sh log through syslog +* revamp logs page, move acme.sh log to a sub tab +* remove legacy logs page 2.3 diff --git a/security/acme-client/src/etc/inc/plugins.inc.d/acmeclient.inc b/security/acme-client/src/etc/inc/plugins.inc.d/acmeclient.inc index a210c2f85..801a1fb07 100644 --- a/security/acme-client/src/etc/inc/plugins.inc.d/acmeclient.inc +++ b/security/acme-client/src/etc/inc/plugins.inc.d/acmeclient.inc @@ -71,6 +71,15 @@ function acmeclient_services() return $services; } +function acmeclient_syslog() +{ + $logfacilities = array(); + $logfacilities['acmeclient'] = array( + 'facility' => array('acmeclient', 'acme.sh') + ); + return $logfacilities; +} + /** * NOTE: Does NOT support configuration sync (xmlrpc). The required acme.sh * state files are missing on the secondary node and thus all attempts diff --git a/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/LogsController.php b/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/LogsController.php new file mode 100644 index 000000000..927e31f9d --- /dev/null +++ b/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/LogsController.php @@ -0,0 +1,45 @@ +view->pick('OPNsense/AcmeClient/logs'); + } +} 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 0a6fbba49..151445d0c 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 @@ -123,8 +123,6 @@ abstract class LeCommon // Store config objects $this->config = $obj; $this->model = $model; - // Set log file - $this->acme_args[] = LeUtils::execSafe('--log %s', self::ACME_LOG_FILE); return true; } @@ -155,26 +153,36 @@ abstract class LeCommon switch ($loglevel) { case 'extended': + $this->acme_args[] = '--syslog 6'; $this->acme_args[] = '--log-level 2'; $this->debug = false; break; case 'debug': + $this->acme_args[] = '--syslog 7'; $this->acme_args[] = '--debug'; $this->debug = true; break; case 'debug2': + $this->acme_args[] = '--syslog 7'; $this->acme_args[] = '--debug 2'; $this->debug = true; break; case 'debug3': + $this->acme_args[] = '--syslog 7'; $this->acme_args[] = '--debug 3'; $this->debug = true; break; default: + $this->acme_args[] = '--syslog 6'; $this->acme_args[] = '--log-level 1'; $this->debug = false; break; } + + // Set log file + // NOTE: This log file is no longer exposed to the GUI. However, it may + // still turn out to be useful for debug purposes in rare egde cases. + $this->acme_args[] = LeUtils::execSafe('--log %s', self::ACME_LOG_FILE); } /** diff --git a/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/Menu/Menu.xml b/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/Menu/Menu.xml index 79a8f7cf8..33a92cfb5 100644 --- a/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/Menu/Menu.xml +++ b/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/Menu/Menu.xml @@ -9,7 +9,10 @@ - + + + + diff --git a/security/acme-client/src/opnsense/mvc/app/views/OPNsense/AcmeClient/logs.volt b/security/acme-client/src/opnsense/mvc/app/views/OPNsense/AcmeClient/logs.volt new file mode 100644 index 000000000..ae057bc86 --- /dev/null +++ b/security/acme-client/src/opnsense/mvc/app/views/OPNsense/AcmeClient/logs.volt @@ -0,0 +1,130 @@ +{# + # Copyright (c) 2019 Deciso B.V. + # 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. + #} + + + + + + +
+ +
+
+
+ + + + + + + + + + +
{{ lang._('Date') }}{{ lang._('Process') }}{{ lang._('Line') }}
+
+
+
+ +
+
+
+ + + + + + + + + + +
{{ lang._('Date') }}{{ lang._('Process') }}{{ lang._('Line') }}
+
+
+
+ +
diff --git a/security/acme-client/src/opnsense/scripts/systemhealth/logformats/acmeclient.py b/security/acme-client/src/opnsense/scripts/systemhealth/logformats/acmeclient.py new file mode 100755 index 000000000..a311773ec --- /dev/null +++ b/security/acme-client/src/opnsense/scripts/systemhealth/logformats/acmeclient.py @@ -0,0 +1,63 @@ +""" + Copyright (c) 2021 Frank Wall + Copyright (c) 2020 Ad Schellevis + 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. +""" +import re +import datetime +from . import BaseLogFormat + +class AcmeclientLogFormat(BaseLogFormat): + def __init__(self, filename): + super(AcmeclientLogFormat, self).__init__(filename) + # XXX This is ugly, but it's the only way to override the line() method. + self._priority = 1 + self._startup_timestamp = datetime.datetime.now() + + def match(self, line): + return self._filename.find('acmeclient') > -1 and len(line) > 15 and re.match(r'(?:[01]\d|2[0123]):(?:[012345]\d):(?:[012345]\d)', line[7:15]) + + def timestamp(self, line): + # syslog format, strip timestamp and return actual log data + ts = datetime.datetime.strptime("%s %s" % (self._startup_timestamp.year, line[0:15]), "%Y %b %d %H:%M:%S") + ts = ts.replace(year=self._startup_timestamp.year) + if (self._startup_timestamp - ts).days < 0: + # likely previous year, (month for this year not reached yet) + ts = ts.replace(year=ts.year - 1) + return ts.isoformat() + + @staticmethod + def line(line): + # parse [date] [hostname] [process_name] [line] format + response = line[16:] + tmp = response.find(':') + pre = response[tmp+1:].strip() if tmp > -1 else response[response.find(' ')+1:].strip() + # strip the duplicate date from the line + return pre[30:].strip() + + @staticmethod + def process_name(line): + response = line[16:] + tmp = response.find(':') + return response[:tmp].strip().split()[-1] if tmp > -1 else "" diff --git a/security/acme-client/src/www/diag_logs_acmeclient.php b/security/acme-client/src/www/diag_logs_acmeclient.php deleted file mode 100644 index e5d406e95..000000000 --- a/security/acme-client/src/www/diag_logs_acmeclient.php +++ /dev/null @@ -1,7 +0,0 @@ - - * Copyright (C) 2004-2009 Scott Ullrich - * Copyright (C) 2003-2004 Manuel Kasper - * 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. - */ - -require_once("guiconfig.inc"); -require_once("system.inc"); -require_once("interfaces.inc"); - -/* expects $logfile to point to the system path */ -/* expects $logclog to be true or false */ - -require_once 'diag_logs_common.inc'; - -$filtertext = ''; -$nentries = 50; - -if (isset($config['syslog']['nentries'])) { - $nentries = $config['syslog']['nentries']; -} - -if (!empty($_POST['clear'])) { - if ($logclog) { - system_clear_clog($logfile); - } else { - system_clear_log($logfile); - } -} - -if (isset($_POST['filtertext'])) { - $filtertext = $_POST['filtertext']; -} - -include("head.inc"); -?> - - - -
-
-
-
-

-

-
-
- -
-
-

-
- - - - - - - - - - - - - - -
- -
-
- - - - -
-
-
-
-
-
-
-