docs(openbao): the Proxmox per-VM firewall, and reaching the API over SSH
Two things that cost real debugging time on a live deploy. A Docker-published port on a Proxmox guest is filtered by the per-VM firewall on the PVE host, upstream of everything in the guest. The failure is maximally misleading: inside the VM the DNAT rule, the FORWARD jumps, the docker-proxy socket and a local curl to the bind address are all correct and the listener answers 503, while a LAN client times out. SSH working proves nothing -- it only proves a rule exists for 22. The decisive test is `tcpdump -ni eth0 'tcp port 8200'` capturing zero packets during a failed connection, which says the guest never saw them. And: the publish is pinned to OPENBAO_BIND, so a browser on another subnet cannot reach the UI. Document the SSH tunnel rather than widening the publish -- the generated cert already carries DNS:localhost + IP:127.0.0.1, so https://localhost:8200 validates against it unchanged. That is also the better way to run the first `operator init`, since the unseal keys are then shown in a browser instead of a root shell's scrollback. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -136,6 +136,14 @@ This is a secrets store on the LAN, not a public service. Two things to know:
|
||||
`OPENBAO_ADDR` when that is an IP, so the API listens only on that LAN IP. To
|
||||
restrict by *source host*, use a `FORWARD`/`DOCKER-USER` rule or network
|
||||
segmentation, not `INPUT`.
|
||||
- **On a Proxmox guest, the per-VM firewall filters before the guest sees
|
||||
anything.** If the VM's NIC has `firewall=1` and the datacenter firewall is
|
||||
enabled, a Docker-published port needs its own `IN ACCEPT -p tcp -dport 8200`
|
||||
rule in `/etc/pve/firewall/<vmid>.fw`. SSH working does **not** prove the path
|
||||
— it only proves there is a rule for 22. The give-away is that everything
|
||||
inside the guest looks perfect (`curl` to the bind address answers, the DNAT
|
||||
and `FORWARD` jumps are present) while `tcpdump -ni eth0 'tcp port 8200'`
|
||||
captures zero packets during a failed connection.
|
||||
- **mTLS (optional):** to require the tape host to present a client cert, enable
|
||||
the `tls_require_and_verify_client_cert` stanza in [`config.hcl`](config.hcl)
|
||||
and issue the tape host a client cert from the same CA.
|
||||
@@ -144,6 +152,21 @@ And **initialise the vault immediately** after `deploy.sh` — an uninitialised
|
||||
vault reachable on the LAN can be `bao operator init`'d by anyone who connects,
|
||||
handing them the root token and unseal keys.
|
||||
|
||||
### Reaching it without LAN access
|
||||
|
||||
The API publishes on `OPENBAO_BIND` only, so a browser on another subnet (or
|
||||
behind a firewall you do not control) cannot reach it. Tunnel over SSH instead
|
||||
of widening the publish — the generated cert already carries `DNS:localhost`
|
||||
and `IP:127.0.0.1` in its SANs, so it validates as-is:
|
||||
|
||||
```bash
|
||||
ssh -L 8200:<bind-addr>:8200 root@<host>
|
||||
# then browse https://localhost:8200
|
||||
```
|
||||
|
||||
This is also the better way to do the first `operator init`: the unseal keys and
|
||||
root token are shown in your browser instead of a root shell's scrollback.
|
||||
|
||||
## Backup / DR
|
||||
|
||||
The vault is the sole recovery path for encrypted tapes — back it up:
|
||||
|
||||
Reference in New Issue
Block a user