From af235daa4383657eb015e799fd8d927090809779 Mon Sep 17 00:00:00 2001 From: Franco Fichtner Date: Fri, 14 Feb 2025 11:08:17 +0100 Subject: [PATCH] system: change the "monitor" syshook and de-deprecate; closese #8199 We move the gateway recovery into the hook as a user and users can do their on similar scripts to fetch current status and inspect and react accordingly. We do so before filter reload to avoid excessive reloads in the facility script(s). What this loses is the ability to get the previous argments for statistics, but OTOH it also reduces the risk for spurious events as we only trigger on state transitions. --- plist | 2 +- src/etc/rc.routing_configure | 18 +++----- src/etc/rc.syshook.d/monitor/10-dpinger | 3 -- src/etc/rc.syshook.d/monitor/20-recover | 43 +++++++++++++++++++ .../scripts/routes/gateway_watcher.php | 26 +++-------- 5 files changed, 54 insertions(+), 38 deletions(-) delete mode 100755 src/etc/rc.syshook.d/monitor/10-dpinger create mode 100755 src/etc/rc.syshook.d/monitor/20-recover diff --git a/plist b/plist index f7d269efd..7b0c023af 100644 --- a/plist +++ b/plist @@ -136,7 +136,7 @@ /usr/local/etc/rc.syshook.d/early/20-backup /usr/local/etc/rc.syshook.d/early/90-carp /usr/local/etc/rc.syshook.d/import/20-importer -/usr/local/etc/rc.syshook.d/monitor/10-dpinger +/usr/local/etc/rc.syshook.d/monitor/20-recover /usr/local/etc/rc.syshook.d/start/10-newwanip /usr/local/etc/rc.syshook.d/start/20-freebsd /usr/local/etc/rc.syshook.d/start/25-syslog diff --git a/src/etc/rc.routing_configure b/src/etc/rc.routing_configure index ec236e42c..1ec17a489 100755 --- a/src/etc/rc.routing_configure +++ b/src/etc/rc.routing_configure @@ -36,7 +36,7 @@ require_once 'filter.inc'; exit_on_bootup(); /* when called with an argument we are in gateway switch mode */ -$recover_only = !empty($argv[1]); +$monitor_hook = !empty($argv[1]); /* drop deleted routes */ foreach (glob("/tmp/delete_route_*.todo") as $filename) { @@ -46,19 +46,11 @@ foreach (glob("/tmp/delete_route_*.todo") as $filename) { unlink($filename); } -system_routing_configure(true, null, !$recover_only); +/* routing is not allowed to restart monitors when extended hook is requested */ +system_routing_configure(true, null, !$monitor_hook); -if ($recover_only) { - $gwnames = []; - - foreach (return_gateways_status() as $status) { - if ($status['status'] == 'down') { - /* try to recover monitors stuck in down state ignoring "force_down" */ - $gwnames[] = $status['name']; - } - } - - plugins_configure('monitor', true, [$gwnames]); +if ($monitor_hook) { + passthru('/usr/local/etc/rc.syshook monitor'); } filter_configure_sync(true, false); diff --git a/src/etc/rc.syshook.d/monitor/10-dpinger b/src/etc/rc.syshook.d/monitor/10-dpinger deleted file mode 100755 index d808a714e..000000000 --- a/src/etc/rc.syshook.d/monitor/10-dpinger +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -# XXX stub for monitoring facility, functionality moved to gateway_watcher.php diff --git a/src/etc/rc.syshook.d/monitor/20-recover b/src/etc/rc.syshook.d/monitor/20-recover new file mode 100755 index 000000000..b70870d0c --- /dev/null +++ b/src/etc/rc.syshook.d/monitor/20-recover @@ -0,0 +1,43 @@ +#!/usr/local/bin/php + + * 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 'config.inc'; +require_once 'util.inc'; +require_once 'system.inc'; + +$gwnames = []; + +foreach (return_gateways_status() as $status) { + if ($status['status'] == 'down') { + /* try to recover monitors stuck in down state ignoring "force_down" */ + $gwnames[] = $status['name']; + } +} + +plugins_configure('monitor', true, [$gwnames]); diff --git a/src/opnsense/scripts/routes/gateway_watcher.php b/src/opnsense/scripts/routes/gateway_watcher.php index 8854a8504..a81080484 100755 --- a/src/opnsense/scripts/routes/gateway_watcher.php +++ b/src/opnsense/scripts/routes/gateway_watcher.php @@ -2,7 +2,7 @@ + * Copyright (C) 2023-2025 Franco Fichtner * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -64,8 +64,6 @@ while (1) { continue; } - $alarm = false; - /* clear known gateways in first step to flush unknown in second step */ $cleanup = $mode; foreach ($status as $report) { @@ -77,7 +75,7 @@ while (1) { /* run main watcher pass */ foreach ($status as $report) { - $ralarm = false; + $alarm = false; if ($report['loss'] == '~') { /* wait for valid data before triggering an alarm */ @@ -98,7 +96,7 @@ while (1) { if (isset($config['system']['gw_switch_default'])) { /* only consider down state transition in this case */ if (!empty($mode[$report['name']]) && $mode[$report['name']] != $report['status'] && ($mode[$report['name']] == 'down' || $report['status'] == 'down')) { - $ralarm = true; + $alarm = true; } } @@ -109,31 +107,17 @@ while (1) { /* consider all state transitions as they depend on individual trigger setting */ if (!empty($mode[$report['name']]) && $mode[$report['name']] != $report['status']) { /* XXX consider trigger conditions later on */ - $ralarm = true; + $alarm = true; break; } } } } - if ($ralarm) { - /* raise an alarm via the rc.syshook monitor facility */ - shell_safe("/usr/local/etc/rc.syshook monitor %s %s %s %s %s %s", [ - $report['name'], - $report['monitor'], - $mode[$report['name']] . ' -> ' . $report['status'], - $report['delay'], - $report['stddev'], - $report['loss'] - ]); - - $alarm = true; - } - if ($mode[$report['name']] != $report['status']) { syslog(LOG_NOTICE, sprintf( "%s: %s (Addr: %s Alarm: %s RTT: %s RTTd: %s Loss: %s)", - $ralarm ? 'ALERT' : 'MONITOR', + $alarm ? 'ALERT' : 'MONITOR', $report['name'], $report['monitor'], $mode[$report['name']] . ' -> ' . $report['status'],