summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--statuspage/README.md2
-rwxr-xr-xstatuspage/checks/pf.sh49
-rwxr-xr-xstatuspage/checks/wg-watcher.sh14
-rwxr-xr-xstatuspage/lib/common.sh8
-rwxr-xr-xstatuspage/render.sh2
5 files changed, 74 insertions, 1 deletions
diff --git a/statuspage/README.md b/statuspage/README.md
index 3b83a81..e77991a 100644
--- a/statuspage/README.md
+++ b/statuspage/README.md
@@ -36,7 +36,7 @@ Each JSON object has exactly these fields:
| `section` | groups rows under a heading: `hardware`, `host services`, `jails` (or a new section name - unrecognized sections are rendered after the known ones, in the order first seen) |
| `label` | display name for the row |
| `value` | display value; use `""` for a plain up/down check with no value |
-| `status` | one of `ok`, `warn`, `down` - maps to a green/yellow/red square |
+| `status` | one of `ok`, `warn`, `down` (green/yellow/red), or `info` (gray) for a row that isn't a health signal at all - e.g. `pf.sh` lists loaded rules as `info` rather than implying each rule is itself being checked |
Example (`checks/wireguard.sh`):
diff --git a/statuspage/checks/pf.sh b/statuspage/checks/pf.sh
new file mode 100755
index 0000000..47b2acd
--- /dev/null
+++ b/statuspage/checks/pf.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+# checks/pf.sh
+# pf health summary (enabled, state table usage, rule count), plus the
+# actual active filter and nat/rdr rules listed as rows below. The rule
+# rows use status "info" (a neutral gray square) rather than "ok" -
+# they're informational, not a health signal, and a green square there
+# would wrongly imply each individual rule was itself being health-
+# checked.
+set -eu
+
+DIR=$(dirname "$0")
+. "$DIR/../lib/common.sh"
+
+INFO=$(pfctl -si 2>/dev/null) || INFO=""
+
+ENABLED=$(printf '%s\n' "$INFO" | awk -F'[ :]+' '/^Status:/{print $2; exit}')
+if [ "$ENABLED" = "Enabled" ]; then
+ json_line "pf" "pf" "" "ok"
+else
+ json_line "pf" "pf" "${ENABLED:-unknown}" "down"
+fi
+
+CURRENT=$(printf '%s\n' "$INFO" | awk '/current entries/{print $NF; exit}')
+LIMIT=$(pfctl -sm 2>/dev/null | awk '/^states/{print $NF; exit}')
+
+if [ -n "$CURRENT" ] && [ -n "$LIMIT" ] && [ "$LIMIT" -gt 0 ] 2>/dev/null; then
+ PCT=$((CURRENT * 100 / LIMIT))
+ if [ "$PCT" -ge 90 ]; then
+ SSTATUS=down
+ elif [ "$PCT" -ge 75 ]; then
+ SSTATUS=warn
+ else
+ SSTATUS=ok
+ fi
+ json_line "pf" "state table" "${CURRENT}/${LIMIT} (${PCT}%)" "$SSTATUS"
+fi
+
+RULE_COUNT=$(pfctl -sr 2>/dev/null | grep -c .) || RULE_COUNT=0
+json_line "pf" "filter rules loaded" "$RULE_COUNT" "ok"
+
+pfctl -sr 2>/dev/null | while IFS= read -r rule; do
+ [ -n "$rule" ] || continue
+ json_line "pf" " $rule" "" "info"
+done
+
+pfctl -sn 2>/dev/null | while IFS= read -r rule; do
+ [ -n "$rule" ] || continue
+ json_line "pf" " nat: $rule" "" "info"
+done
diff --git a/statuspage/checks/wg-watcher.sh b/statuspage/checks/wg-watcher.sh
new file mode 100755
index 0000000..9351afd
--- /dev/null
+++ b/statuspage/checks/wg-watcher.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+# checks/wg-watcher.sh
+# wg-quick's background route monitor (spawned by `wg-quick up wg0` to
+# react to WAN interface/address changes) isn't rc.d-managed, so there's
+# no `service ... status` for it. If it dies, wg0 itself stays up - the
+# kernel interface doesn't depend on it - but the box stops reacting to
+# WAN IP changes (e.g. a DHCP lease renewal) until wg-quick is restarted.
+set -eu
+
+DIR=$(dirname "$0")
+. "$DIR/../lib/common.sh"
+
+STATUS=$(proc_running "route -n monitor")
+json_line "host services" "wg-quick watcher" "" "$STATUS"
diff --git a/statuspage/lib/common.sh b/statuspage/lib/common.sh
index d063e07..dcc26f5 100755
--- a/statuspage/lib/common.sh
+++ b/statuspage/lib/common.sh
@@ -47,3 +47,11 @@ port_check() {
jail_status() {
jls -j "$1" >/dev/null 2>&1 && echo "ok" || echo "down"
}
+
+# proc_running PATTERN
+# Prints "ok" or "down" depending on whether any process's command line
+# matches PATTERN (pgrep -f). For ad-hoc background processes that
+# aren't rc.d-managed, so there's no `service ... status` for them.
+proc_running() {
+ pgrep -f "$1" >/dev/null 2>&1 && echo "ok" || echo "down"
+}
diff --git a/statuspage/render.sh b/statuspage/render.sh
index 22df5e7..a5602f0 100755
--- a/statuspage/render.sh
+++ b/statuspage/render.sh
@@ -85,6 +85,7 @@ function htmlesc(s) {
function sqclass(status) {
if (status == "ok") return "green"
if (status == "warn") return "yellow"
+ if (status == "info") return "gray"
return "red"
}
@@ -128,6 +129,7 @@ END {
print ".green { background:#3c3; }"
print ".yellow { background:#cc3; }"
print ".red { background:#c33; }"
+ print ".gray { background:#666; }"
print ".dim { color:#888; font-size: 0.85em; }"
print "</style>"
print "</head>"