server-monitor-manager/deploy/ochenstarik-smm-emergency
ochenstarik-ui 3851d87534
Add standalone Linux bootstrap foundation (#5)
* Add standalone Linux bootstrap foundation

* Record bootstrap foundation progress

* Add single-code Node enrollment

* Validate bootstrap release payloads

* Add managed WireGuard mesh bootstrap

* Exercise repeated systemd installation in CI

* Expose systemd smoke failure diagnostics

* Fix bootstrap os-release variable collision

* Create policy helper directory during install

* Capture systemd smoke healthcheck errors

* Report Control listener diagnostics in CI

* Capture stalled Control process diagnostics

* Set service working directories

* Run protected CA healthcheck as root

* Add local Mesh emergency recovery

* Add multi-architecture Linux system matrix

* Add provisioning job control plane

* Stabilize Debian systemd smoke files

* Add node-scoped provisioning job channel

* Add provisioning progress state machine

* Reconcile expired provisioning jobs

* Add provisioning rollback workflow

* Add redacted provisioning event history

* Add restricted provisioning preflight helper

* Persist typed provisioning preflight facts

* Add preflight desired state drift detection

* Define strict base install schema catalog

* Add safe base install plan generation

* Add pre-confirmation base install plans

* Test base install plan API flow

* Authorize confirmed provisioning execution

---------

Co-authored-by: Ochenstarik <ochenstarik@inbox.ru>
2026-07-30 21:18:39 +07:00

129 lines
4.3 KiB
Bash
Executable file

#!/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 "$@"