Zum Inhalt springen
use-cases / cert-renewal-no-ssh / hero
CRON · EXEC · KEIN SSH

TLS-Zertifikate ohne SSH-Session erneuern

Hoody Cron trägt den Schedule. Hoody Exec trägt die Erneuerungs-Logik. Sonntag um 04:00 feuert ein curl, certbot läuft, das neue Bundle wird per PATCH in den Proxy geschoben, und der Reload wird quittiert. Keine Shell-Session, kein Key in ~/.ssh, kein Jump-Host zwischen dir und dem Zertifikat.

Cron-Docs lesen
use-cases / cert-renewal-no-ssh / lifecycle

Drei URLs, keine Shell

Die ganze Erneuerungs-Pipeline besteht aus zwei Endpoints und einem 5-Feld-Schedule. Cron triggert Exec. Exec ruft ACME auf und schickt PATCH an den Proxy. Die Quittung kommt als 200 zurück.

RENEWAL LIFECYCLEEINMAL POSTed · LÄUFT WÖCHENTLICH
01 · SCHEDULE

POST einen Cron-Eintrag

POST /users/me/entries mit schedule "0 4 * * 0" und command "curl /scripts/certs/renew". Der Cron-Service schreibt es in die User-Crontab und fängt an zu ticken. Du hast das einmal gemacht, von irgendwo mit HTTPS.

02 · RUN

Exec führt das Skript aus

Sonntag 04:00 curlt der Cron die Exec-URL. Exec startet das Skript, redet mit dem ACME-Endpoint von Let's Encrypt, validiert den http-01-Challenge und schreibt das erneuerte Bundle nach /files. Niemand loggt sich auf einer Node ein, keine Session nötig.

03 · RELOAD

PATCH das Proxy-Bundle

Das Skript schickt das neue Zertifikat und den Key per PATCH an den Bundle-Endpoint des Hoody-Proxys. Der Proxy lädt heiß nach — kein Restart — und der nächste TLS-Handshake liefert das neue Zertifikat aus. Der ganze Zyklus dauert unter einer Minute.

Jeder Schritt ist ein HTTP-Call, den du aus einem Terminal nachspielen kannst — `curl --dry-run` wenn du debuggen willst, `curl -i` wenn du die Header sehen willst. Die Pipeline hängt zu keinem Zeitpunkt von einer eingeloggten Session ab.

use-cases / cert-renewal-no-ssh / mechanism

Wie die zwei Endpoints aussehen

Links der Cron-Eintrag, der den Job einplant. Rechts das Exec-Skript, das die Arbeit erledigt. Beide sind über HTTP adressierbar — beide auditierbar, beide von jedem Laptop oder Handy aus replaybar.

cron · Schedule registrieren
POST · einmal
# register the weekly renewal
curl -X POST \
  https://cron.containers.hoody.com/users/me/entries \
  -H "Content-Type: application/json" \
  -d '[ "schedule":"0 4 * * 0", "command":"curl -fsS https://exec.containers.hoody.com/scripts/certs/renew", "comment":"weekly TLS renewal", "enabled":true ]'

# response
HTTP/1.1 201 Created
{ "id":"7a92", "schedule":"0 4 * * 0", "enabled":true }
exec · scripts/certs/renew.ts
GET · läuft wöchentlich
// scripts/certs/renew.ts
// @mode serverless
// @timeout 120000

const domains = ["your-app.com", "api.your-app.com", ...];

for (const d of domains) {
  const cert = await acme.order(d);
  await fetch("/api/v1/proxy/cert/bundle", {
    method: "PATCH",
    body: JSON.stringify({ d, cert })
  });
}

return { "renewed": domains.length };

Zwei URLs, ein Sonntagmorgen, null SSH. Der Cron-Eintrag ist Daten — POST ihn einmal, und er ist da, bis du DELETE schickst. Das Exec-Skript ist eine Datei — ändere sie über die API, und der nächste Lauf nimmt die neue Logik. Nichts an dieser Schleife verlangt, dass eine Person an einer Maschine sitzt.

use-cases / cert-renewal-no-ssh / powers

Warum das die SSH-Crontab schlägt

Dasselbe Ergebnis — jede Woche ein erneuertes Zertifikat — mit drei Eigenschaften, die das alte Setup nie hatte.

AUTH · URL-TOKEN

Kein Private Key in ~/.ssh

Auth ist ein URL-Token, kein SSH-Key. Rotier ihn über die API, und der alte Token funktioniert überall gleichzeitig nicht mehr. Kein Agent-Forwarding, kein Bastion, keine Key-Datei, von der du vergessen hast, dass du sie vor drei Jahren auf eine CI-Box kopiert hast.

AUDIT · HTTP-TRACE

Jede Erneuerung ist ein Request-Log

Jeder Lauf ist eine Zeile im Cron-Log und eine Request-Zeile im Exec-Log. Grep, wer es getriggert hat, wann, welches Zertifikat, welcher Response-Code. Die 200 vom Proxy ist die Quittung, dass der Reload angekommen ist.

DEBUG · CURL DRY-RUN

Du SSHst nicht zum Debuggen

Spiel die Erneuerung von deinem Laptop aus mit `curl /scripts/certs/renew?dry_run=true` nach. Schau dir die Antwort an, fix das Skript über die Exec-Write-API, versuch's nochmal. Die ganze Schleife läuft über HTTPS — dieselbe Leitung, die der Produktions-Schedule benutzt.

use-cases / cert-renewal-no-ssh / capacity

Was du dir gespart hast

Zahlen aus dem Deployment, keine Benchmarks. Die Form ist, was zählt: sehr wenige bewegliche Teile, alle sprechen HTTP.

  1. SSH-SESSIONS0

    Setup ist ein POST. Erneuerung ist ein GET nach Schedule. Debug ist ein curl. Es gibt zu keinem Zeitpunkt eine Shell-Session in der Pipeline — dein Private Key muss nie auf der Box liegen.

  2. BENUTZTE ENDPOINTS2

    Ein Cron-Eintrag, um den Lauf zu planen. Eine Exec-Route, die das Skript ausführt. Die dritte URL — der Proxy-Bundle-PATCH — lebt im Skript und lädt das Zertifikat neu.

  3. FELDER · CRON-SCHEDULE5

    Standard-5-Feld-Ausdruck "0 4 * * 0" — Sonntag 04:00. Oder `@weekly`, wenn dir der Tag egal ist. Der Cron-Service akzeptiert beides, plus Auto-Expiration für One-Shot-Erneuerungen.

Cron-Service: 5-Feld-Ausdrücke und Macros (`@hourly`, `@daily`, `@weekly`, `@monthly`, `@yearly`), Pro-User-Isolation, optionales `expires_at`. Exec: V8-Isolates, Bun-Runtime, Magic Comments für Mode/Timeout/CORS. ACME-Flow läuft in deinem Skript — Hoody führt certbot nicht für dich aus, Hoody führt deinen Code nach Schedule aus.

use-cases / cert-renewal-no-ssh / punchline

Erneuerung ist ein curl nach Schedule — keine Shell-Session, kein Key, kein Jump-Host.

alt · Samstag bevor die Zertifikate ablaufenneu · der Cron läuft seit neun Monaten
WIE DER ALTE STACK AUSSAHssh prod && certbot renew && systemctl reload nginxKey in ~/.ssh · Bastion davor · Hoffnung, dass die Cron-Zeile den letzten Reboot überlebt hat
WIE ES JETZT AUSSIEHT
Exec-Docs lesen
use-cases / cert-renewal-no-ssh / replaces

Was das ersetzt

Die üblichen Wege, um TLS in Produktion gültig zu halten. Jeder davon will entweder eine Shell-Session, einen Control-Plane-Service oder beides. Das Cron-plus-Exec-Paar will keines von beiden.

  • SSH + manueller certbotEine Shell-Session, ein Key, ein Renew-Schritt, den du im Urlaub vergisst
  • ssh-Bastion + SkriptEin Jump-Host, den du nur für ein Einzeiler-Skript pflegst
  • AWS Certificate Manager (closed-loop)Kostenlos, aber nur auf AWS — und das Zertifikat verlässt deren Proxy nie
  • HashiCorp Vault PKIEin ganzer Secrets-Daemon, um Zertifikate auszustellen, die du einmal die Woche erneuerst
  • cert-manager auf KubernetesEin Controller, ein CRD, ein Webhook — für das, was zwei HTTP-Calls sind
  • selbstgebaute Renewal-Cron- + Jump-Host-PipelineGlue-Skripte auf einem Bastion, ein Key pro CI-Runner, kein Audit-Trail
use-cases / cert-renewal-no-ssh / cta

Hör auf, dich einzuloggen, um Zertifikate zu erneuern. POSTe den Schedule einmal. Schau zu, wie sich der Proxy jeden Sonntagmorgen selbst neu lädt.

Kit-Docs lesen
use-cases / cert-renewal-no-ssh / related

Lies die anderen