Passa al contenuto principale

Runbook — Break-glass: Tailscale down

Tipo: Emergency access procedure Severity: SEV1 (perdita accesso mgmt) RTO target: <15 minuti dall'allerta Owner: Massimo Bagnoli (m.bagnoli@asheep.it)


1. Quando attivarlo

Attivare il break-glass SOLO se:

  • Tailscale control plane è down (verifica su https://status.tailscale.com) E
  • La mgmt UI Akira (https://mgmt.akira.asheep.it raggiungibile solo via Tailscale) è unreachable E
  • SSH ai server staging/prod non risponde sulle IP private (10.0.0.0/16)

NON attivare se:

  • Tailscale è up ma il client locale è disconnesso → tailscale up risolve.
  • Solo un singolo nodo non risponde → debug normale via altri nodi nel tailnet.
  • Tailscale stessa è sotto manutenzione pianificata <30 min → attendere.

2. Procedura

Step 1 — Verifica Tailscale status

Da workstation locale:

tailscale status
tailscale ping akira-mgmt-01 # deve risolvere su 100.x.y.z (Tailscale CGNAT)

Se tailscale status mostra Logged out o Backend in state Stopped, prova prima tailscale up. Se output è normale ma i nodi Akira sono offline da >5 min, procedi al break-glass.

Step 2 — Connessione bastion SSH pubblico

SSH key-only, password disabled. Bastion IP pubblico in infra/group_vars/all/vault.yml come bastion_public_ip.

ssh -i ~/.ssh/akira_ed25519 -o ConnectTimeout=10 deploy@<bastion_public_ip>

Se la connessione fallisce:

  • Verifica che la chiave ~/.ssh/akira_ed25519 sia presente (ls -la ~/.ssh/).
  • Verifica IP pubblico: dig bastion.akira.asheep.it +short (DNS pubblico, no Tailscale).
  • Verifica Hetzner Cloud Firewall: il break-glass rule consente porta 22 dall'IP statico Massimo (83.103.x.y) — vedi infra/roles/firewall/tasks/main.yml.

Step 3 — Jump dal bastion ai server mgmt

Da dentro il bastion, usa la private network Hetzner (10.0.0.0/16):

ssh akira-mgmt-01 # ~/.ssh/config sul bastion ha già gli alias
# oppure:
ssh deploy@10.0.0.10 # IP statico interno di mgmt-01 (vedi inventory)

L'inventory Ansible infra/inventory/staging.yml ha la mappatura completa hostname → IP interno.

Step 4 — Restart container backend / servizi critici

Sul nodo mgmt-01:

# Verifica stato compose stack
sudo docker compose -f /opt/akira/docker-compose.yml ps

# Restart backend FastAPI
sudo docker compose -f /opt/akira/docker-compose.yml restart backend

# Restart agentcore-bridge se Telegram non risponde
sudo docker compose -f /opt/akira/docker-compose.yml restart agentcore-bridge

# Restart Caddy se mgmt UI down
sudo docker compose -f /opt/akira/docker-compose.yml restart caddy

Step 5 — Verifica DB primary

Da mgmt-01 verso db-01 (10.0.1.11 interno):

psql -h 10.0.1.11 -U akira_app -d akira -c "SELECT 1, now();"

Se errore:

  • Verifica db-01 raggiungibile: ping 10.0.1.11.
  • Verifica processo Postgres su db-01: ssh akira-db-01 'systemctl status postgresql'.
  • Se Postgres giù: ssh akira-db-01 'sudo systemctl restart postgresql'.
  • Verifica TimescaleDB extension: psql -c "SELECT extname, extversion FROM pg_extension WHERE extname='timescaledb';".

Step 6 — Verifica signaling layer (se SIP traffic giù)

ssh akira-sip-01 'sudo kamcmd core.uptime'
ssh akira-sip-01 'sudo kamcmd dispatcher.list'
ssh akira-rtp-01 'sudo systemctl status rtpengine'
ssh akira-fs-01 'sudo fs_cli -x "status"'

Restart selettivo:

ssh akira-sip-01 'sudo systemctl restart kamailio' # WARNING: drop chiamate attive

⚠️ Attenzione: restart Kamailio fa droppare le call attive. Usare solo se diagnosi conferma necessità.


3. Post-incidente

  1. Ripristino Tailscale: quando Tailscale torna up, verifica tailscale status da workstation e da tutti i nodi.
  2. Chiudi accesso bastion: idealmente Hetzner Cloud Firewall riapplica regole strette (bastion accessibile solo da 83.103.x.y). Vedi infra/roles/firewall/tasks/main.yml.
  3. Postmortem: redigere postmortem entro 48h se SEV1 ha causato downtime visibile clienti. Template: engineering:incident-response skill.
  4. Log audit: ogni ssh al bastion è registrato in /var/log/auth.log e shippato a Loki (Stage 1). Controllo che non ci siano accessi non autorizzati.

4. Contatti emergenza

RuoloPersonaContatto
Owner primarioMassimo Bagnolim.bagnoli@asheep.it · Telegram @massimo_asheep
UX backup / on-call alternativoFrancesco _______TBD (popolare quando definito)
Hetzner supporthttps://console.hetzner.cloud → Support ticket SEV1
Tailscale supporthttps://tailscale.com/contact/support (piano Personal Pro: response <24h)

5. Test schedulato

Cadenza: ogni trimestre (Q1, Q2, Q3, Q4).

Procedura test (in staging, mai prod):

  1. Simulare Tailscale down: sudo tailscale down sul workstation Massimo.
  2. Eseguire la procedura completa step 1→6 verso staging.
  3. Cronometrare RTO effettivo, deve essere <15 min.
  4. Documentare anomalie in docs/runbooks/_drill-log.md (file da creare al primo drill).
  5. Aggiornare runbook se procedura ha avuto attriti.

Prossimo drill schedulato: __________ (popolare al primo provisioning completato).


6. Riferimenti

  • ADR-0008 Kamailio HA Hetzner Cloud: docs/adr/0008-kamailio-ha-hetzner-cloud.md
  • Inventory Ansible: infra/inventory/staging.yml, infra/inventory/production.yml
  • Roles firewall: infra/roles/firewall/tasks/main.yml
  • DR restore PG: docs/runbooks/dr-restore-pg-timescale.md
  • Incident response skill: engineering:incident-response