Sysadmin — dag-dagelijks
1. Maandagochtend — wat is er over het weekend veranderd
In het dashboard
- Sidebar → Audit-log
- Filter: laatste 72u + groepeer op event_type
- Klik elke drift_event rij voor operator + reden
- Voor onverklaarde drift: agent → Inventaris → Restore
Klikpad:
/audit-log→ filtercreated_at >= now() - INTERVAL '72 hours'→ sort opevent_type/agents→ “Drift events” panel — alle config-hashes die buiten een EAT-window veranderden- Per verdachte agent:
/agents/<id> → Kernel tab → Reboot history— wie heeft gereboot, EAT-driven of manueel
Equivalent in één SQL-query:
Of via API (geavanceerd — voor automatisering)
SELECT a.hostname, l.event_type, l.event_data->>'reason' AS reason, u.email AS actor, l.created_at FROM audit_log l LEFT JOIN agents a ON a.id = l.agent_id LEFT JOIN users u ON u.id = l.user_id WHERE l.tenant_id = $1::UUID AND l.created_at >= NOW() - INTERVAL '72 hours' ORDER BY l.created_at DESC;Wat je hierna typisch doet: voor elke drift_event zonder bijhorende
emergency_token_issued-rij → checken of het een legitieme wijziging
was. Zo niet → /agents/<id> → Inventory tab → Config hashes → Restore
of het hostje quarantainen via IsolateNetwork EAT.
2. Fleet-wide kernel-update zonder downtime
In het dashboard
- Sidebar → Kernel CVE’s → tab Actieve batches
- Knop ‘Nieuwe batch’ → kies tag-selector + target kernel + reboot-strategie
- TOTP invullen → Start canary
- Volg canary → primary → completed in dezelfde view
Stel: USN-2026-1234 raakt 80 Ubuntu-hosts in productie. Target kernel
is 6.8.0-49.49.
Of via API (geavanceerd — voor automatisering)
curl -X POST https://app.monsys.ai/api/v1/kernel-updates/batches \ -H "Authorization: Bearer $TOKEN" \ -H "X-TOTP-Code: 123456" \ -H "Content-Type: application/json" \ -d '{ "title": "USN-2026-1234 — kernel 6.8.0-49.49", "target_kernel": "6.8.0-49.49", "package_manager": "apt", "reboot_strategy": "auto-at-window", "selector_kind": "tag", "selector_value": {"tag":"production"}, "maintenance_window_id": "8c34…" }'Wat er gebeurt achter de schermen:
- Hub kiest 3 canary-hosts (10% van 80 = 8, capped op 3)
- Voor elke canary: Ed25519-EAT signed, gepushed via WebSocket
- Agent shell out naar
/usr/local/sbin/monsys-kernel-update(alleen via sudoers-rule die deze ene wrapper toestaat) - Wrapper installeert kernel + headers, draait
update-grub, zet/var/run/reboot-required, en — als binnen het maintenance-window —shutdown -r +5 - Hub detecteert
running_releaseflip bij volgende ingest → markeert faserebooted_new - Pas wanneer alle 3 canary op rebooted_new staan → primary fires (77 EATs in één tick)
- Eén canary die
phase='failed'rapporteert → batch aborted, geen primary EATs verstuurd - Canary die binnen 2u niet beweegt → automatisch aborted (“canary timeout”)
Status volgen: /kernel-cves → Actieve batches tab. Of:
curl https://app.monsys.ai/api/v1/kernel-updates/batches/<id> \ -H "Authorization: Bearer $TOKEN" | jq .members3. Eén applicatie is traag — waar kijk je
In het dashboard
- Sidebar → Apps → klik op host web-03 → tab Metrics
- Tab Processes voor top CPU/RAM verbruikers
- Tab Topology voor blast-radius afhankelijkheden
- Tab Logs voor recente WARN/ERROR van de agent
Klikpad voor host web-03:
/agents/web-03 → Metrics tab— CPU/mem/load over laatste 6u/agents/web-03 → Processes tab— top 10 CPU/RAM-verbruikers/agents/web-03 → Topology tab— welke andere agents/apps hangen eraan vast (afhankelijkheidsgraaf)/agents/web-03 → Containers tab—restart_countper container/agents/web-03 → Logs tab— laatste 200 WARN/ERROR-regels van de agent zelf (geen volledige syslog — die staan in Loki)/alertsfilteragent=web-03 AND is_resolved=false
Veelvoorkomende root causes:
| Symptoom | Eerst checken |
|---|---|
| CPU 100% gedurende uren | Processes tab — welke PID? Daarna /agents/web-03 → Logs |
| Memory langzaam vol | Capacity tab — RAM trend + swap-gebruik |
| App reageert niet | Containers tab — restart_count + Inventory → systemd_services voor service state |
| DB-fouten | Topology tab — is de DB-agent stale? last_seen_at check |
4. Auto-reboot enkel in het weekend
In het dashboard
- Sidebar → Settings → Maintenance windows → ‘Nieuw venster’
- Configureer recurrence: zaterdag 02:00-06:00 met tag-target ‘production’
- Bij kernel-batch creation: reboot_strategy = auto-at-window
- Wrapper runt shutdown -r +5 alleen binnen actief venster
Definieer eerst een maintenance window:
Of via API (geavanceerd — voor automatisering)
curl -X POST https://app.monsys.ai/api/v1/maintenance-windows \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Weekend reboot window", "starts_at": "2026-05-23T02:00:00Z", "ends_at": "2026-05-23T06:00:00Z", "recurrence": "weekly", "target_type": "tag", "target_filter": {"tag":"production"}, "silence_categories": [] }'Bij kernel-update batch creation: zet reboot_strategy=auto-at-window.
De wrapper monsys-kernel-update doet shutdown -r +5 alleen wanneer
de host binnen een actief window valt; daarbuiten blijft het bij
“reboot required” en valt het op de operator om te bevestigen.
5. Config drift na een migratie
In het dashboard
- Sidebar → Agents → klik host → tab Inventory → sectie Config hashes
- Tabel toont sha256 huidig vs baseline per gewatcht pad
- Per drift event: ‘Accept as baseline’ OF ‘Investigate’
- Drift zonder linked_eat_id = onverklaard, vereist actie
Per agent zie je sha256 van alle gewatchte paden (default:
/etc/passwd, /etc/shadow, /etc/sudoers, /etc/ssh/sshd_config,
- 4 andere).
Of via API (geavanceerd — voor automatisering)
curl https://app.monsys.ai/api/v1/agents/<id>/drift-events?limit=50 \ -H "Authorization: Bearer $TOKEN"Voor elke drift-event toon je:
path— welk bestandprev_sha256/new_sha256detected_atlinked_eat_id—nullbetekent: niemand heeft hier een EAT voor geautoriseerd, dit is onverklaarde drift
Workflow:
- Als het een legitieme wijziging was (manueel patchen, migratie):
POST /api/v1/agents/<id>/drift-events/<id>/accept— baseline bumpt - Als het verdacht is:
POST /api/v1/agents/<id>/emergencymet actionIsolateNetwork+ TOTP, dan handmatig inspecteren
6. Vind alle Ubuntu 20.04 servers (end-of-standard-support 2025-04)
In het dashboard
- Sidebar → Agents → filter os_name=Ubuntu + os_version~20.04
- Bulk-select de getoonde hosts
- Knop ‘Add tag’ → tag = ‘eol-2025’
- Sidebar → Settings → Alert rules → nieuw met threshold-datum 2025-04-30
Of via API (geavanceerd — voor automatisering)
curl 'https://app.monsys.ai/api/v1/agents?os_name=Ubuntu&os_version_like=20.04' \ -H "Authorization: Bearer $TOKEN" | jq '.[] | .hostname'Of in SQL:
SELECT hostname, ip_addresses, last_seen_at FROM agents WHERE tenant_id = $1::UUID AND os_name = 'Ubuntu' AND os_version LIKE '20.04%' AND is_active = true ORDER BY last_seen_at DESC;Daarna typisch: tag deze hosts met eol-2025 via bulk-tagging in
/groups, en bouw een SLA-alert die fires zodra er na 2025-04-30 nog
agents in die tag zitten.
7. “Waarom kreeg ik 438 CPU-alerts vannacht?”
In het dashboard
- Sidebar → Alerts → tab ‘Grouped by title’
- Sorteer descending op count
- Klik op grootste groep — bevat de title een waarde?
- Settings → Alert rules → bewerk de regel zodat waarde in description komt
Sinds de alert-storm fix (sessie 17) doet InsertAlert 30-minuten dedup
per (tenant, agent, category, title). Krijg je toch storm: meest
waarschijnlijk een veranderende title (bv. count in titel) die de
dedup-key elke keer anders maakt.
Quick check:
Of via API (geavanceerd — voor automatisering)
SELECT title, COUNT(*), MIN(created_at), MAX(created_at) FROM alerts WHERE tenant_id = $1::UUID AND created_at >= NOW() - INTERVAL '24 hours' GROUP BY title ORDER BY 2 DESC LIMIT 10;Als één title 100+ keer voorkomt → bug. Als 100 unieke titles 1× elk →
de title bevat een waarde (count, percentage, timestamp). Fix de
emittende worker om de waarde naar description te verhuizen.
8. Werknemer vertrokken — wat had die persoon allemaal
In het dashboard
- Sidebar → Identity surface → zoek alice@
- Bekijk gekoppelde systemen (hosts, SSH keys, Copilot/OpenAI seats)
- Per systeem ‘Revoke’ knop OF één playbook EAT ‘revoke-user’ over alle hosts
- Audit-log toont ‘identity_revoked’ per uitgevoerde revocatie
/identity/surface → search "alice@…" toont:
- Dashboard-account (rollen per tenant)
- Lokale users op welke hosts (
inventory_users.username='alice') - SSH-keys waar publickey-fingerprint matched
- GitHub Copilot seat (als Copilot Audit module aan staat)
- OpenAI org-member (als OpenAI Audit module aan staat)
- Sudo-rechten (
inventory_sudo_rules.who='alice')
Bulk-revoke vanuit de Identity-surface page: ofwel per systeem (POST /api/v1/identity/persons/<id>/revoke), ofwel als één RunPlaybook EAT
die alle hosts in één keer afhandelt.
9. On-call rotation timezone-aware
In het dashboard
- Sidebar → Settings → On-call rotations → ‘Nieuwe rotation’
- Voor team eu-ops: shifts ma-vr 09:00-18:00 Europe/Brussels
- Voeg buddy fallback toe voor buiten kantoor
- NotifyWorker resolveert per alert welke shift open is en routeert naar ntfy
Of via API (geavanceerd — voor automatisering)
-- Voor team eu-ops, 09:00-18:00 Brussel-tijd, ma-vr, met fallback naar buddyINSERT INTO oncall_shifts (tenant_id, group_id, person_id, weekday, start_time, end_time, timezone)VALUES ($1, $2, $alice, 1, '09:00', '18:00', 'Europe/Brussels'), ($1, $2, $alice, 2, '09:00', '18:00', 'Europe/Brussels'), -- … en ($1, $2, $bob, 1, '18:00', '09:00', 'Europe/Brussels'); -- buddyNotifyWorker resolveert per alert welke shift open is op
alerts.created_at, en routeert naar de juiste ntfy-topic + e-mail.
10. Backups van productie-DBs — werken ze echt nog
In het dashboard
- Sidebar → Inventaris → tab Backups → filter tag ‘production-db’
- Sorteer ‘Last successful’ ascending
- Per stale host (>25u): klik ‘Create alert rule’
- Threshold = 25u + severity = critical
Of via API (geavanceerd — voor automatisering)
SELECT a.hostname, b.tool AS backup_tool, b.destination AS target, b.last_successful_run AS last_ok, NOW() - b.last_successful_run AS age, b.last_failure_message FROM backup_configs b JOIN agents a ON a.id = b.agent_id WHERE b.tenant_id = $1::UUID AND 'production-db' = ANY(a.tags) ORDER BY b.last_successful_run NULLS FIRST;Alert-regel als age > 25h (default schedule = dagelijks):
curl -X POST https://app.monsys.ai/api/v1/alert-rules \ -H "Authorization: Bearer $TOKEN" \ -d '{ "name": "Backup stale > 25h on production-db", "tag": "production-db", "category": "backup", "metric": "backup_age_hours", "operator": ">", "threshold": 25, "severity": "critical" }'