Zurück zum Webship Blog

Webship-Ingenieurwesen

TLS-Zertifikate in Webship: Die eingebettete ACME-CA

Sieh dir an, wie Webship 1.4.0 private TLS-Zertifikate pro Seite mit seiner eingebetteten CA ausstellt und rotiert, wie das Vertrauen der Clients funktioniert und wie eingebettete Identitäten mit öffentlichen ACME- und manuellen Zertifikaten koexistieren.

# TLS-Zertifikate in Webship: Die eingebettete ACME-CA

Ein TLS-Zertifikat erfüllt zwei Aufgaben: Es hilft, eine Verbindung zu verschlüsseln, und teilt dem Client mit, mit welcher Identität er spricht. Die Verschlüsselung kann stark sein, während die Vertrauensentscheidung für das Publikum falsch ist. Deshalb muss die Zertifikatsautomatisierung mit einer Frage beginnen: Wer muss dieser Website vertrauen?

Webship 1.4.0 trifft diese Wahl unabhängig für jede konfigurierte Website. Eine öffentliche Website kann ein von Browsern vertrautes ACME-Zertifikat verwenden, ein interner Dienst kann Webships eingebettete private Zertifizierungsstelle nutzen, und eine Website mit einer bestehenden PKI kann von Betreibern verwaltete Zertifikatsdateien behalten. Sie alle können einen Webship-Prozess gemeinsam nutzen, ohne einen privaten Schlüssel oder eine Vertrauensgrenze zu teilen.

Vier automatische Zertifikatsmodi, die pro Standort ausgewählt werden

Das Feld certificate_mode gehört zu jedem [[sites]]-Eintrag. Es ist kein globaler Schalter.

| Modus | Vertrauensquelle | Beste Passform | Validierungspfad | | --- | --- | --- | --- | | per_site | Öffentliche Browser- und Betriebssystem-Trust-Stores | Eine öffentliche Website mit genau einem Hostnamen | Öffentlicher ACME mit TLS-ALPN-01 | | Flotte | Öffentliche Browser- und Betriebssystem-Trust-Stores | Große Mengen an dritten- und vierten-Level-Namen unter explizit registrierten Domains | Öffentliches ACME mit DNS-01 und stabilen Zertifikatsfragmenten | | eingebettet | Ein privater Webship-Root, der vom Betreiber installiert wurde | Interne Dienste, verwaltete Geräte, private Flotten und Testumgebungen | Ausstellung im Prozess; keine externe Überprüfung | | gemeinsam | Öffentliche Browser- und Betriebssystem-Truststores | Legacy-Deployments, die absichtlich eine öffentliche Multi-SAN-Gruppe verwenden | Öffentliche ACME mit TLS-ALPN-01 |

Die Standardeinstellung ist pro_site. Es wird ein öffentliches Zertifikat für den genauen Namen der Website angeordnet. Der Flottenmodus ist die skalierbare öffentliche Option für viele tiefe Subdomains. Der eingebettete Modus verwendet Webships private In-Process-CA. Der geteilte Modus bleibt zur Kompatibilität verfügbar, ist jedoch nicht die Standardeinstellung.

Ein vollständiges Zertifikat und ein Schlüssel unter [sites.tls] haben immer Vorrang vor der automatischen Ausstellung für diese Site.

Was „eingebettetes ACME-CA“ bedeutet

Der Konfigurationsabschnitt heißt [acme_ca], aber die eingebettete CA ist kein öffentliches oder netzwerkzugängliches ACME-Dienst. Sie stellt keinen Verzeichnispunkt bereit, akzeptiert keine Remote-Einschreibung, ruft keine Registrar-API auf und führt keine Kontrolle-nachweisende Challenge durch.

Stattdessen behält Webship den gesamten privaten Ausgabepfad in einem Prozess:

  1. Die Seite wählt certificate_mode = "embedded" aus.
  2. Webship lädt oder erstellt die private Root-Identität im konfigurierten Zustandsverzeichnis.
  3. Webship generiert einen neuen privaten Schlüssel für die Website.
  4. Das eingebettete Root-Zertifikat unterschreibt ein Blattzertifikat für genau diesen Namen.
  5. Webship überprüft die abgeschlossene Identität, bevor sie im live TLS-Resolver installiert wird.
  6. Das Zertifikat steht dann jedem für diese Website aktivierten Protokoll zur Verfügung.

Eine ACME-ähnliche Netzwerkherausforderung würde Webship nur sich selbst beweisen, daher hat der eingebettete Pfad absichtlich kein Netzwerkprotokoll. Der Abschnitt [acme_ca] ist privater PKI-Status: Er definiert, wo die Root liegt und wie lange ausgestellte Leaf-Zertifikate gültig bleiben.

Konfigurieren Sie ein eingebettetes Zertifikat für eine Website

Dies ist die minimale Form für eine private Seite:

~~~toml listen = "0.0.0.0:443"

[tls] unknown_sni = "ablehnen"

[automatisches_tls] aktiviert = wahr cache_dir = "/var/lib/webship/acme"

[acme_ca] state_dir = "/var/lib/webship/acme-ca" blatt_gültigkeit_tage = 90

[[Stätten]] domain = "service.internal.example" root = "/srv/service" certificate_mode = "eingebettet"

[sites.protokolle] h1 = wahr h2 = wahr h3 = wahr ~~~

Die Stammidentität wird lazy erstellt, wenn eine eingebettete Seite sie zum ersten Mal benötigt. Webship speichert den Stamm-Schlüssel mit restriktiven Berechtigungen im state_dir. Das Stammzertifikat hat eine Laufzeit von zehn Jahren; die Laufzeit des Leaf wird durch leaf_validity_days kontrolliert.

Behandeln Sie beide Speicherorte als Produktionszustand:

  • Der ACME-Cache enthält automatisch verwaltete Standortidentitäten.
  • Das eingebettete CA-Statusverzeichnis enthält die private Root-Identität.
  • Das Dienstkonto benötigt Zugriff, aber Anwendungbenutzer nicht.
  • Backups müssen die Vertraulichkeit und die Datei-Berechtigungen wahren.
  • Produktion, Entwicklung und Test sollten separate Wurzeln und separate Verzeichnisse verwenden.

Das Löschen des Stammverzeichnisses „setzt TLS nicht zurück“. Es erstellt einen neuen Vertrauensanker. Clients, die dem alten Stamm vertrauen, lehnen Zertifikate ab, die vom Ersatz ausgestellt wurden, bis ihre Vertrauensspeicher aktualisiert sind.

Privates Vertrauen ist absichtlich

Zertifikate der eingebetteten CA werden von öffentlichen Browsern oder Betriebssystemen nicht automatisch als vertrauenswürdig eingestuft. Sie werden erst dann vertraut, nachdem der Betreiber das exportierte Webship-Stammzertifikat im Vertrauensspeicher des Clients installiert hat.

Das macht den eingebetteten Modus zu einer guten Wahl für:

  • Unternehmensverwaltete Laptops und Telefone, die über die Gerätemanagement registriert sind;
  • interner Service-zu-Service-Verkehr mit einem expliziten CA-Bündel;
  • private Geräte und kontrollierte Randflotten;
  • Entwicklungs- und Testumgebungen, die echtes TLS-Verhalten ausführen müssen;
  • Getrennte Netzwerke, die sich nicht auf eine öffentliche CA verlassen können.

Es ist nicht der richtige Modus für eine normale öffentliche Website, deren Besucher unverwaltete Browser verwenden. Verwenden Sie die öffentliche pro-Site-Ausgabe für einen genauen öffentlichen Namen, eine Flottenausgabe für große öffentliche Subdomain-Sets, nur gemeinsam genutzt für eine gezielte Legacy-Multi-SAN-Bereitstellung oder manuelle Dateien von einer bereits vertrauenswürdigen PKI.

Verteilen Sie nur das Stammzertifikat an die Clients. Verteilen Sie niemals den privaten Root-Schlüssel. Der Besitz dieses Schlüssels gibt seinem Inhaber die Befugnis, Identitäten auszustellen, die von jedem eingeschriebenen Client vertraut werden.

Öffentliche und private Zertifikate können koexistieren

Webship 1.4.0 kann Zertifikatsstrategien am selben Listener mischen:

~~~toml listen = "0.0.0.0:443"

[tls] unknown_sni = "ablehnen"

[automatisches_tls] aktiviert = wahr directory_url = "https://acme-v02.api.letsencrypt.org/directory" cache_dir = "/var/lib/webship/acme" kontakte = ["mailto:ops@example.com"] bedingungen_der_nutzung_akzeptieren = wahr

[acme_ca] state_dir = "/var/lib/webship/acme-ca" blatt_gültigkeitstage = 90

[[Stätten]] domain = "www.example.com" root = "/srv/public" certificate_mode = "pro_site"

[[Stätten]] domain = "control.internal.example" root = "/srv/control" certificate_mode = "eingebettet"

[[Stätten]] domain = "payments.example.com" root = "/srv/payments"

[sites.tls] cert = "/etc/webship/payments-fullchain.pem" key = "/etc/webship/payments-private-key.pem" ~~~

Hier erhält www.example.com sein eigenes öffentliches ACME-Zertifikat. control.internal.example erhält ein privates Zertifikat von der eingebetteten CA. payments.example.com bleibt unter der externen PKI des Betreibers, da seine expliziten Dateien Vorrang haben.

Das öffentliche ACME-Verzeichnis wird von eingebetteten Sites ignoriert. Die eingebettete Root signiert die öffentliche Site nie. Die manuelle Site wird niemals stillschweigend in einen der automatischen Workflows aufgenommen.

Ein Zertifikat-Resolver für H1, H2, H3 und WebTransport

Die Zertifikatsauswahl erfolgt während des TLS-Handshakes, bevor eine HTTP-Anfrage existiert. Webship verwendet den Servernamen aus dem ClientHello, um die Website-Identität auszuwählen, und verhandelt dann das Anwendungsprotokoll.

  • HTTP/1.1 und HTTP/2 verwenden TLS über TCP.
  • HTTP/3 und WebTransport verwenden TLS innerhalb von QUIC über UDP.
  • Eine gültige Website-Identität kann jedem aktivierten Protokoll dienen.
  • HTTP/3 erfordert ebenfalls die Erreichbarkeit über UDP; H1 und H2 nutzen den TCP-Pfad.
  • Alt-Svc kann H3 bewerben und gleichzeitig einen TCP-Fallback beibehalten.

TCP, TLS und QUIC verwenden dasselbe standortbewusste Identitätsmodell. Exakte Namen haben Vorrang, das längste gültige Wildcard-Zertifikat gewinnt dort, wo Wildcard-Zertifikate konfiguriert sind, und unbekannte benannte SNI können abgelehnt werden, anstatt ein unzusammenhängendes Standardzertifikat zu erhalten.

Verwenden Sie unknown_sni = "reject" auf einem Multi-Site-Listener, wenn ein nicht erkannter Hostname geschlossen fehlschlagen muss. Testen Sie erkannte Namen, nicht erkannte Namen und Ihr erwartetes No-SNI-Verhalten vor der Produktionsbereitstellung.

Eingebettete Identitäten ohne Unterbrechung rotieren

Webship stellt den Zertifikatsstatus und kontrollierte Mutationen über seinen authentifizierten, auf Loopback gebundenen MCP-Server bereit:

  • webship.tls.get_status berichtet über den aktiven Zertifikatsauflöser und den Erneuerungszustand.
  • webship.tls.reissue_certificate stellt ein automatisch verwaltetes Zertifikat sofort nur dann neu aus, wenn diese Website im eingebetteten Modus verwendet wird.
  • webship.tls.reload lädt den Zertifikatsstatus über den normalen geschützten TLS-Pfad neu.
  • webship.acme_ca.status meldet, ob die private CA ausgewählt ist, ihr Zustandsverzeichnis, die Lebensdauer der Zertifikate, die Anzahl der ausgestellten Zertifikate, die Anzahl der Widerrufe und eine kürzliche Domainprobe.
  • webship.sites.apply fügt Sites zu einer angehefteten Konfigurationsversion hinzu oder entfernt sie davon.

Für eine eingebettete Neuauflage erstellt und validiert Webship die Ersatzidentität, bevor sie in den Dienst übernommen wird. Die derzeit gültige Identität bleibt in Betrieb, bis die neue Identität bereit ist. Die ausgemusterte Identität wird erst aufgezeichnet, nachdem der Ersatz installiert wurde.

Die sofortige Neuausstellungsvorgang lehnt absichtlich öffentliche per_site-Zertifikate ab. Die öffentliche Erneuerung muss innerhalb des öffentlichen ACME-Lebenszyklus bleiben, anstatt mit der privaten, laufenden Signierung verwechselt zu werden. Die Mitgliedschaft im Shared-Modus ist ebenfalls startgefroren, da das Ändern einer Multi-SAN-Gruppe die Identitätsgrenze neu aufbaut.

MCP ist eine privilegierte Steuereinheit. Halten Sie sie im Loopback-Modus, verlangen Sie TLS und ein starkes Bearer-Token, verwenden Sie einen authentifizierten Tunnel für die Fernverwaltung und prüfen Sie jede Änderung.

Fehlergrenzen, die wichtig sind

Ein sicheres Zertifikatsystem muss in die richtige Richtung fehlschlagen.

  • Eine neu konfigurierte eingebettete Site erhält nicht die Identität einer anderen Site, während die Ausstellung aussteht.
  • Ein ungültiger Ersatz wird nicht über ein funktionierendes Zertifikat installiert.
  • Explizite Handbuchdateien verhindern die automatische Eigentümerschaft dieser Website.
  • Unbekanntes benanntes SNI kann vor der HTTP-Routing abgelehnt werden.
  • Die eingebettete CA bleibt privat und hat keinen entfernten Registrierungspunkt.
  • Öffentliche und eingebettete Identitäten verwenden innerhalb des automatischen TLS-Zustands separate Cache-Pfade.

Eine Warnung, dass die eingebettete CA nicht initialisiert ist, bedeutet, dass Webship das konfigurierte Statusverzeichnis nicht vorbereiten konnte. Beheben Sie Eigentumsrechte, Berechtigungen, Persistenz oder Speicherverfügbarkeit, bevor Sie Datenverkehr an die betroffene Site senden. Umgehen Sie den Fehler nicht, indem Sie den Root-Schlüssel einer anderen Umgebung kopieren.

Produktionscheckliste

Vor der Aktivierung des eingebetteten Modus:

  1. Identifizieren Sie jede Kundengruppe, die der Website vertrauen muss.
  2. Erstellen Sie einen kontrollierten Prozess für den Export und die Installation des Root-Zertifikats.
  3. Verwenden Sie einen separaten Stammzustand für Produktion, Entwicklung und Tests.
  4. Das eingebettete CA-Statusverzeichnis und den automatischen TLS-Cache beibehalten und schützen.
  5. Führen Sie Webship unter einem dedizierten Dienstkonto aus, das nur Zugriff auf das erforderliche Schlüsselmaterial hat.
  6. Wählen Sie certificate_mode auf jeder Website aus, deren Vertrauensgrenze explizit sein muss.
  7. Die Unknown-SNI-Richtlinie festlegen und testen.
  8. Aktivieren Sie H1, H2 und H3 gezielt und überprüfen Sie sowohl TCP- als auch UDP-Pfade.
  9. Übung zur Neuerteilung, zum Neustart, Backup, zur Wiederherstellung und Validierung des Kundenvertrauens außerhalb der Produktion.
  10. Führen Sie webship --check-config vor dem Rollout aus, und überprüfen Sie dann den Aussteller, die Namen, die Gültigkeit, die Kette und die ausgehandelten Protokolle von einem echten Client.

Wähle zuerst Vertrauen, dann Automatisierung

Die eingebettete CA entfernt eine externe Zertifikatsdienstabhängigkeit für private Infrastruktur. Sie macht eine private Root nicht global vertrauenswürdig und entfernt nicht die PKI-Verantwortlichkeiten des Betreibers.

Webship automatisiert die Schlüsselerzeugung, das Signieren, die Validierung, die Installation, die Rotation und die protokollweite Zertifikatsauswahl. Der Betreiber behält jedoch weiterhin die Root-Verwahrung, die Client-Registrierung, die Trennung der Umgebungen, Sicherung, Wiederherstellung und die Entscheidung, einen öffentlichen oder privaten Vertrauenspfad zu verwenden.

Diese Trennung ist das Merkmal. Ein eigenständiger Server kann privates TLS automatisieren, ohne vorzugeben, eine öffentliche CA zu sein – und öffentliche Websites können im selben Prozess weiterhin browser-vertrauenswürdige pro-Site- oder Flottenausstellung verwenden.

Lesen Sie die versionierte Webship 1.4.0 Dokumentation vor der Einführung. RFC 5280 definiert Zertifikatsprofile und Validierung, RFC 6066 definiert TLS-Servernamen-Signalisierung, RFC 8446 definiert TLS 1.3, RFC 8555 definiert öffentliches ACME, und RFC 9525 definiert die Überprüfung der Dienstidentität.