From 8d6aabaab6b82574a3b4023f6c2d38475f7ffbd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni=20Marques?= Date: Sat, 18 Jul 2026 23:58:53 +0200 Subject: [PATCH] release 1.6.0: mail monitoring (firefly + pixel/TSA) --- README.md | 1 + VERSION | 2 +- VERSIONS.md | 11 +- check_mail.sh | 291 ++++++++++++++++++++++ host-agent/README.md | 2 + host-agent/install-host-agent.sh | 8 +- host-agent/run-mail-monitoring.sh | 32 +++ host-agent/taler-monitoring-mail.service | 18 ++ host-agent/taler-monitoring-mail.timer | 14 ++ mail-catalog.conf | 22 ++ site-gen/caddy-monitoring-handles.snippet | 16 ++ taler-monitoring.sh | 6 +- 12 files changed, 415 insertions(+), 8 deletions(-) create mode 100755 check_mail.sh create mode 100755 host-agent/run-mail-monitoring.sh create mode 100644 host-agent/taler-monitoring-mail.service create mode 100644 host-agent/taler-monitoring-mail.timer create mode 100644 mail-catalog.conf diff --git a/README.md b/README.md index 414b9d8..2db24f3 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Checks for **GNU Taler** stacks (bank, exchange, merchant; optional surface inve Outside-only example: `./taler-monitoring.sh -d demo.taler.net urls` Mattermost chat: `./taler-monitoring.sh mattermost` (default `https://mattermost.taler.net`) +Mail (firefly/pixel): `./taler-monitoring.sh mail` Full local GOA example: `./taler-monitoring.sh -d hacktivism.ch urls inside versions` Repo: https://git.hacktivism.ch/hernani/taler-monitoring · tree: `~/src/taler-monitoring` diff --git a/VERSION b/VERSION index 3e1ad72..ce6a70b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.0 \ No newline at end of file +1.6.0 \ No newline at end of file diff --git a/VERSIONS.md b/VERSIONS.md index 5e2f8b2..43140f7 100644 --- a/VERSIONS.md +++ b/VERSIONS.md @@ -13,11 +13,12 @@ Tags and `VERSION` use **MAJOR.FEATURE.FIX** (three components): | **FEATURE** | New capabilities (phases, HTML features, i18n packs, …) | | **FIX** | Bugfixes and docs that do not add a feature | -Git tags: `vMAJOR.FEATURE.FIX` (e.g. `v1.5.0`). File `VERSION` omits the `v` prefix. +Git tags: `vMAJOR.FEATURE.FIX` (e.g. `v1.6.0`). File `VERSION` omits the `v` prefix. | Tag | Date (UTC) | Notes | |-----|------------|--------| -| **v1.6.0** | *planned* | **L10n** packs for user-facing strings that need localization: **fr-CH** (FrancPaysan) and **de-CH** (hacktivism / Taler CH German). | +| **v1.7.0** | *planned* | **L10n** packs for user-facing strings that need localization: **fr-CH** (FrancPaysan) and **de-CH** (hacktivism / Taler CH German). | +| **v1.6.0** | 2026-07-18 | **Mail monitoring:** phase `mail` (`check_mail.sh` + `mail-catalog.conf`) for **firefly** (taler.net, gnunet.org) and **pixel**/TSA (taler-systems.com, mail.anastasis.lu); MX/SMTP/IMAP/SPF/DMARC; host-agent `/taler-monitoring-mail*`. | | **v1.5.0** | 2026-07-18 | **Mattermost monitoring:** phase `mattermost` (`check_mattermost.sh`) for `mattermost.taler.net` (SPA + `/api/v4/system/ping` + TLS); host-agent HTML `/taler-monitoring-mattermost*`; hourly timer. | | **v1.4.1** | 2026-07-18 | **Docs/versioning:** canonical tree `~/src/taler-monitoring`; docs use generic ops/outside-runner wording (no client hostnames); tags always **MAJOR.FEATURE.FIX**. | | **v1.3.4** | 2026-07-18 | Summary i18n, monpages code-21, aptdeploy rsync path. | @@ -33,7 +34,7 @@ Older short tags (`v1`, `v1.0`, `v1.1`, `v1.2`, `v1.3`) are obsolete; use the th ## Sticky bar version (v1.3.0+) -Generated HTML shows the installed release tag (e.g. `v1.5.0`) next to the host line. +Generated HTML shows the installed release tag (e.g. `v1.6.0`) next to the host line. Clicking opens the tag page on Forgejo: `https://git.hacktivism.ch/hernani/taler-monitoring/src/tag/` @@ -65,11 +66,11 @@ sudo ~/koopa-caddy/apply-monitoring-live.sh | Env | `TALER_MON_LANG=en` or `fr` | | Auto | `*lefrancpaysan*` → fr, else en | -Full locale packs (fr-CH / de-CH) are scheduled for **v1.6.0**. +Full locale packs (fr-CH / de-CH) are scheduled for **v1.7.0**. ## Pin a release ```bash git clone https://git.hacktivism.ch/hernani/taler-monitoring.git ~/src/taler-monitoring -cd ~/src/taler-monitoring && git checkout v1.5.0 +cd ~/src/taler-monitoring && git checkout v1.6.0 ``` diff --git a/check_mail.sh b/check_mail.sh new file mode 100755 index 0000000..7b74ca4 --- /dev/null +++ b/check_mail.sh @@ -0,0 +1,291 @@ +#!/usr/bin/env bash +# check_mail.sh — outside-in mail (MX / SMTP / IMAP / SPF / DMARC) +# +# Catalog: mail-catalog.conf (MAIL_CATALOG=… to override) +# Covers firefly (taler.net, gnunet.org) and pixel (taler-systems.com, …). +# +# Outside-only. Phase: mail +# +set -euo pipefail +ROOT=$(cd "$(dirname "$0")" && pwd) +# shellcheck source=lib.sh +source "$ROOT/lib.sh" + +set_area mail +section "mail · MX / SMTP / IMAP / SPF / DMARC (outside-in)" + +CATALOG="${MAIL_CATALOG:-$ROOT/mail-catalog.conf}" +PORT_TIMEOUT="${MAIL_PORT_TIMEOUT:-4}" +SMTP_TIMEOUT="${MAIL_SMTP_TIMEOUT:-10}" + +if [ ! -f "$CATALOG" ]; then + fail "catalog" "missing $CATALOG" + exit 1 +fi + +# dig or host fallback +dns_mx() { + local d="$1" + if command -v dig >/dev/null 2>&1; then + dig +short +time=3 +tries=2 MX "$d" 2>/dev/null | awk '{print tolower($2)}' | sed 's/\.$//' + else + host -t MX "$d" 2>/dev/null | awk -F'in mail is |has address ' '/mail is/{print tolower($NF)}' | sed 's/\.$//' + fi +} + +dns_a() { + local h="$1" + if command -v dig >/dev/null 2>&1; then + dig +short +time=3 +tries=2 A "$h" 2>/dev/null | grep -E '^[0-9.]+$' || true + dig +short +time=3 +tries=2 AAAA "$h" 2>/dev/null | grep -E ':' || true + else + getent ahosts "$h" 2>/dev/null | awk '{print $1}' | sort -u + fi +} + +dns_txt() { + local name="$1" + if command -v dig >/dev/null 2>&1; then + dig +short +time=3 +tries=2 TXT "$name" 2>/dev/null | tr -d '"' + else + host -t TXT "$name" 2>/dev/null | sed 's/.*"\(.*\)"/\1/' + fi +} + +tcp_open() { + local h="$1" p="$2" + if command -v timeout >/dev/null 2>&1; then + timeout "$PORT_TIMEOUT" bash -c "echo >/dev/tcp/${h}/${p}" 2>/dev/null + else + bash -c "echo >/dev/tcp/${h}/${p}" 2>/dev/null + fi +} + +# SMTP: read banner first, then EHLO (avoids "protocol synchronization") +smtp_probe() { + local host="$1" port="$2" + MAIL_HOST="$host" MAIL_PORT="$port" MAIL_TO="${SMTP_TIMEOUT}" python3 - <<'PY' 2>/dev/null +import os, socket, sys +host = os.environ["MAIL_HOST"] +port = int(os.environ["MAIL_PORT"]) +to = float(os.environ.get("MAIL_TO", "10")) +try: + s = socket.create_connection((host, port), to) + s.settimeout(to) + banner = s.recv(1024).decode("utf-8", "replace").strip().split("\n")[0] + if not banner.startswith("220"): + print(f"bad_banner={banner[:80]}") + sys.exit(1) + s.sendall(b"EHLO taler-monitoring.invalid\r\n") + data = b"" + while True: + chunk = s.recv(4096) + if not chunk: + break + data += chunk + if b"\n" in chunk and (data.endswith(b"\r\n") or len(data) > 8000): + # multi-line 250-… ends with 250 space + lines = data.decode("utf-8", "replace").splitlines() + if any(l.startswith("250 ") for l in lines): + break + if any(l.startswith("5") for l in lines[:3]): + break + text = data.decode("utf-8", "replace") + s.sendall(b"QUIT\r\n") + try: + s.recv(256) + except Exception: + pass + s.close() + starttls = "starttls" if "STARTTLS" in text.upper() else "no_starttls" + print(f"banner={banner[:60]} · {starttls}") + sys.exit(0) +except Exception as e: + print(f"err={e}") + sys.exit(1) +PY +} + +# IMAP unencrypted greeting on 143, or just TCP on 993 (TLS) +imap_probe() { + local host="$1" port="$2" + if [ "$port" = "993" ] || [ "$port" = "995" ]; then + if tcp_open "$host" "$port"; then + echo "tcp_open tls_port=$port" + return 0 + fi + return 1 + fi + MAIL_HOST="$host" MAIL_PORT="$port" MAIL_TO="${SMTP_TIMEOUT}" python3 - <<'PY' 2>/dev/null +import os, socket, sys +host = os.environ["MAIL_HOST"] +port = int(os.environ["MAIL_PORT"]) +to = float(os.environ.get("MAIL_TO", "10")) +try: + s = socket.create_connection((host, port), to) + s.settimeout(to) + banner = s.recv(1024).decode("utf-8", "replace").strip().split("\n")[0] + s.sendall(b"a001 LOGOUT\r\n") + try: + s.recv(256) + except Exception: + pass + s.close() + if banner.upper().startswith("* OK") or "IMAP" in banner.upper(): + print(f"banner={banner[:70]}") + sys.exit(0) + print(f"unexpected={banner[:70]}") + sys.exit(1) +except Exception as e: + print(f"err={e}") + sys.exit(1) +PY +} + +info "catalog" "$CATALOG" + +# Track probed hosts to avoid duplicate SMTP checks +declare -A HOST_DONE=() + +while IFS= read -r line || [ -n "$line" ]; do + line=${line%%#*} + line=$(echo "$line" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + [ -z "$line" ] && continue + # shellcheck disable=SC2086 + set -- $line + domain=$1 + expect_mx=${2:-} + mail_hosts=${3:-} + smtp_ports=${4:-25,465,587} + imap_ports=${5:-143,993} + label=${6:-$domain} + + set_group "$label" + info "domain" "$domain · expected_mx=$expect_mx · hosts=$mail_hosts" + + # --- MX --- + mapfile -t mx_hosts < <(dns_mx "$domain" | sed '/^$/d') + if [ "${#mx_hosts[@]}" -eq 0 ]; then + fail "mx" "$domain has no MX records" + else + ok "mx" "$domain MX → ${mx_hosts[*]}" + # expected MX match (suffix / exact) + if [ -n "$expect_mx" ]; then + matched=0 + IFS=',' read -ra want_list <<<"$expect_mx" + for w in "${want_list[@]}"; do + w=$(echo "$w" | tr '[:upper:]' '[:lower:]' | sed 's/\.$//') + for m in "${mx_hosts[@]}"; do + m=$(echo "$m" | tr '[:upper:]' '[:lower:]') + case "$m" in + "$w"|"$w".*|*."$w") matched=1; break ;; + esac + [ "$m" = "$w" ] && matched=1 + done + [ "$matched" = "1" ] && break + done + if [ "$matched" = "1" ]; then + ok "mx expected" "$domain MX matches catalog ($expect_mx)" + else + fail "mx expected" "$domain MX ${mx_hosts[*]} · want one of: $expect_mx" + fi + fi + fi + + # --- SPF / DMARC --- + spf=$(dns_txt "$domain" | tr '\n' ' ') + if echo "$spf" | grep -qi 'v=spf1'; then + ok "spf" "$domain has SPF" + else + warn "spf" "$domain no SPF TXT (v=spf1)" + fi + dmarc=$(dns_txt "_dmarc.$domain" | tr '\n' ' ') + if echo "$dmarc" | grep -qi 'v=dmarc1'; then + ok "dmarc" "$domain has DMARC" + else + warn "dmarc" "$domain no DMARC at _dmarc.$domain" + fi + + # --- mail hosts: DNS + ports + banners --- + IFS=',' read -ra hosts <<<"$mail_hosts" + for h in "${hosts[@]}"; do + h=$(echo "$h" | tr '[:upper:]' '[:lower:]' | sed 's/\.$//;s/^[[:space:]]*//;s/[[:space:]]*$//') + [ -z "$h" ] && continue + + addrs=$(dns_a "$h" | tr '\n' ' ') + if [ -z "${addrs// }" ]; then + fail "dns" "$h does not resolve (A/AAAA)" + continue + fi + ok "dns" "$h → $addrs" + + # skip full protocol re-probe if already done + if [ "${HOST_DONE[$h]:-}" = "1" ]; then + info "host" "$h already probed this run" + continue + fi + HOST_DONE[$h]=1 + + IFS=',' read -ra sports <<<"$smtp_ports" + for p in "${sports[@]}"; do + p=${p// /} + [ -z "$p" ] && continue + if ! tcp_open "$h" "$p"; then + # 587 optional on pixel + case "$p" in + 587) warn "smtp port" "$h:$p closed/filtered (submission)" ;; + *) fail "smtp port" "$h:$p closed/filtered" ;; + esac + continue + fi + case "$p" in + 465) + ok "smtp port" "$h:$p open (SMTPS)" + ;; + 25|587) + if detail=$(smtp_probe "$h" "$p"); then + ok "smtp" "$h:$p $detail" + else + # port open but banner failed — still ERROR for 25 + if [ "$p" = "25" ]; then + fail "smtp" "$h:$p open but SMTP handshake failed · $detail" + else + warn "smtp" "$h:$p open but handshake failed · $detail" + fi + fi + ;; + *) + ok "smtp port" "$h:$p open" + ;; + esac + done + + IFS=',' read -ra iports <<<"$imap_ports" + for p in "${iports[@]}"; do + p=${p// /} + [ -z "$p" ] && continue + if ! tcp_open "$h" "$p"; then + fail "imap port" "$h:$p closed/filtered" + continue + fi + case "$p" in + 993|995) + ok "imap port" "$h:$p open (TLS)" + ;; + 143|110) + if detail=$(imap_probe "$h" "$p"); then + ok "imap" "$h:$p $detail" + else + warn "imap" "$h:$p open but greeting failed · $detail" + fi + ;; + *) + ok "imap port" "$h:$p open" + ;; + esac + done + done +done <"$CATALOG" + +info "hint" "firefly = taler.net/gnunet.org MX; pixel = taler-systems.com (mail.anastasis.lu / mail.taler-systems.com)" +exit 0 diff --git a/host-agent/README.md b/host-agent/README.md index 7390860..71a1198 100644 --- a/host-agent/README.md +++ b/host-agent/README.md @@ -127,6 +127,8 @@ Units: | `taler-monitoring-surface.service` | → `/taler-monitoring-surface*` (taler only) | | `taler-monitoring-mattermost.timer` | every **1h** | | `taler-monitoring-mattermost.service` | → `/taler-monitoring-mattermost*` (mattermost.taler.net) | +| `taler-monitoring-mail.timer` | every **4h** | +| `taler-monitoring-mail.service` | → `/taler-monitoring-mail*` (firefly + pixel MX/SMTP/IMAP) | | `taler-monitoring-aptdeploy.timer` | every **4h** | | `taler-monitoring-aptdeploy.service` | → `/taler-monitoring-aptdeploy*` (taler only) | diff --git a/host-agent/install-host-agent.sh b/host-agent/install-host-agent.sh index f28c21f..2a1fb93 100755 --- a/host-agent/install-host-agent.sh +++ b/host-agent/install-host-agent.sh @@ -64,6 +64,8 @@ install_local() { install -m 644 "$ROOT/taler-monitoring-aptdeploy.timer" "$home_unit/" install -m 644 "$ROOT/taler-monitoring-mattermost.service" "$home_unit/" install -m 644 "$ROOT/taler-monitoring-mattermost.timer" "$home_unit/" + install -m 644 "$ROOT/taler-monitoring-mail.service" "$home_unit/" + install -m 644 "$ROOT/taler-monitoring-mail.timer" "$home_unit/" systemctl --user daemon-reload systemctl --user enable --now taler-monitoring-hacktivism.path @@ -71,12 +73,14 @@ install_local() { systemctl --user enable --now taler-monitoring-surface.timer systemctl --user enable --now taler-monitoring-aptdeploy.timer systemctl --user enable --now taler-monitoring-mattermost.timer + systemctl --user enable --now taler-monitoring-mail.timer # initial stamp so path exists "$ROOT/touch-software-stamp.sh" systemctl --user start taler-monitoring-hacktivism.service || true systemctl --user start taler-monitoring-surface.service || true systemctl --user start taler-monitoring-aptdeploy.service || true systemctl --user start taler-monitoring-mattermost.service || true + systemctl --user start taler-monitoring-mail.service || true echo "--- status ---" systemctl --user status taler-monitoring-hacktivism.path --no-pager -l | head -15 @@ -84,13 +88,15 @@ install_local() { systemctl --user status taler-monitoring-surface.timer --no-pager -l | head -12 systemctl --user status taler-monitoring-aptdeploy.timer --no-pager -l | head -12 systemctl --user status taler-monitoring-mattermost.timer --no-pager -l | head -12 + systemctl --user status taler-monitoring-mail.timer --no-pager -l | head -12 systemctl --user list-timers --all | grep taler-monitoring || true - echo "OK host-agent (hacktivism 4h + surface 1h + aptdeploy 4h + mattermost 1h)" + echo "OK host-agent (hacktivism 4h + surface 1h + aptdeploy 4h + mattermost 1h + mail 4h)" echo "suite: $mon" echo "manual: systemctl --user start taler-monitoring-hacktivism.service" echo "manual surface: systemctl --user start taler-monitoring-surface.service" echo "manual aptdeploy: systemctl --user start taler-monitoring-aptdeploy.service" echo "manual mattermost: systemctl --user start taler-monitoring-mattermost.service" + echo "manual mail: systemctl --user start taler-monitoring-mail.service" echo "after upgrades: $ROOT/touch-software-stamp.sh" } diff --git a/host-agent/run-mail-monitoring.sh b/host-agent/run-mail-monitoring.sh new file mode 100755 index 0000000..b939c28 --- /dev/null +++ b/host-agent/run-mail-monitoring.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# run-mail-monitoring.sh — mail MX/SMTP/IMAP (firefly + pixel, …) → public HTML +# Public only on taler.hacktivism.ch: +# https://taler.hacktivism.ch/taler-monitoring-mail/ +# https://taler.hacktivism.ch/taler-monitoring-mail_err/ +# +set -uo pipefail +AGENT_DIR=$(cd "$(dirname "$0")" && pwd) + +export AGENT_LABEL="${AGENT_LABEL:-mail-host-agent}" +export STATE_NAME="${STATE_NAME:-taler-mail-monitoring}" +export TALER_DOMAIN="${TALER_DOMAIN:-hacktivism.ch}" +export INSIDE_PODMAN=0 +export LOCAL_STACK=0 +export SKIP_SSH=1 +export INSIDE_MODE="${INSIDE_MODE:-none}" +export CONTINUE_ON_ERROR="${CONTINUE_ON_ERROR:-1}" +export RUN_TIMEOUT="${RUN_TIMEOUT:-600}" +export PHASES="${PHASES:-mail monpages}" +export MON_HOSTS="${MON_HOSTS:-taler.hacktivism.ch}" +export HTML_OUT="${HTML_OUT:-$HOME/monitoring-sites-staging}" +export DEPLOY_WWW_ROOT="${DEPLOY_WWW_ROOT:-/var/www/monitoring-sites}" + +export HTML_OK_DIR="taler-monitoring-mail" +export HTML_ERR_DIR="taler-monitoring-mail_err" +export HTML_URL_OK="/taler-monitoring-mail/" +export HTML_URL_ERR="/taler-monitoring-mail_err/" +export PAGE_LABEL="taler-monitoring-mail" + +export APT_DEPLOY_ENSURE=0 + +exec bash "$AGENT_DIR/run-host-report.sh" "$@" diff --git a/host-agent/taler-monitoring-mail.service b/host-agent/taler-monitoring-mail.service new file mode 100644 index 0000000..3446e91 --- /dev/null +++ b/host-agent/taler-monitoring-mail.service @@ -0,0 +1,18 @@ +[Unit] +Description=Taler monitoring mail (firefly/pixel MX SMTP IMAP) +Documentation=file:%h/src/taler-monitoring/host-agent/README.md +After=network-online.target +Wants=network-online.target + +[Service] +Type=oneshot +Environment=PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin +Environment=CONTINUE_ON_ERROR=1 +Environment=RUN_TIMEOUT=600 +WorkingDirectory=%h/src/taler-monitoring +ExecStart=%h/src/taler-monitoring/host-agent/run-mail-monitoring.sh +Nice=10 +TimeoutStartSec=20min + +[Install] +WantedBy=default.target diff --git a/host-agent/taler-monitoring-mail.timer b/host-agent/taler-monitoring-mail.timer new file mode 100644 index 0000000..a0f03c8 --- /dev/null +++ b/host-agent/taler-monitoring-mail.timer @@ -0,0 +1,14 @@ +[Unit] +Description=Periodic taler-monitoring mail (MX/SMTP/IMAP) +Documentation=file:%h/src/taler-monitoring/host-agent/README.md + +[Timer] +OnBootSec=30min +OnUnitActiveSec=4h +AccuracySec=5min +Persistent=true +RandomizedDelaySec=10min +Unit=taler-monitoring-mail.service + +[Install] +WantedBy=timers.target diff --git a/mail-catalog.conf b/mail-catalog.conf new file mode 100644 index 0000000..69bc819 --- /dev/null +++ b/mail-catalog.conf @@ -0,0 +1,22 @@ +# mail-catalog.conf — domains and mail hosts for phase `mail` +# +# Format (whitespace-separated; # comments): +# domain expected_mx (comma) mail_hosts (comma) smtp_ports imap_ports label +# +# - expected_mx: MX exchange hostnames that should appear (any match = OK if multiple) +# - mail_hosts: servers to probe for SMTP/IMAP (A/AAAA + ports + optional banner) +# - ports: comma-separated; empty = skip that protocol family +# +# Override path: MAIL_CATALOG=/path/to/file +# +# GNU Taler / GNUnet mail (firefly) + TSA (pixel / mail.anastasis.lu) + +# --- firefly (primary for taler.net + gnunet.org) --- +taler.net firefly.gnunet.org firefly.gnunet.org 25,465,587 143,993 taler-net +gnunet.org firefly.gnunet.org firefly.gnunet.org 25,465,587 143,993 gnunet + +# --- taler-systems.com / pixel (MX mail.anastasis.lu → pixel) --- +taler-systems.com mail.anastasis.lu,pixel.taler-systems.com pixel.taler-systems.com,mail.taler-systems.com,mail.anastasis.lu 25,465 143,993 tsa-pixel + +# Optional related (same pixel path; keep expected MX loose) +# anastasis.lu mail.anastasis.lu mail.anastasis.lu,pixel.taler-systems.com 25,465 143,993 anastasis diff --git a/site-gen/caddy-monitoring-handles.snippet b/site-gen/caddy-monitoring-handles.snippet index 54cca0c..fedec82 100644 --- a/site-gen/caddy-monitoring-handles.snippet +++ b/site-gen/caddy-monitoring-handles.snippet @@ -10,6 +10,7 @@ # /taler-monitoring-surface* → taler.hacktivism.ch only # /taler-monitoring-aptdeploy* → taler.hacktivism.ch only # /taler-monitoring-mattermost* → taler.hacktivism.ch only +# /taler-monitoring-mail* → taler.hacktivism.ch only # --- only inside taler.hacktivism.ch { ... } --- handle /taler-monitoring-surface_err { @@ -56,6 +57,21 @@ file_server } + handle /taler-monitoring-mail_err { + redir /taler-monitoring-mail_err/ 302 + } + handle /taler-monitoring-mail_err/ { + root * /var/www/monitoring-sites/taler.hacktivism.ch/taler-monitoring-mail_err + file_server + } + handle /taler-monitoring-mail { + redir /taler-monitoring-mail/ 302 + } + handle /taler-monitoring-mail/ { + root * /var/www/monitoring-sites/taler.hacktivism.ch/taler-monitoring-mail + file_server + } + # --- bank + exchange + taler (each site block) --- handle /monitoring_err { redir /monitoring_err/ 302 diff --git a/taler-monitoring.sh b/taler-monitoring.sh index 13d03b5..24d77e1 100755 --- a/taler-monitoring.sh +++ b/taler-monitoring.sh @@ -41,6 +41,7 @@ Phases: ecosystem hosts (taler.net, gnunet.org, taler-systems.com, mattermost, …) or -d DOMAIN → that domain’s surface; port/protocol/TLS/CVE (OSV) mattermost Mattermost chat health (default mattermost.taler.net; SPA + /api/v4/system/ping) + mail MX/SMTP/IMAP for Taler mail (firefly, pixel/TSA, catalogued domains) monpages public monitoring HTML via FQDN (HTTP 200 + suite page, not code 21) uses MON_HOSTS + HTML_URL_OK (same as host-agent); v1.3.1+ all urls + inside + versions + sanity + e2e (SSH phases only on koopa) @@ -113,6 +114,7 @@ Remote surface / ecosystem (explicit only — never default): ./taler-monitoring.sh -d hacktivism.ch surface ./taler-monitoring.sh -d lefrancpaysan.ch surface ./taler-monitoring.sh mattermost # mattermost.taler.net chat health + ./taler-monitoring.sh mail # firefly + pixel MX/SMTP/IMAP SPA pin after selfbuild: EXPECT_WEBUI_VERSION=1.6.11 EXPECT_WEBUI_OVERLAY=selfbuild-v1.6.11 \\ @@ -181,7 +183,7 @@ while [ $# -gt 0 ]; do CURRENCY_OVERRIDE="$2"; shift 2 ;; --no-probe) NO_PROBE=1; shift ;; - urls|inside|versions|sanity|server|e2e|ladder|goa-ladder|auth401|aptdeploy|apt-deploy|apt_src|surface|ecosystem|mattermost|monpages|pages|all|full) PHASES+=("$1"); shift ;; + urls|inside|versions|sanity|server|e2e|ladder|goa-ladder|auth401|aptdeploy|apt-deploy|apt_src|surface|ecosystem|mattermost|mail|monpages|pages|all|full) PHASES+=("$1"); shift ;; *) # bare domain shorthand: ./taler-monitoring.sh taler.net if [[ "$1" == *.* && "$1" != *://* && "$1" != -* ]]; then @@ -347,6 +349,7 @@ if [ "${PROGRESS_TOTAL:-0}" = "0" ] || [ -z "${PROGRESS_TOTAL:-}" ]; then surface|ecosystem) _pt=$((_pt + 80)) ;; monpages|pages) _pt=$((_pt + 30)) ;; mattermost) _pt=$((_pt + 25)) ;; + mail) _pt=$((_pt + 40)) ;; esac done set_progress_total "$_pt" @@ -465,6 +468,7 @@ for p in "${PHASES[@]}"; do aptdeploy|apt-deploy|apt_src) run_phase aptdeploy "$ROOT/check_apt_deploy.sh" || ec=1 ;; surface|ecosystem) run_phase surface "$ROOT/check_surface.sh" || ec=1 ;; mattermost) run_phase mattermost "$ROOT/check_mattermost.sh" || ec=1 ;; + mail) run_phase mail "$ROOT/check_mail.sh" || ec=1 ;; monpages|pages) run_phase monpages "$ROOT/check_monitoring_pages.sh" || ec=1 ;; esac done