#!/usr/bin/env bash set -Eeuo pipefail IFS=$'\n\t' readonly PROGRAM="ochenstarik-smm-emergency" readonly STATE_DIR="/var/lib/ochenstarik-server-monitor-manager" readonly ETC_DIR="/etc/ochenstarik-server-monitor-manager" readonly MARKER="$STATE_DIR/mesh/emergency-disabled" readonly CONTROL_UNIT="ochenstarik-smm-control.service" readonly AGENT_UNIT="ochenstarik-smm-agent.service" readonly FIREWALL_UNIT="ochenstarik-smm-firewall.service" readonly WIREGUARD_UNIT="wg-quick@smm0.service" readonly NFT_FAMILY="inet" readonly NFT_TABLE="ochenstarik_smm" fail() { printf '%s: %s\n' "$PROGRAM" "$*" >&2; exit 78; } log() { printf '%s: %s\n' "$PROGRAM" "$*"; } usage() { cat <<'EOF' Local Server Monitor Manager emergency recovery Usage: ochenstarik-smm-emergency status ochenstarik-smm-emergency mesh-disable ochenstarik-smm-emergency mesh-enable ochenstarik-smm-emergency firewall-restore Commands use only Server Monitor Manager-owned units, interface and nftables table. They do not modify the host SSH service or unrelated firewall rules. EOF } require_root() { [[ ${EUID:-$(id -u)} -eq 0 ]] || fail "this action must run as root (use sudo)" } unit_state() { local unit="$1" if systemctl list-unit-files "$unit" --no-legend 2>/dev/null | grep -q "^$unit"; then systemctl is-active "$unit" 2>/dev/null || true else printf '%s\n' "not-installed" fi } show_status() { local unit for unit in "$CONTROL_UNIT" "$AGENT_UNIT" "$FIREWALL_UNIT" "$WIREGUARD_UNIT"; do printf '%s: %s\n' "$unit" "$(unit_state "$unit")" done if command -v ip >/dev/null 2>&1 && ip link show smm0 >/dev/null 2>&1; then printf '%s\n' "mesh-interface: present" else printf '%s\n' "mesh-interface: absent" fi if command -v nft >/dev/null 2>&1 && nft list table "$NFT_FAMILY" "$NFT_TABLE" >/dev/null 2>&1; then printf '%s\n' "mesh-firewall: loaded" else printf '%s\n' "mesh-firewall: absent" fi [[ -f "$MARKER" ]] && printf '%s\n' "emergency-lock: active" || printf '%s\n' "emergency-lock: inactive" printf '%s\n' "backups:" find "$STATE_DIR/bootstrap-backups" -maxdepth 1 -type f \ \( -name '*.tar.gz' -o -name '*.empty' \) -printf ' %f\n' 2>/dev/null | sort -r | head -n 10 || true } delete_project_firewall() { if command -v nft >/dev/null 2>&1; then nft delete table "$NFT_FAMILY" "$NFT_TABLE" 2>/dev/null || true fi } mesh_disable() { require_root systemctl disable --now "$WIREGUARD_UNIT" 2>/dev/null || true systemctl disable --now "$FIREWALL_UNIT" 2>/dev/null || true delete_project_firewall install -d -m 0700 "$(dirname "$MARKER")" printf '%s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" >"$MARKER" chmod 0600 "$MARKER" log "Mesh disabled locally; Control and SSH were not changed." } restore_project_firewall() { require_root [[ -f "$ETC_DIR/mesh.nft" ]] || fail "managed firewall configuration is missing" command -v nft >/dev/null 2>&1 || fail "nft is unavailable" if ! nft list table "$NFT_FAMILY" "$NFT_TABLE" >/dev/null 2>&1; then nft --check -f "$ETC_DIR/mesh.nft" fi delete_project_firewall if ! nft -f "$ETC_DIR/mesh.nft"; then systemctl disable --now "$WIREGUARD_UNIT" 2>/dev/null || true fail "managed firewall restore failed; Mesh was disabled to fail closed" fi if systemctl list-unit-files "$FIREWALL_UNIT" --no-legend 2>/dev/null | grep -q "^$FIREWALL_UNIT"; then systemctl enable "$FIREWALL_UNIT" >/dev/null fi log "Base deny-by-default Mesh firewall restored; Control must reconcile active Links." } mesh_enable() { require_root [[ -f /etc/wireguard/smm0.conf ]] || fail "WireGuard smm0 configuration is missing" if [[ -f "$ETC_DIR/mesh.nft" ]]; then restore_project_firewall fi systemctl enable "$WIREGUARD_UNIT" >/dev/null systemctl restart "$WIREGUARD_UNIT" rm -f -- "$MARKER" log "Mesh enabled locally." } main() { local action="${1:-help}" shift || true [[ $# -eq 0 ]] || fail "unexpected arguments" case "$action" in help|-h|--help) usage ;; status) show_status ;; mesh-disable) mesh_disable ;; mesh-enable) mesh_enable ;; firewall-restore) restore_project_firewall ;; *) fail "unknown action: $action" ;; esac } main "$@"