# Certbot — Verteilte Zertifikatserneuerung

## Uebersicht

Let's Encrypt TLS-Zertifikate werden auf **allen 5 Cluster-Servern** unabhaengig erneuert. Wer zuerst erneuert, synct an die anderen. Let's Encrypt ist idempotent — doppelte Renewals sind harmlos.

## Zertifikate

| Name | Domains | Ablauf | Key |
|------|---------|--------|-----|
| cert-business | `*.{dev,tst,int,lup,pen,pres,abn,prd}.bahn.business` + Wildcards | 90 Tage (Renewal ab Tag 60) | ECDSA |
| cert-services | `*.{dev,tst,int,lup,pen,pres,abn,prd}.bahn.services` + Wildcards | 90 Tage (Renewal ab Tag 60) | ECDSA |

## Installation

- **Certbot:** Snap 5.5.0 (`snap install certbot --classic`)
- **Plugin:** `snap install certbot-dns-cloudflare`
- **Binary:** `/usr/bin/certbot` → `/snap/bin/certbot` (Symlink)
- **WICHTIG:** apt-certbot (2.9.0) darf NICHT installiert sein — blockiert den Snap-Symlink und ist inkompatibel mit den Renewal-Configs (v5.3.1)

## Dateien

| Pfad | Inhalt | Permissions |
|------|--------|-------------|
| `/etc/letsencrypt/renewal/*.conf` | Renewal-Konfiguration (Zone, Plugin, Account) | root:root 644 |
| `/etc/letsencrypt/live/cert-*/` | Symlinks auf aktuelle Certs | root:root 700 |
| `/etc/letsencrypt/archive/cert-*/` | Alle Cert-Versionen (History) | root:root 700 |
| `/etc/letsencrypt/accounts/` | ACME-Account + Private Key | root:root 700 |
| `/root/.secrets/certbot/cloudflare-business.ini` | CF API Token bahn.business | root:root 600 |
| `/root/.secrets/certbot/cloudflare-services.ini` | CF API Token bahn.services | root:root 600 |
| `/etc/letsencrypt/renewal-hooks/deploy/reload-and-sync.sh` | Post-Renewal Hook | root:root 755 |

## Timer-Staffelung

Jeder Server prueft 2x taeglich, mit 2h Abstand untereinander:

| Server | Timer 1 | Timer 2 |
|--------|---------|---------|
| .2 Cert-Server-1-NBG | 00:10 | 20:23 |
| .3 Cert-Server-0-NBG | 02:10 | 22:23 |
| .4 Cert-Server-0-FSN | 04:10 | 00:23 |
| .5 Cert-Server-1-FSN | 06:10 | 02:23 |
| .6 Cert-Server-HEL | 08:10 | 04:23 |

Implementiert via systemd drop-in Override: `/etc/systemd/system/snap.certbot.renew.timer.d/override.conf`

## Deploy-Hook (Post-Renewal)

`/etc/letsencrypt/renewal-hooks/deploy/reload-and-sync.sh`

Identisch auf allen 5 Servern. Erkennt eigene VLAN-IP, synct an alle anderen:

1. **Cert-Validierung:** openssl prueft Syntax + Ablaufdatum + Privkey
2. **Apache-Reload lokal:** systemctl reload apache2
3. **Apache-Funktionstest:** curl auf localhost:443 (muss antworten)
4. **Sync an Peers:** rsync live/ + archive/ an alle anderen VLAN-IPs
5. **Apache-Reload auf Peers:** per SSH

**Sicherung:** Wenn Schritt 1, 2 oder 3 fehlschlaegt → `exit 1`, KEIN Sync an Peers. Die alten (gueltigen) Certs bleiben auf den anderen Servern erhalten.

rsync wird OHNE `--delete` ausgefuehrt — ueberschreibt nur, loescht nie.

## Manuell erneuern

```bash
# Dry-Run (testet ohne echtes Cert):
certbot renew --dry-run

# Echte Erneuerung erzwingen:
certbot renew --force-renewal

# Status pruefen:
certbot certificates
```

## Neuen Server hinzufuegen

1. `snap install certbot --classic && snap install certbot-dns-cloudflare`
2. `rsync -a root@10.0.0.2:/etc/letsencrypt/ /etc/letsencrypt/`
3. `rsync -a root@10.0.0.2:/root/.secrets/certbot/ /root/.secrets/certbot/`
4. `chmod 600 /root/.secrets/certbot/*.ini`
5. Timer-Override anlegen (naechster 2h-Slot)
6. `certbot renew --dry-run` (muss "success" zeigen)
7. Deploy-Hook pruefen: VLAN-IPs in `ALL_PEERS` Array aktualisieren

## Bekannte Probleme

- **apt-certbot vs. snap-certbot:** Wenn `certbot --version` < 5.x zeigt, ist die apt-Version aktiv. Fix: `apt-get purge certbot python3-certbot*`, dann `ln -sf /snap/bin/certbot /usr/bin/certbot`
- **Lock-File haengt:** `rm -f /var/lib/letsencrypt/.certbot.lock` nach Absturz
- **DNS-Propagation:** 30s Wartezeit konfiguriert (`dns_cloudflare_propagation_seconds = 30`), bei langsamer CF-Propagation ggf. erhoehen
