All checks were successful
Run nix flake check / flake-check (push) Successful in 2m16s
179 lines
5.3 KiB
Markdown
179 lines
5.3 KiB
Markdown
# OpenBao TPM2 Auto-Unseal Setup
|
|
|
|
This document describes the one-time setup process for enabling TPM2-based auto-unsealing on vault01.
|
|
|
|
## Overview
|
|
|
|
The auto-unseal feature uses systemd's `LoadCredentialEncrypted` with TPM2 to securely store and retrieve an unseal key. On service start, systemd automatically decrypts the credential using the VM's TPM, and the service unseals OpenBao.
|
|
|
|
## Prerequisites
|
|
|
|
- OpenBao must be initialized (`bao operator init` completed)
|
|
- You must have at least one unseal key from the initialization
|
|
- vault01 must have a TPM2 device (virtual TPM for Proxmox VMs)
|
|
|
|
## Initial Setup
|
|
|
|
Perform these steps on vault01 after deploying the service configuration:
|
|
|
|
### 1. Save Unseal Key
|
|
|
|
```bash
|
|
# Create temporary file with one of your unseal keys
|
|
echo "paste-your-unseal-key-here" > /tmp/unseal-key.txt
|
|
```
|
|
|
|
### 2. Encrypt with TPM2
|
|
|
|
```bash
|
|
# Encrypt the key using TPM2 binding
|
|
systemd-creds encrypt \
|
|
--with-key=tpm2 \
|
|
--name=unseal-key \
|
|
/tmp/unseal-key.txt \
|
|
/var/lib/openbao/unseal-key.cred
|
|
|
|
# Set proper ownership and permissions
|
|
chown openbao:openbao /var/lib/openbao/unseal-key.cred
|
|
chmod 600 /var/lib/openbao/unseal-key.cred
|
|
```
|
|
|
|
### 3. Cleanup
|
|
|
|
```bash
|
|
# Securely delete the plaintext key
|
|
shred -u /tmp/unseal-key.txt
|
|
```
|
|
|
|
### 4. Test Auto-Unseal
|
|
|
|
```bash
|
|
# Restart the service - it should auto-unseal
|
|
systemctl restart openbao
|
|
|
|
# Verify it's unsealed
|
|
bao status
|
|
# Should show: Sealed = false
|
|
```
|
|
|
|
## TPM PCR Binding
|
|
|
|
The default `--with-key=tpm2` binds the credential to PCR 7 (Secure Boot state). For stricter binding that includes firmware and boot state:
|
|
|
|
```bash
|
|
systemd-creds encrypt \
|
|
--with-key=tpm2 \
|
|
--tpm2-pcrs=0+7+14 \
|
|
--name=unseal-key \
|
|
/tmp/unseal-key.txt \
|
|
/var/lib/openbao/unseal-key.cred
|
|
```
|
|
|
|
PCR meanings:
|
|
- **PCR 0**: BIOS/UEFI firmware measurements
|
|
- **PCR 7**: Secure Boot state (UEFI variables)
|
|
- **PCR 14**: MOK (Machine Owner Key) state
|
|
|
|
**Trade-off**: Stricter PCR binding improves security but may require re-encrypting the credential after firmware updates or kernel changes.
|
|
|
|
## Re-provisioning
|
|
|
|
If you need to reprovision vault01 from scratch:
|
|
|
|
1. **Before destroying**: Back up your root token and all unseal keys (stored securely offline)
|
|
2. **After recreating the VM**:
|
|
- Initialize OpenBao: `bao operator init`
|
|
- Follow the setup steps above to encrypt a new unseal key with TPM2
|
|
3. **Restore data** (if migrating): Copy `/var/lib/openbao` from backup
|
|
|
|
## Handling System Changes
|
|
|
|
**After firmware updates, kernel updates, or boot configuration changes**, PCR values may change, causing TPM decryption to fail.
|
|
|
|
### Symptoms
|
|
- Service fails to start
|
|
- Logs show: `Failed to decrypt credentials`
|
|
- OpenBao remains sealed after reboot
|
|
|
|
### Fix
|
|
1. Unseal manually with one of your offline unseal keys:
|
|
```bash
|
|
bao operator unseal
|
|
```
|
|
|
|
2. Re-encrypt the credential with updated PCR values:
|
|
```bash
|
|
echo "your-unseal-key" > /tmp/unseal-key.txt
|
|
systemd-creds encrypt \
|
|
--with-key=tpm2 \
|
|
--name=unseal-key \
|
|
/tmp/unseal-key.txt \
|
|
/var/lib/openbao/unseal-key.cred
|
|
chown openbao:openbao /var/lib/openbao/unseal-key.cred
|
|
chmod 600 /var/lib/openbao/unseal-key.cred
|
|
shred -u /tmp/unseal-key.txt
|
|
```
|
|
|
|
3. Restart the service:
|
|
```bash
|
|
systemctl restart openbao
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
### What This Protects Against
|
|
- **Data at rest**: Vault data is encrypted and cannot be accessed without unsealing
|
|
- **VM snapshot theft**: An attacker with a VM snapshot cannot decrypt the unseal key without the TPM state
|
|
- **TPM binding**: The key can only be decrypted by the same VM with matching PCR values
|
|
|
|
### What This Does NOT Protect Against
|
|
- **Compromised host**: If an attacker gains root access to vault01 while running, they can access unsealed data
|
|
- **Boot-time attacks**: If an attacker can modify the boot process to match PCR values, they may retrieve the key
|
|
- **VM console access**: An attacker with VM console access during boot could potentially access the unsealed vault
|
|
|
|
### Recommendations
|
|
- **Keep offline backups** of root token and all unseal keys in a secure location (password manager, encrypted USB, etc.)
|
|
- **Use Shamir secret sharing**: The default 5-key threshold means even if the TPM key is compromised, an attacker needs the other keys
|
|
- **Monitor access**: Use OpenBao's audit logging to detect unauthorized access
|
|
- **Consider stricter PCR binding** (PCR 0+7+14) for production, accepting the maintenance overhead
|
|
|
|
## Troubleshooting
|
|
|
|
### Check if credential exists
|
|
```bash
|
|
ls -la /var/lib/openbao/unseal-key.cred
|
|
```
|
|
|
|
### Test credential decryption manually
|
|
```bash
|
|
# Should output your unseal key if TPM decryption works
|
|
systemd-creds decrypt /var/lib/openbao/unseal-key.cred -
|
|
```
|
|
|
|
### View service logs
|
|
```bash
|
|
journalctl -u openbao -n 50
|
|
```
|
|
|
|
### Manual unseal
|
|
```bash
|
|
bao operator unseal
|
|
# Enter one of your offline unseal keys when prompted
|
|
```
|
|
|
|
### Check TPM status
|
|
```bash
|
|
# Check if TPM2 is available
|
|
ls /dev/tpm*
|
|
|
|
# View TPM PCR values
|
|
tpm2_pcrread
|
|
```
|
|
|
|
## References
|
|
|
|
- [systemd.exec - Credentials](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Credentials)
|
|
- [systemd-creds man page](https://www.freedesktop.org/software/systemd/man/systemd-creds.html)
|
|
- [TPM2 PCR Documentation](https://uapi-group.org/specifications/specs/linux_tpm_pcr_registry/)
|
|
- [OpenBao Documentation](https://openbao.org/docs/)
|