Add HTTPS management console and response planning
This commit is contained in:
parent
a56d72edd6
commit
a7129e5666
16 changed files with 927 additions and 160 deletions
|
|
@ -89,12 +89,20 @@ def main(argv: list[str] | None = None) -> int:
|
|||
po.add_argument("action", nargs="?", default="check", choices=["check"],
|
||||
help="posture action (default: check)")
|
||||
po.add_argument("--json", action="store_true", help="emit findings as JSON")
|
||||
rsp = sub.add_parser("respond",
|
||||
help="build dry-run response plans for incidents")
|
||||
rsp.add_argument("action", nargs="?", default="plan", choices=["plan"],
|
||||
help="response action (default: plan)")
|
||||
rsp.add_argument("id", nargs="?", help="incident id")
|
||||
rsp.add_argument("--json", action="store_true", help="emit plan as JSON")
|
||||
wd = sub.add_parser("watchdog",
|
||||
help="poll a remote dashboard and push if Sentinel is silent")
|
||||
wd.add_argument("--url", required=True, help="dashboard base URL")
|
||||
wd.add_argument("--token", default="", help="dashboard bearer token")
|
||||
wd.add_argument("--max-age", type=int, default=120,
|
||||
help="heartbeat staleness threshold (seconds)")
|
||||
wd.add_argument("--insecure-tls", action="store_true",
|
||||
help="allow self-signed/untrusted dashboard certificates")
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
cfg = Config.load(args.config)
|
||||
|
|
@ -138,15 +146,20 @@ def main(argv: list[str] | None = None) -> int:
|
|||
return _cmd_incident(cfg, args.action, args.id, args.json)
|
||||
if args.cmd == "posture":
|
||||
return _cmd_posture(cfg, args.json)
|
||||
if args.cmd == "respond":
|
||||
return _cmd_respond(cfg, args.action, args.id, args.json)
|
||||
if args.cmd == "watchdog":
|
||||
return _cmd_watchdog(cfg, args.url, args.token, args.max_age)
|
||||
return _cmd_watchdog(cfg, args.url, args.token, args.max_age,
|
||||
not args.insecure_tls)
|
||||
return _cmd_run(cfg)
|
||||
|
||||
|
||||
def _cmd_watchdog(cfg: Config, url: str, token: str, max_age: int) -> int:
|
||||
def _cmd_watchdog(cfg: Config, url: str, token: str, max_age: int,
|
||||
verify_tls: bool = True) -> int:
|
||||
from . import notify
|
||||
from .selfprotect import poll_status, watchdog_verdict
|
||||
ok, msg = watchdog_verdict(poll_status(url, token), max_age)
|
||||
ok, msg = watchdog_verdict(poll_status(url, token, verify_tls=verify_tls),
|
||||
max_age)
|
||||
print(("OK: " if ok else "ALERT: ") + msg)
|
||||
if not ok:
|
||||
n = notify.Notification(
|
||||
|
|
@ -328,6 +341,42 @@ def _cmd_posture(cfg: Config, as_json: bool) -> int:
|
|||
return 1
|
||||
|
||||
|
||||
def _cmd_respond(cfg: Config, action: str, iid: str | None, as_json: bool) -> int:
|
||||
import json
|
||||
|
||||
from . import respond
|
||||
|
||||
if action != "plan":
|
||||
print(f"error: unsupported respond action: {action}", file=sys.stderr)
|
||||
return 2
|
||||
if not iid:
|
||||
print("error: 'respond plan' needs an incident id "
|
||||
"(see 'incident list')", file=sys.stderr)
|
||||
return 2
|
||||
bundle = respond.load_bundle(cfg, iid)
|
||||
if bundle is None:
|
||||
print(f"error: no such incident: {iid}", file=sys.stderr)
|
||||
return 1
|
||||
plan = respond.build_plan(bundle, cfg)
|
||||
if as_json:
|
||||
print(json.dumps(plan, indent=2))
|
||||
return 0
|
||||
|
||||
summary = plan["summary"]
|
||||
print(f"Response plan {plan['plan_id']} [{summary['severity']}]")
|
||||
print(f" incident: {plan['incident_id']}")
|
||||
print(f" mode: {plan['mode']} (no commands executed)")
|
||||
print(f" signatures: {', '.join(summary['signatures']) or '—'}")
|
||||
print(f" snapshots: {summary['snapshot_count']}")
|
||||
print(" actions:")
|
||||
for a in plan["actions"]:
|
||||
cmd = " ".join(a["command"])
|
||||
print(f" {a['id']} [{a['risk']}] {a['title']}")
|
||||
print(f" {cmd}")
|
||||
print(f" reason: {a['reason']}")
|
||||
return 0
|
||||
|
||||
|
||||
def _cmd_fim_check(cfg: Config, packages: bool) -> int:
|
||||
from . import fim
|
||||
sentinel = Sentinel(cfg)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue