mt-az: vollstaendige Zertifikatskette, plus Pruefung beim Erneuern

api-ssl auf mt-az lieferte nur das Blattzertifikat aus. Gegen die famfi-Root-CA
allein scheiterte die Pruefung deshalb mit "unable to get local issuer
certificate" - jeder strenge TLS-Client braucht die Zwischen-CA separat
zugesteckt. Der CrowdSec-Bouncer funktionierte nur, weil er mit
famfi-ca-bundle.pem (Root + Intermediate) konfiguriert ist.

Ursache war nicht das Skript, sondern der Zertifikatsspeicher des Routers: die
Zwischen-CA lag dort gar nicht. RouterOS verknuepft Blatt und CA beim IMPORT des
Blattes (Feld ca=), und ohne die CA im Speicher entsteht diese Verknuepfung nicht.
Nachtraeglich laesst sie sich auch nicht setzen - "bad parameter ca".

Behoben in zwei Schritten: die Zwischen-CA als famfi-int-ca-20261022.crt_0
importiert, danach ein --force-Renew, damit RouterOS das neue Blatt mit ihr
verknuepft. api-ssl liefert jetzt Blatt + Zwischen-CA, und die Pruefung gegen die
Root allein gibt "Verify return code: 0 (ok)".

Das Skript selbst brauchte dafuer keine Aenderung - es schreibt weiterhin nur
d["certificate"]. Es funktioniert aber nur, SOLANGE die Zwischen-CA im Speicher
liegt. Darum hier ergaenzt:

- Hinweis im Kopf auf diese Abhaengigkeit.
- Kettenpruefung am Ende: nach dem Austausch wird gegen $ROOT_CA verifiziert.
  Bewusst nur eine Warnung, kein die() - das Zertifikat waere ja in Ordnung, die
  fehlende Kette ist ein Mangel, kein Ausfall. Ein Abbruch wuerde einen
  erfolgreichen Austausch als Fehlschlag melden.

Die Pruefung laeuft nur bei einer tatsaechlichen Erneuerung, nicht beim taeglichen
Leerlauf - also genau dann, wenn die Verknuepfung verloren gehen koennte. Die Zeit
dazwischen deckt die Blackbox-Probe ab: deren Modul tcp_tls_famfi zeigt seit heute
auf die Root-CA allein, scheitert also, wenn die Kette je wieder wegfaellt.

Nachgewiesen: Bouncer nach dem Zertifikatswechsel neu gestartet, frischer
TLS-Handshake ohne x509-Fehler, arbeitet Entscheidungen ab; 16145 Eintraege in der
Router-Sperrliste, 82591 verworfene Pakete.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-22 13:28:47 +02:00
parent a9e51fbc8c
commit f3cfe777b6

View File

@@ -22,6 +22,12 @@ TTL="2160h" # 90 Tage, wie bei openbao/gitea
RT_HOST="192.168.0.2"
RT_USER="apics" # group=full, address=192.168.0.0/24
RENEW_WINDOW_DAYS="${RENEW_WINDOW_DAYS:-21}"
# Fuer die vollstaendige Kette muss die Zwischen-CA im Zertifikatsspeicher des
# Routers liegen (2026-10-22 als famfi-int-ca-20261022.crt_0 importiert). RouterOS
# verknuepft Blatt und CA beim IMPORT des Blattes; fehlt die CA, liefert api-ssl nur
# das Blatt aus und strenge Clients scheitern mit "unable to get local issuer
# certificate". Wird die CA je entfernt, faellt das unten in der Kettenpruefung auf.
ROOT_CA="${ROOT_CA:-/home/lutz/.config/famfi-ca/famfi-home-root-ca.pem}"
FORCE="${1:-}"
log() { printf '%s [renew-mikrotik-cert] %s\n' "$(date '+%F %T')" "$*"; }
@@ -135,3 +141,19 @@ end_new="$(echo "$got" | sed -n 's/^notAfter=//p')"
left=$(( ( $(date -d "$end_new" +%s) - $(date +%s) ) / 86400 ))
[ "$left" -gt 0 ] || die "ausgeliefertes Zertifikat ist nicht gueltig (${left}d)"
log "OK - noch ${left} Tage gueltig"
# Kette pruefen: gegen die ROOT allein verifizieren. Das gelingt nur, wenn der
# Router die Zwischen-CA mitschickt. Kein die(), denn das Zertifikat selbst ist
# in Ordnung - es ist ein Mangel, kein Ausfall, und ein Abbruch hier wuerde einen
# erfolgreichen Austausch als Fehlschlag melden.
if [ -r "$ROOT_CA" ]; then
if echo | timeout 20 openssl s_client -connect "${RT_HOST}:8729" \
-CAfile "$ROOT_CA" 2>&1 | grep -q "Verify return code: 0"; then
log "Kette vollstaendig (gegen die Root-CA verifiziert)"
else
log "WARNUNG: api-ssl liefert keine vollstaendige Kette - liegt die Zwischen-CA"
log " noch im Speicher? /certificate print where common-name~\"Intermediate\""
fi
else
log "Kettenpruefung uebersprungen: $ROOT_CA nicht lesbar"
fi