mTLS für Service-zu-Service REST-APIs einrichten
AI generated
{ }
GET
mTLS · Zero Trust · Microservices
mTLS für Service-zu-Service-APIs
Beide Seiten einer internen Verbindung per Zertifikat statt per API-Key authentifizieren

API-Keys für interne Service-zu-Service-Kommunikation haben ein strukturelles Problem: Ein gestohlener Key lässt sich von überall nutzen, ohne dass der Server merkt, dass die Anfrage nicht vom erwarteten Service stammt. Mutual TLS löst das, indem beide Seiten der Verbindung sich gegenseitig per Zertifikat ausweisen, nicht nur der Server gegenüber dem Client.

16 Min. Lesezeit Mutual TLS · Zero Trust Zertifikate · PKI

1. Warum API-Keys für interne Kommunikation nicht genug sind

Bei klassischem TLS weist sich nur der Server gegenüber dem Client aus: Der Client prüft das Serverzertifikat, aber der Server hat keine kryptografische Garantie, wer tatsächlich auf der anderen Seite der Verbindung sitzt, außer was in einem übertragenen API-Key oder Bearer-Token steht. Wird dieser Key kompromittiert, etwa durch ein Leck in einer Konfigurationsdatei oder einem kompromittierten Container, kann der Angreifer sich damit von jedem beliebigen Ort als legitimer Service ausgeben, ohne dass der angesprochene Server das ohne zusätzliche Prüfungen erkennen könnte.

Mutual TLS (mTLS) erweitert den TLS-Handshake um eine zweite Richtung: Auch der Client präsentiert ein Zertifikat, das der Server gegen eine vertrauenswürdige Certificate Authority (CA) prüft. Ein Angreifer ohne das passende private Schlüsselmaterial kann selbst mit einem gestohlenen API-Key keine gültige Verbindung aufbauen, weil der TLS-Handshake selbst bereits fehlschlägt, lange bevor die Anwendungsebene überhaupt einen Request sieht.

2. Die eigene Zertifizierungsstelle als Vertrauensanker

Für internes mTLS zwischen eigenen Services wird üblicherweise eine eigene, interne Certificate Authority betrieben statt öffentlicher CAs wie Let's Encrypt zu nutzen, weil interne Service-Namen (order-service.internal) ohnehin nicht öffentlich auflösbar sind und öffentliche CAs solche Namen nicht signieren würden. Diese interne CA signiert sowohl Server- als auch Client-Zertifikate für jeden Service in der Infrastruktur.

Der Aufbau einer eigenen PKI (Public Key Infrastructure) klingt aufwendiger, als es mit modernen Tools tatsächlich ist. Werkzeuge wie HashiCorp Vaults PKI-Secrets-Engine oder cert-manager in Kubernetes automatisieren Ausstellung, Erneuerung und Widerruf von Zertifikaten vollständig, sodass ein einzelnes Team die interne CA nicht manuell mit OpenSSL-Kommandos pflegen muss.


# Interne CA und Service-Zertifikat mit Vault PKI erzeugen (vereinfacht)
vault secrets enable pki
vault secrets tune -max-lease-ttl=87600h pki

vault write pki/root/generate/internal \
    common_name="internal-ca.mironsoft.local" \
    ttl=87600h

vault write pki/roles/order-service \
    allowed_domains="order-service.internal" \
    allow_subdomains=true \
    max_ttl="720h"

# Zertifikat fuer den order-service ausstellen
vault write pki/issue/order-service \
    common_name="order-service.internal" \
    ttl="720h"

3. mTLS in Symfony-Clients und -Servern konfigurieren

Auf Client-Seite konfiguriert Symfonys HttpClient-Komponente das eigene Client-Zertifikat und den privaten Schlüssel über die Optionen local_cert und local_pk, zusätzlich zur regulären TLS-Verifizierung des Server-Zertifikats über die interne CA. Auf Server-Seite muss der Webserver (Nginx, Apache) so konfiguriert werden, dass er ein Client-Zertifikat verlangt und gegen die interne CA prüft, bevor die Anfrage überhaupt an die Symfony-Anwendung weitergereicht wird.

Die eigentliche Symfony-Anwendung erhält Informationen über das validierte Client-Zertifikat üblicherweise über vom Webserver gesetzte Header (z.B. X-SSL-Client-DN), aus denen sich die Identität des aufrufenden Services ableiten lässt, etwa für feingranulare Autorisierungsentscheidungen jenseits der reinen Verbindungsauthentifizierung.


<?php
// Symfony HttpClient mit mTLS-Client-Zertifikat konfigurieren
use Symfony\Component\HttpClient\HttpClient;

$client = HttpClient::create([
    'local_cert' => '/etc/certs/order-service.pem',
    'local_pk' => '/etc/certs/order-service.key',
    'cafile' => '/etc/certs/internal-ca.pem',
    'verify_peer' => true,
    'verify_host' => true,
]);

$response = $client->request('GET', 'https://pricing-service.internal/api/prices/SKU-123');

4. Zertifikatsrotation ohne Downtime

Zertifikate sollten kurzlebig sein, typischerweise Tage statt Jahre, um das Zeitfenster eines kompromittierten Zertifikats zu minimieren. Kurzlebige Zertifikate erfordern aber automatisierte Erneuerung, denn ein manueller Rotationsprozess für hunderte Services alle paar Tage ist praktisch nicht durchführbar und würde regelmäßig zu Ausfällen durch abgelaufene Zertifikate führen.

Tools wie cert-manager in Kubernetes oder ein Vault-Agent-Sidecar erneuern Zertifikate automatisch vor Ablauf und legen sie an einer definierten Stelle im Dateisystem ab, ohne dass der Service selbst neu gestartet werden muss, solange die Anwendung das Zertifikat bei jeder neuen Verbindung neu vom Dateisystem liest statt es dauerhaft im Speicher zu cachen.

5. mTLS als Baustein einer Zero-Trust-Architektur

mTLS ist ein zentraler Baustein des Zero-Trust-Sicherheitsmodells, bei dem kein impliziertes Vertrauen allein aufgrund der Netzwerkposition existiert, etwa 'im internen Netzwerk, also vertrauenswürdig'. Stattdessen muss jede Verbindung, auch innerhalb desselben internen Netzwerks, kryptografisch authentifiziert werden, unabhängig davon, ob der Traffic ein internes oder externes Netzwerksegment durchläuft.

Diese Denkweise wird zunehmend relevant, weil klassische Netzwerksegmentierung allein nicht mehr als ausreichende Sicherheitsgrenze gilt, insbesondere in Cloud-Umgebungen mit dynamischer Infrastruktur, wo IP-Adressen sich häufig ändern und eine reine IP-basierte Zugriffskontrolle unzuverlässig wird. Ein Angreifer, der einen einzelnen Container innerhalb des internen Netzwerks kompromittiert, soll sich in einer echten Zero-Trust-Architektur eben nicht frei zu allen anderen internen Services bewegen können.

6. Service-Mesh als Alternative zur manuellen mTLS-Implementierung

Statt mTLS in jedem einzelnen Service manuell zu implementieren, übernehmen Service-Mesh-Lösungen wie Istio oder Linkerd die gesamte mTLS-Verwaltung transparent über Sidecar-Proxys: Jeder Service bekommt einen Proxy zur Seite gestellt, der den gesamten ein- und ausgehenden Traffic automatisch über mTLS verschlüsselt und authentifiziert, ohne dass der Anwendungscode selbst etwas davon mitbekommt.

Der Vorteil ist deutlich weniger Boilerplate-Code in jedem einzelnen Service und zentrale Kontrolle über mTLS-Richtlinien. Der Nachteil ist zusätzliche Infrastruktur-Komplexität durch das Service-Mesh selbst, was für kleinere Systemlandschaften mit wenigen Services den Aufwand oft nicht rechtfertigt und zunächst mit direkter Symfony-Konfiguration begonnen werden sollte.

7. Häufige Fallstricke bei der praktischen Einführung

Ein häufiger Fehler ist, Zertifikatsablaufdaten nicht proaktiv zu überwachen: Ein abgelaufenes Zertifikat führt zu plötzlichen Verbindungsfehlern zwischen Services, die auf den ersten Blick wie ein Netzwerkproblem statt wie eine Zertifikatsfrage aussehen. Ein Monitoring-Alarm, der einige Tage vor Ablauf eines Zertifikats warnt, verhindert solche produktiven Überraschungen zuverlässig und deutlich günstiger als eine nächtliche Fehlersuche im laufenden Betrieb.

Ein zweiter verbreiteter Fehler ist unzureichendes Zertifikatswiderruf-Handling: Wenn ein Service kompromittiert wird, muss dessen Zertifikat sofort widerrufen werden können, nicht erst nach dessen natürlichem Ablauf. Eine funktionierende Certificate Revocation List (CRL) oder OCSP-Prüfung ist deshalb kein optionales Detail, sondern integraler Bestandteil einer produktionsreifen mTLS-Einführung, der von Anfang an mitgeplant werden sollte statt ihn nachträglich zu ergänzen.

8. mTLS-Verbindungsfehler systematisch eingrenzen

mTLS-Fehler äußern sich meist als generische TLS-Handshake-Fehler ohne aussagekräftige Anwendungs-Fehlermeldung, was die Fehlersuche erschwert. Ein strukturiertes Vorgehen prüft zuerst mit openssl s_client, ob der Server überhaupt ein Client-Zertifikat anfordert, danach ob das präsentierte Client-Zertifikat gültig und von der erwarteten CA signiert ist, und erst danach die eigentliche Anwendungslogik.

Aussagekräftige Logs auf Webserver-Ebene (nicht erst in der Symfony-Anwendung) sind entscheidend, weil ein fehlgeschlagener TLS-Handshake die Anwendung selbst nie erreicht. Nginx und Apache bieten beide detaillierte SSL-Debug-Logs, die genau anzeigen, an welcher Stelle des Handshakes die Verbindung abgelehnt wurde, etwa wegen eines abgelaufenen oder nicht vertrauenswürdigen Client-Zertifikats.


# mTLS-Verbindung manuell testen und Fehler eingrenzen
openssl s_client -connect order-service.internal:443 \
    -cert /etc/certs/pricing-service.pem \
    -key /etc/certs/pricing-service.key \
    -CAfile /etc/certs/internal-ca.pem

# Zertifikat auf Gueltigkeit und Aussteller pruefen
openssl x509 -in /etc/certs/pricing-service.pem -noout -dates -issuer

9. mTLS im Vergleich zu anderen Service-Authentifizierungsverfahren

Die folgende Tabelle stellt mTLS anderen verbreiteten Ansätzen zur Service-zu-Service-Authentifizierung gegenüber, um die Wahl für das eigene System zu erleichtern.

Verfahren Schutz bei gestohlenem Secret Implementierungsaufwand Typischer Einsatz
API-Key Kein Schutz, sofort nutzbar Niedrig Einfache interne Setups, geringe Sicherheitsanforderungen
Bearer-Token/JWT Kein Schutz bis Ablauf Mittel Häufigster Standard für interne APIs
mTLS Hoch, privater Schlüssel bleibt nötig Hoch ohne Service-Mesh Zero-Trust-Anforderungen, regulierte Branchen
mTLS via Service-Mesh Hoch, transparent verwaltet Mittel (Mesh-Setup einmalig) Größere Microservice-Landschaften

Mironsoft

OpenAPI-Design, Symfony-APIs und API-Sicherheit

APIs, die externe Teams ohne Rückfragen integrieren können?

Wir prüfen bestehende REST-APIs auf inkonsistente Fehlerformate, fehlende OpenAPI-Dokumentation und Sicherheitslücken und bauen daraus eine API, die klar dokumentiert, versioniert und gegen Missbrauch abgesichert ist.

API-Review

OpenAPI-Spezifikation, Fehlerformate und Statuscodes auf Konsistenz prüfen.

Symfony-Umsetzung

DTOs, Serializer und Validator für saubere, typsichere Request/Response-Modelle einsetzen.

Security-Audit

Rate-Limiting, Auth-Schemes und Input-Validierung gegen echte Angriffsflächen absichern.

10. Zusammenfassung

mTLS für Service-zu-Service-APIs: Das Wichtigste auf einen Blick

Kernprinzip

Beide Seiten der Verbindung authentifizieren sich per Zertifikat, nicht nur der Server gegenüber dem Client.

PKI-Aufbau

Eine interne Certificate Authority signiert Zertifikate für alle Services, automatisiert über Vault oder cert-manager.

Rotation

Kurzlebige Zertifikate mit automatisierter Erneuerung minimieren das Risiko-Zeitfenster kompromittierter Schlüssel.

Service-Mesh

Istio oder Linkerd übernehmen mTLS transparent per Sidecar, reduzieren Boilerplate-Code in jedem einzelnen Service erheblich.

11. FAQ: mTLS für Service-zu-Service-APIs: Das Wichtigste auf einen Blick

1Was ist der Unterschied zwischen TLS und mTLS?
Bei TLS weist sich nur der Server per Zertifikat aus. Bei mTLS (Mutual TLS) präsentieren beide Seiten der Verbindung ein Zertifikat, das die jeweils andere Seite gegen eine vertrauenswürdige CA prüft.
2Brauche ich eine öffentliche CA für interne mTLS-Zertifikate?
Nein, für interne Service-Namen wird üblicherweise eine eigene, interne Certificate Authority betrieben, da öffentliche CAs interne, nicht auflösbare Domainnamen ohnehin nicht signieren.
3Wie oft sollten mTLS-Zertifikate erneuert werden?
Kurzlebige Zertifikate im Bereich von Tagen statt Jahren minimieren das Zeitfenster eines kompromittierten Zertifikats. Das erfordert automatisierte Erneuerung über Tools wie Vault oder cert-manager.
4Ersetzt mTLS API-Keys und JWTs komplett?
mTLS authentifiziert die Verbindung auf Transportebene. Für feingranulare Autorisierung (welche Aktionen darf dieser Service konkret ausführen) wird oft trotzdem zusätzlich ein Token oder Scope-System auf Anwendungsebene genutzt.
5Lohnt sich mTLS für ein kleines Symfony-Projekt mit zwei Services?
Bei sehr wenigen Services überwiegt oft der Konfigurationsaufwand den Sicherheitsgewinn gegenüber einem einfachen, gut geschützten API-Key. mTLS lohnt sich klarer ab einer größeren Anzahl an Services oder bei regulierten Branchen.
6Was passiert, wenn ein Zertifikat abläuft, ohne dass es erneuert wurde?
Die Verbindung schlägt beim TLS-Handshake fehl, was sich oft wie ein Netzwerkproblem statt wie eine Zertifikatsfrage anfühlt. Proaktives Monitoring auf bevorstehenden Zertifikatsablauf verhindert solche Überraschungen.
7Wie widerrufe ich ein kompromittiertes Zertifikat sofort?
Über eine Certificate Revocation List (CRL) oder OCSP-Prüfung, die der Server bei jedem Handshake gegen die aktuelle Widerrufsliste prüft, statt auf den natürlichen Ablauf des Zertifikats zu warten.
8Was ist ein Service-Mesh und wie hilft es bei mTLS?
Ein Service-Mesh wie Istio oder Linkerd stellt jedem Service einen Sidecar-Proxy zur Seite, der mTLS-Verschlüsselung und -Authentifizierung transparent übernimmt, ohne dass der Anwendungscode selbst etwas davon mitbekommt.
9Funktioniert mTLS auch über Cloud-Provider-Grenzen hinweg?
Ja, solange beide Seiten Zertifikate derselben vertrauenswürdigen CA-Hierarchie nutzen. Bei Multi-Cloud-Setups wird dafür oft eine übergreifende, zentrale PKI-Instanz betrieben.
10Ist mTLS ein Ersatz für Netzwerksegmentierung?
Nein, beide Maßnahmen ergänzen sich. Netzwerksegmentierung begrenzt, wer eine Verbindung überhaupt versuchen kann, mTLS stellt sicher, dass die Verbindung selbst kryptografisch authentifiziert ist.