Skip to main content

Setup OpenBao

1. Architecture and Security Model

1.1 Obiettivo

OpenBao viene utilizzato come sistema centralizzato per la gestione delle configurazioni e dei secret utilizzati dagli stack Docker Compose.

Gli obiettivi principali sono:

  • evitare la distribuzione manuale delle variabili tramite SSH;
  • centralizzare gestione e modifica dei secret;
  • applicare RBAC differenziato agli utenti;
  • avere versionamento tramite KV v2;
  • registrare le operazioni tramite audit;
  • distribuire automaticamente le variabili alle VM;
  • aggiornare gli stack Docker Compose quando cambiano i valori;
  • evitare che gli sviluppatori debbano accedere direttamente alle VM;
  • mantenere separata la gestione dei secret dall'orchestrazione Docker.

1.2 Architettura generale

                         ┌─────────────────────┐
                         │      Authentik      │
                         │        OIDC         │
                         └──────────┬──────────┘
                                    │
                                    │ OIDC
                                    ▼
Users / CLI ───── HTTPS ────────┐
                                │
OpenBao Agent VM1 ─── HTTPS ────┤
OpenBao Agent VM2 ─── HTTPS ────┤
OpenBao Agent VM3 ─── HTTPS ────┤
                                ▼
                         ┌───────────────┐
                         │     Caddy     │
                         │ Reverse Proxy │
                         └───────┬───────┘
                                 │
                                 │ HTTPS
                                 ▼
                         ┌───────────────┐
                         │    OpenBao    │
                         │    KV v2      │
                         │    Raft       │
                         │    Audit      │
                         └───────────────┘

Caddy è l'unico gateway verso OpenBao.

Browser, CLI e OpenBao Agent utilizzano tutti:

https://secretmanager.eagleprojects.cloud

Nessun DEV e nessun Agent deve accedere direttamente alla porta 8200 di OpenBao.


1.3 Ruolo dei componenti

Componente Responsabilità
Authentik Identità degli utenti e membership dei gruppi
Caddy Reverse proxy e unico punto di ingresso
OpenBao Secret, policy, identity, audit e token
Raft Persistenza dello stato OpenBao
OpenBao Agent Distribuzione dei secret sulle VM
AppRole Autenticazione machine-to-machine
systemd Gestione Agent, backup e meccanismi privilegiati
Docker Compose Esecuzione degli stack applicativi
Uptime Kuma Health monitoring esterno

Caddy non utilizza Authentik forward-auth davanti a OpenBao.

L'autenticazione degli utenti è gestita direttamente da:

OpenBao → Authentik OIDC

Questo permette allo stesso endpoint di essere utilizzato senza interferenze da:

UI
bao CLI
OpenBao Agent
API

2. OpenBao Server Deployment

2.1 Server

OpenBao è installato nativamente sulla VM, non tramite Docker.

Configurazione base:

VM OpenBao: 514
IP:         192.168.5.14
FQDN:       secretmanager.eagleprojects.cloud
OS:         Debian 13
OpenBao:    2.6.2
Init:       systemd
Storage:    Integrated Storage / Raft

OpenBao è stato installato tramite repository APT e bloccato per evitare aggiornamenti non controllati:

apt-mark hold openbao

La VM utilizza inoltre:

nftables
systemd-timesyncd
QEMU Guest Agent

SSH è stato spostato sulla porta:

22122/tcp

La configurazione di rete e i principali permessi del filesystem sono stati validati durante il deployment.


2.2 Firewall

La policy nftables è:

INPUT  → DROP
OUTPUT → ACCEPT

Sono consentiti:

loopback
established,related
ICMP / ICMPv6

SSH 22122/tcp è consentito esclusivamente dalle reti/sorgenti amministrative previste.

La porta API OpenBao:

8200/tcp

è consentita esclusivamente da Caddy:

192.168.5.1

La porta cluster:

8201/tcp

è limitata al perimetro OpenBao.

Di conseguenza:

Agent → OpenBao diretto       DENY
DEV   → OpenBao diretto       DENY
Caddy → OpenBao               ALLOW

3. TLS e Reverse Proxy

3.1 TLS OpenBao

È stata creata una CA interna dedicata e un certificato server.

File:

/etc/openbao/tls/openbao-ca.crt
/etc/openbao/tls/openbao.crt
/etc/openbao/tls/openbao.key

Il certificato contiene SAN validi per:

DNS:514
DNS:secretmanager.eagleprojects.cloud
IP:192.168.5.14

Permessi:

chown root:openbao /etc/openbao
chown root:openbao /etc/openbao/tls

chmod 750 /etc/openbao
chmod 750 /etc/openbao/tls

chown root:openbao /etc/openbao/tls/openbao.key
chown root:openbao /etc/openbao/tls/openbao.crt
chown root:openbao /etc/openbao/tls/openbao-ca.crt

chmod 640 /etc/openbao/tls/openbao.key
chmod 644 /etc/openbao/tls/openbao.crt
chmod 644 /etc/openbao/tls/openbao-ca.crt

Verifica:

openssl verify \
  -CAfile /etc/openbao/tls/openbao-ca.crt \
  /etc/openbao/tls/openbao.crt

Risultato atteso:

/etc/openbao/tls/openbao.crt: OK

3.2 Caddy → OpenBao

La CA OpenBao è installata su Caddy:

/etc/caddy/tls/openbao-ca.crt

Con Caddy 2.6.2 viene utilizzata:

secretmanager.eagleprojects.cloud {
    reverse_proxy https://192.168.5.14:8200 {
        transport http {
            tls_trusted_ca_certs /etc/caddy/tls/openbao-ca.crt
            tls_server_name secretmanager.eagleprojects.cloud
        }
    }
}

tls_trust_pool non viene utilizzato perché non supportato dalla versione Caddy installata.

Il flusso TLS validato è quindi:

Client
  ↓ HTTPS
Caddy :443
  ↓ HTTPS
OpenBao :8200

4. Configurazione OpenBao

File principale:

/etc/openbao/openbao.hcl

Configurazione concettuale:

ui = true

api_addr     = "https://secretmanager.eagleprojects.cloud"
cluster_addr = "https://192.168.5.14:8201"

storage "raft" {
  path    = "/var/lib/openbao/raft"
  node_id = "openbao01"
}

listener "tcp" {
  address         = "0.0.0.0:8200"
  cluster_address = "0.0.0.0:8201"

  tls_cert_file = "/etc/openbao/tls/openbao.crt"
  tls_key_file  = "/etc/openbao/tls/openbao.key"

  tls_min_version          = "tls12"
  tls_disable_client_certs = true

  x_forwarded_for_authorized_addrs      = "192.168.5.1/32"
  x_forwarded_for_reject_not_authorized = true
  x_forwarded_for_reject_not_present    = false
}

log_level = "info"

OpenBao considera quindi attendibili gli header X-Forwarded-For esclusivamente quando provengono da Caddy.


5. Storage Raft

Storage:

/var/lib/openbao/raft

Ownership e permessi:

chown -R openbao:openbao /var/lib/openbao
chmod 700 /var/lib/openbao
chmod 700 /var/lib/openbao/raft

Attenzione: bao operator diagnose

Il comando deve essere eseguito come utente openbao:

sudo -u openbao bao operator diagnose \
  -config=/etc/openbao/openbao.hcl

Non eseguirlo come root.

Durante il deployment è stato verificato che l'esecuzione come root può creare:

/var/lib/openbao/raft/vault.db

con ownership:

root:root

provocando successivamente:

permission denied

all'avvio di OpenBao.


6. Init, Seal e Unseal

OpenBao è stato inizializzato utilizzando Shamir:

bao operator init \
  -key-shares=6 \
  -key-threshold=2

Configurazione:

Unseal shares: 6
Threshold:     2

Sono quindi necessarie 2 delle 6 share per effettuare l'unseal.

Le share sono custodite separatamente; una share è prevista anche per il CTO.

Dopo ogni reboot:

OpenBao service start
        ↓
OpenBao SEALED
        ↓
2 Unseal Keys richieste
        ↓
OpenBao ACTIVE

Procedura:

export BAO_ADDR="https://192.168.5.14:8200"
export BAO_CACERT="/etc/openbao/tls/openbao-ca.crt"

bao status

Poi:

bao operator unseal

Inserire la prima share.

Ripetere:

bao operator unseal

Inserire la seconda share.

Verificare:

bao status

Stato corretto:

Initialized    true
Sealed         false
Storage Type   raft
HA Enabled     true
HA Mode        active

La configurazione Shamir 6/2 e il funzionamento Raft sono stati validati durante l'inizializzazione.


7. Audit Logging

L'audit è abilitato fin dall'installazione.

Directory:

/var/log/openbao

Configurazione:

audit "file" "local-file" {
  description = "Local OpenBao audit log"

  options {
    file_path = "/var/log/openbao/audit.log"
    mode      = "0600"
  }
}

File risultante:

/var/log/openbao/audit.log

Ownership:

openbao:openbao

Permessi:

0600

Verifica:

tail -n 3 /var/log/openbao/audit.log

I record sono prodotti in formato JSON.


8. Authentik OIDC

8.1 Discovery endpoint

Authentik:

https://login.eagleprojects.cloud/application/o/open-bao/

L'auth method è montato su:

oidc/

Ruolo:

openbao-test

Configurazione rilevante:

role_type    oidc
user_claim   sub
groups_claim groups
ttl          1h

Redirect URI:

https://secretmanager.eagleprojects.cloud/ui/vault/auth/oidc/oidc/callback
http://localhost:8250/oidc/callback

Il login dalla UI tramite Authentik è stato validato.


9. RBAC utenti

9.1 Modello

Per ogni gruppo applicativo:

<gruppo>          → Read Only
<gruppo>-senior   → Read / Write / Delete

Esempio:

RPA
   ↓
kv-rpa-ro

RPA-senior
   ↓
kv-rpa-rwd

Gli utenti senior possono effettuare il normale delete KV v2.

Restano escluse le operazioni distruttive permanenti:

destroy
delete metadata

La sincronizzazione sfrutta:

Authentik Group
       ↓
OIDC groups claim
       ↓
OpenBao External Identity Group
       ↓
Group Alias
       ↓
OpenBao Policy

9.2 DevOps administrators

È presente una policy:

openbao-admin

associata all'external group:

DevOps

con alias verso il gruppo Authentik DevOps.

Sono esplicitamente negate alla policy amministrativa alcune operazioni particolarmente sensibili:

sys/raw/*
sys/generate-root/*

Il login di un membro del gruppo DevOps e l'applicazione della policy sono stati verificati.


10. Provisioning automatico gruppi

Script:

/usr/local/sbin/openbao-provision-authentik-group

Esempio:

openbao-provision-authentik-group RPA

Lo script gestisce:

verifica OpenBao
verifica KV v2
verifica OIDC
creazione/aggiornamento policy
creazione Identity Group external
creazione alias OIDC
verifica mapping
test capability RO/RWD
logging

Log:

/var/log/openbao/group-provisioning/

Validazione:

bash -n /usr/local/sbin/openbao-provision-authentik-group

11. KV v2

Mount:

kv/

Versione:

KV v2

Gerarchia definitiva:

kv/apps/<gruppo>/<ambiente>/<progetto>

Esempi:

kv/apps/rpa/prod/project-a
kv/apps/rpa/prod/project-b
kv/apps/rpa/staging/project-a

Il nome del gruppo viene normalizzato in lowercase.

La struttura è volutamente indipendente dalla VM che esegue l'applicazione.

Non usare quindi:

kv/apps/vm01/project-a

La VM è infrastruttura e può cambiare; il namespace del secret rappresenta invece:

gruppo
+
ambiente
+
applicazione

La struttura KV v2 definitiva e il modello RBAC sono stati validati.


12. Machine Authentication – AppRole

AppRole è utilizzato per l'autenticazione degli OpenBao Agent.

Auth method:

auth/approle/

La granularità delle policy Agent è:

gruppo + ambiente

Esempio:

agent-rpa-prod

Policy:

path "kv/data/apps/rpa/prod/*" {
  capabilities = ["read"]
}

Gli AppRole sono invece separati per VM.

Convenzione:

agent-<gruppo>-<VM_ID>

Esempio:

agent-rpa-2711

L'ambiente non deve essere codificato nel nome AppRole: viene determinato dal perimetro della VM e dalla policy associata.

Questo permette di revocare una singola macchina senza modificare le altre.

Script disponibili:

/usr/local/sbin/openbao-create-agent-policy
/usr/local/sbin/openbao-create-agent-approle

Il primo genera:

/etc/openbao/policies/agent-<gruppo>-<ambiente>.hcl

Il secondo gestisce:

verifica policy
creazione AppRole
RoleID
SecretID
credenziali bootstrap

Le policy degli Agent sono strettamente READ sul relativo namespace.


13. OpenBao Agent

13.1 Principio architetturale

Viene installato:

1 OpenBao Agent per VM

e non un Agent per ogni Docker Compose.

Esempio:

VM
│
├── OpenBao Agent
│
├── stack-a
├── stack-b
├── stack-c
├── stack-d
└── ...

L'Agent può quindi gestire contemporaneamente più template.


13.2 Installazione

OpenBao viene installato anche sulle VM Agent tramite repository ufficiale:

apt update
apt install -y openbao
apt-mark hold openbao

Il server OpenBao incluso nel pacchetto viene disabilitato:

systemctl disable --now openbao

13.3 Utente dedicato

useradd \
  --system \
  --home /var/lib/openbao-agent \
  --shell /usr/sbin/nologin \
  openbao-agent

Directory:

/etc/openbao-agent
/etc/openbao-agent/auth
/var/lib/openbao-agent
/run/openbao-agent

Credenziali AppRole:

/etc/openbao-agent/auth/role_id
/etc/openbao-agent/auth/secret_id

Ownership:

root:openbao-agent

Permessi:

0640

14. Agent Auto-Auth

Configurazione base:

vault {
  address = "https://secretmanager.eagleprojects.cloud"
}

auto_auth {
  method "approle" {
    mount_path = "auth/approle"

    config = {
      role_id_file_path                   = "/etc/openbao-agent/auth/role_id"
      secret_id_file_path                 = "/etc/openbao-agent/auth/secret_id"
      remove_secret_id_file_after_reading = false
    }
  }

  sink "file" {
    config = {
      path = "/run/openbao-agent/token"
      mode = 0640
    }
  }
}

Il token OpenBao è quindi temporaneo e viene materializzato sotto:

/run/openbao-agent/token

L'Agent non utilizza root token né token amministrativi permanenti.


15. Rendering dei secret

Intervallo utilizzato:

template_config {
  static_secret_render_interval = "1m"
}

Ogni stack genera un proprio .env sotto:

/run/openbao-agent/

Esempio:

/run/openbao-agent/backend.env
/run/openbao-agent/grafana.env
/run/openbao-agent/project-a.env

Il percorso /run è volutamente volatile.

Al reboot i file vengono quindi persi e devono essere nuovamente prodotti dall'Agent.

Il rendering KV → .env è stato validato end-to-end.


16. Docker Compose Integration

Gli stack utilizzano:

env_file:
  - /run/openbao-agent/<stack>.env

La catena completa è:

OpenBao
   ↓
Caddy
   ↓
AppRole
   ↓
OpenBao Agent
   ↓
template
   ↓
/run/openbao-agent/<stack>.env
   ↓
Docker Compose
   ↓
container

La presenza delle variabili nei container è stata validata tramite printenv.


17. Reload automatico degli stack

17.1 Principio

L'utente openbao-agent non deve avere accesso al Docker socket:

/var/run/docker.sock

La gestione privilegiata deve rimanere separata dal rendering dei secret.

Architettura:

OpenBao Agent
      ↓
.env modificato
      ↓
helper controllato
      ↓
systemd
      ↓
docker compose up -d --force-recreate
      ↓
solo stack interessato

Il comando previsto per il reload controllato è:

/usr/local/sbin/openbao-compose-reload

e deve operare esclusivamente su stack autorizzati.

Il modello di separazione Agent/Docker è una decisione architetturale esplicita.


18. Comportamento verificato delle variabili

Sono stati verificati tre scenari.

Scenario A – OpenBao e Agent disponibili

Cambio secret in OpenBao
        ↓
Agent rileva modifica
        ↓
.env aggiornato
        ↓
stack aggiornato

Risultato: OK


Scenario B – Agent disabilitato

Agent OFF
   ↓
Cambio secret OpenBao
   ↓
.env sulla VM invariato

Risultato: OK

Questo conferma che la distribuzione dei secret avviene esclusivamente tramite OpenBao Agent.


Scenario C – OpenBao offline e reboot VM applicativa

Dopo reboot con OpenBao non disponibile:

/run/openbao-agent/

risulta vuoto.

Questo è atteso perché /run è volatile.

I container Docker già esistenti continuano però a ripartire con le environment variables utilizzate al momento della loro creazione.

Esempio verificato:

OpenBao OFF
        ↓
reboot VM
        ↓
/run/openbao-agent vuoto
        ↓
container esistente riparte
        ↓
ultima ENV precedentemente caricata ancora presente

Questo comportamento garantisce che un'indisponibilità temporanea di OpenBao non impedisca il riavvio degli stack già creati.

Quando OpenBao torna unsealed, l'Agent effettua nuovamente l'Auto-Auth e ricostruisce i file sotto /run/openbao-agent.


19. Recovery dell'Agent dopo Seal

Se OpenBao rimane sealed per un periodo prolungato, l'Agent applica un meccanismo di retry/backoff.

È stato deciso di mantenere il comportamento standard, accettando che in determinate condizioni il recovery possa richiedere fino a circa cinque minuti.

Non è quindi necessario ridurre artificialmente il retry interval.


20. Security Caveat – Docker ENV

OpenBao protegge:

accesso
RBAC
audit
versionamento
distribuzione

ma dopo che un secret è stato trasformato in:

DB_PASSWORD=xxxx

e passato come environment variable al container, non è più protetto direttamente da OpenBao.

Un amministratore con privilegi sufficienti sul Docker host può leggere tali valori.

Il modello attuale è quindi:

OpenBao
   ↓
.env
   ↓
Docker ENV

Per secret particolarmente sensibili potrà essere valutato in futuro:

OpenBao
   ↓
/run/secrets/...
   ↓
bind mount read-only nel container

21. Backup Raft

21.1 Strategia

Configurazione definitiva:

Frequenza:       1 snapshot al giorno
Retention:       ultimi 14 snapshot riusciti
Scheduler:       systemd timer
Checksum:        SHA-256
Directory:       /var/backups/openbao/daily

Gli snapshot manuali/iniziali vengono mantenuti separati e non vengono coinvolti nella rotazione automatica.


21.2 Autenticazione backup

Policy dedicata:

path "sys/storage/raft/snapshot" {
  capabilities = ["read"]
}

Nome:

openbao-backup

AppRole dedicato:

openbao-backup

Token:

TTL:     15m
Max TTL: 15m

Credenziali locali:

/etc/openbao/backup-auth/role_id
/etc/openbao/backup-auth/secret_id

Permessi:

0600
root:root

Non viene conservato un root token nel job di backup.


21.3 Script

/usr/local/sbin/openbao-raft-backup

Lo script:

login AppRole
      ↓
token temporaneo
      ↓
snapshot .tmp
      ↓
verifica snapshot non vuoto
      ↓
rename atomico .snap
      ↓
SHA-256
      ↓
verifica checksum
      ↓
rotazione

La rotazione avviene solo dopo il completamento corretto del nuovo snapshot.

Vengono mantenuti esattamente gli ultimi:

14

snapshot riusciti.


21.4 systemd

Service:

/etc/systemd/system/openbao-raft-backup.service

Tipo:

Type=oneshot

Pertanto dopo una corretta esecuzione:

Active: inactive (dead)

è uno stato normale.

Timer:

/etc/systemd/system/openbao-raft-backup.timer

Configurazione:

[Timer]
OnCalendar=daily
Persistent=true
AccuracySec=5m
Unit=openbao-raft-backup.service

Persistent=true permette a systemd di recuperare un'esecuzione mancata dopo uno shutdown.

Verifica:

systemctl status openbao-raft-backup.timer --no-pager

systemctl list-timers openbao-raft-backup.timer

Il backup viene pianificato quotidianamente a mezzanotte, salvo la finestra prevista da AccuracySec.


22. Backup Off-site

Gli snapshot Raft non vengono attualmente copiati autonomamente off-host.

La scelta è consapevole perché la VM OpenBao è già inclusa nel sistema di backup off-site dell'infrastruttura.

La replica dedicata degli snapshot Raft verso uno storage indipendente rimane un possibile miglioramento futuro.


23. Monitoring

Il monitoraggio esterno viene affidato a Uptime Kuma.

Endpoint:

https://secretmanager.eagleprojects.cloud/v1/sys/health

Configurazione consigliata:

Monitor Type:          HTTP(s)
Method:                GET
Heartbeat Interval:    60 s
Retries:               2–3
Timeout:               10 s
Accepted Status Codes: 200–299

Questo monitor verifica contemporaneamente:

DNS
 ↓
TLS
 ↓
Caddy
 ↓
OpenBao
 ↓
stato ACTIVE / UNSEALED

È preferibile rispetto al semplice controllo TCP della porta 8200, perché un'istanza OpenBao può essere raggiungibile a livello TCP ma risultare sealed.


23.1 Monitoring backup – miglioramento possibile

In futuro può essere introdotto un Push Monitor Uptime Kuma che controlli:

ultimo snapshot < 30 ore

per rilevare automaticamente eventuali problemi del backup giornaliero.


24. systemd Hardening

L'unit OpenBao fornita dal pacchetto utilizza già:

User=openbao
Group=openbao

ProtectSystem=full
ProtectHome=read-only
PrivateTmp=yes
PrivateDevices=yes

SecureBits=keep-caps
CapabilityBoundingSet=CAP_SYSLOG
NoNewPrivileges=yes

MemorySwapMax=0

MemorySwapMax=0 impedisce al servizio di utilizzare swap.

La base di hardening del pacchetto è quindi già significativa.


24.1 Hardening aggiuntivo in valutazione

È stato predisposto come possibile ulteriore livello:

[Service]

ProtectClock=yes
ProtectKernelLogs=yes
ProtectKernelModules=yes
ProtectKernelTunables=yes
ProtectControlGroups=yes
ProtectHostname=yes

LockPersonality=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
RestrictNamespaces=yes
RemoveIPC=yes

RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
SystemCallArchitectures=native

Prima di applicarlo definitivamente deve essere eseguito:

systemctl daemon-reload

systemd-analyze verify openbao.service

systemd-analyze security openbao.service

Non deve essere effettuato un restart non pianificato: con Shamir un restart riporta infatti OpenBao nello stato sealed.

Non vengono introdotti per il momento:

MemoryDenyWriteExecute=yes
ProtectSystem=strict

per evitare restrizioni non necessarie o possibili incompatibilità operative.


25. Initial Root Token

L'Initial Root Token viene mantenuto solo durante la fase finale di deployment e hardening.

L'autenticazione amministrativa ordinaria è già disponibile tramite:

Authentik
   ↓
OIDC
   ↓
DevOps
   ↓
openbao-admin

Al termine delle verifiche finali il root token dovrà essere rimosso/revocato e non dovrà essere utilizzato come credenziale operativa.

Prima della rimozione verificare:

printenv BAO_TOKEN

e:

if [ -f /root/.vault-token ]; then
    ls -l /root/.vault-token
else
    echo "OK: nessun token OpenBao persistente"
fi

Non memorizzare mai il root token in script, unit systemd o file di configurazione.


26. Runbook operativo

26.1 Verifica OpenBao

export BAO_ADDR="https://192.168.5.14:8200"
export BAO_CACERT="/etc/openbao/tls/openbao-ca.crt"

bao status

26.2 Health check tramite Caddy

curl -i \
  https://secretmanager.eagleprojects.cloud/v1/sys/health

26.3 Verifica servizio

systemctl status openbao --no-pager

Log:

journalctl -u openbao -n 100 --no-pager

Porte:

ss -lntp | grep -E ':(8200|8201)\b'

26.4 Unseal dopo reboot

bao status

Poi:

bao operator unseal

Prima share.

bao operator unseal

Seconda share.

Infine:

bao status

Verificare:

Sealed false
HA Mode active

26.5 Verifica OpenBao Agent

Sulla VM applicativa:

systemctl status openbao-agent --no-pager

Log:

journalctl -u openbao-agent -n 100 --no-pager

File generati:

ls -la /run/openbao-agent/

26.6 Verifica variabile container

docker exec <container> printenv <VARIABILE>

26.7 Verifica backup

Ultimi snapshot:

ls -lh /var/backups/openbao/daily/

Service:

systemctl status openbao-raft-backup.service --no-pager

Timer:

systemctl list-timers openbao-raft-backup.timer

Verifica manuale checksum:

sha256sum -c \
  /var/backups/openbao/daily/<snapshot>.snap.sha256

27. Troubleshooting

27.1 vault.db: permission denied

Errore:

open /var/lib/openbao/raft/vault.db: permission denied

Controllare:

ls -la /var/lib/openbao/raft

Correggere:

chown -R openbao:openbao /var/lib/openbao
chmod 700 /var/lib/openbao
chmod 700 /var/lib/openbao/raft

Causa osservata durante il deployment:

bao operator diagnose

eseguito come root.

Utilizzare sempre:

sudo -u openbao bao operator diagnose \
  -config=/etc/openbao/openbao.hcl

27.2 TLS certificate permission denied

Errore:

error loading TLS cert: permission denied

Controllare non solo i file, ma anche le directory:

namei -l /etc/openbao/tls/openbao.crt
namei -l /etc/openbao/tls/openbao.key

Le directory devono consentire all'utente OpenBao di attraversare il path.


27.3 OpenBao Agent non aggiorna immediatamente dopo unseal

Dopo un periodo in cui OpenBao è sealed, l'Agent può essere entrato nel proprio backoff di retry.

Attendere fino ad alcuni minuti.

Controllare:

journalctl -fu openbao-agent

Il comportamento corrente è considerato accettabile e non viene modificato.


27.4 /run/openbao-agent vuoto dopo reboot

È normale:

/run

è un filesystem volatile.

Se OpenBao è disponibile:

Agent
 ↓
Auto-Auth
 ↓
template render
 ↓
file ricreati

Se OpenBao è offline, i file rimangono assenti fino al recovery dell'Agent.

I container già esistenti mantengono tuttavia le environment variables con cui erano stati precedentemente creati.


27.5 Backup service inactive (dead)

Per:

openbao-raft-backup.service

questo stato è normale perché:

Type=oneshot

Verificare il risultato dell'ultima esecuzione con:

journalctl \
  -u openbao-raft-backup.service \
  -n 30 \
  --no-pager

28. Decisioni architetturali definitive

Area Decisione
OpenBao OS Debian 13
Deployment Pacchetto APT nativo
Storage Integrated Storage / Raft
Nodo iniziale Single node
Seal Shamir 6/2
Accesso Sempre attraverso Caddy
TLS client → Caddy
TLS Caddy → OpenBao
Auth utenti Authentik OIDC
Caddy forward-auth No
Secret engine KV v2
Struttura KV gruppo/ambiente/progetto
RBAC <group> RO / <group>-senior RWD
Machine auth AppRole
AppRole Uno per VM
Agent Uno per VM
Agent → Docker socket Vietato
Rendering /run/openbao-agent/*.env
Aggiornamento secret Automatico
Audit File locale JSON
Backup Raft Giornaliero
Retention Ultimi 14
Scheduler backup systemd
Monitoring Uptime Kuma /sys/health
Root token Da rimuovere a fine hardening

29. Stato del progetto

Completato

  • Debian 13
  • OpenBao 2.6.2
  • Integrated Storage / Raft
  • TLS OpenBao
  • Caddy reverse proxy
  • Firewall OpenBao
  • Init Shamir 6/2
  • Unseal verificato
  • Audit logging
  • Authentik OIDC
  • DevOps administrative mapping
  • KV v2
  • RBAC utenti
  • Provisioning automatico gruppi
  • AppRole
  • Policy Agent
  • OpenBao Agent
  • Rendering automatico .env
  • Docker Compose integration
  • Aggiornamento automatico delle variabili
  • Test Agent offline
  • Test OpenBao offline
  • Test reboot VM applicativa con OpenBao offline
  • Snapshot Raft
  • SHA-256 snapshot
  • Backup automatico systemd
  • Retention ultimi 14 snapshot

Da completare

  • Validazione/applicazione eventuale hardening systemd aggiuntivo
  • Rimozione/revoca Initial Root Token

30. Future Improvements

Miglioramenti possibili, non necessari per l'attuale messa in produzione:

Replica dedicata snapshot Raft off-host

Attualmente la VM è già protetta dal backup off-site dell'infrastruttura.

In futuro:

OpenBao
   ↓
snapshot Raft
   ↓
storage indipendente

OpenBao Raft HA

Evoluzione possibile:

OpenBao01
OpenBao02
OpenBao03
     ↓
Raft cluster

Secret file invece di Docker ENV

Per credenziali particolarmente sensibili:

OpenBao
   ↓
/run/secrets/application
   ↓
bind mount RO
   ↓
container

Restore test isolato

Eseguire periodicamente un test controllato di ripristino dello snapshot Raft su un ambiente isolato.