Transportsicherheit

Im vorherigen Topic hast du gesehen, was APIs sind, wie Anwendungen über definierte Schnittstellen miteinander kommunizieren und warum insbesondere webbasierte APIs heute eine so große Rolle spielen.

Damit entsteht aber auch eine wichtige Sicherheitsfrage:

„Wenn Anwendungen über APIs Daten austauschen – wie sorgen wir eigentlich dafür, dass niemand diese Kommunikation mitlesen oder manipulieren kann?“

„Der erste Schritt ist derselbe wie bei einer Webanwendung: Wir verschlüsseln die Verbindung mit TLS. Bei APIs ist das besonders wichtig, weil darüber nicht nur Daten, sondern häufig auch Zugangsdaten wie API-Keys oder Tokens übertragen werden.“

Webbasierte APIs verwenden in der Regel HTTP als Grundlage. Entsprechend gelten viele der Sicherheitsmechanismen, die du bereits bei Webanwendungen kennengelernt hast, auch hier. Eine API sollte daher ausschließlich über HTTPS erreichbar sein. Ohne TLS könnten beispielsweise

  • API-Keys,
  • Access Tokens,
  • Benutzerdaten oder
  • andere vertrauliche Informationen

auf dem Transportweg mitgelesen oder manipuliert werden. Das gilt nicht nur für öffentlich erreichbare APIs. Auch die Kommunikation zwischen internen Systemen sollte verschlüsselt werden. Ein internes Netzwerk allein ist keine ausreichende Vertrauensbasis. TLS löst allerdings zunächst nur einen Teil des Problems.

Bei einer normalen HTTPS-Verbindung weist der Server mit seinem Zertifikat seine Identität gegenüber dem Client nach. Der Client kann also beispielsweise prüfen, ob er tatsächlich mit api.novahealth-solutions.de verbunden ist. Aber woher weiß die API, wer der Client ist?

Dafür benötigen wir eine Authentifizierung des Clients. Eine Möglichkeit dafür ist Mutual TLS.

Beim normalen TLS-Handshake authentifiziert sich üblicherweise nur der Server mit einem Zertifikat. Bei Mutual TLS – kurz mTLS – funktioniert die Authentifizierung dagegen in beide Richtungen. Nicht nur der Server besitzt also ein Zertifikat. Auch der Client muss ein gültiges Client-Zertifikat vorweisen.

Stell dir beispielsweise vor, der Laborservice der NovaHealth übermittelt Laborwerte über eine API an das zentrale Patientensystem. Ohne mTLS weiß der Laborservice zwar, ob er mit der richtigen API kommuniziert, da serverseitig bei TLS immer ein Zertifikat geliefert wird. Aber die API weiß damit noch nicht, wer da mit ihr spricht und ob es sich um einen zugelassenen Laborservice handelt. Liefert die Clientseite nun aber auch ein Zertifikat, ist ihre Identität sichergestellt:

„Aber könnte sich der Laborservice nicht einfach mit einem Passwort oder einem API-Key anmelden?“

„Doch. mTLS ersetzt solche Verfahren nicht grundsätzlich. Der entscheidende Unterschied ist, dass die Gegenstelle bereits beim Aufbau der TLS-Verbindung ein Zertifikat vorweisen muss. Damit können wir technische Systeme sehr zuverlässig gegenseitig authentifizieren. Unabhängig davon können weitere Verfahren zur Anwendung kommen.“

mTLS eignet sich besonders für kontrollierte Umgebungen, in denen die beteiligten Systeme bekannt sind. Ein typisches Beispiel ist die Service-zu-Service-Kommunikation.

In einer Microservice-Architektur können zahlreiche Services über APIs miteinander kommunizieren:

Mit mTLS kann jeder Service eine eigene kryptografische Identität erhalten. Ein Service akzeptiert dann nur Verbindungen von Clients, deren Zertifikate von einer vertrauenswürdigen CA ausgestellt wurden.

Das passt auch zum Zero-Trust-Prinzip, das du bereits aus Modul B1 kennst: Ein System wird nicht allein deshalb als vertrauenswürdig betrachtet, weil es sich im internen Netzwerk befindet. Seine Identität wird überprüft. In Kubernetes-Umgebungen kann diese Aufgabe beispielsweise von einem Service Mesh übernommen werden.

Ein Service Mesh ist eine zusätzliche Infrastrukturschicht, die die Netzwerkkommunikation zwischen den einzelnen Services zentral steuert und absichert. Statt dass jeder Microservice Funktionen wie Verschlüsselung, gegenseitige Authentifizierung, Traffic-Steuerung oder Monitoring selbst implementieren muss, übernimmt diese Aufgaben das Service Mesh.

Technisch wird dazu die Kommunikation der Services über spezielle Proxys geleitet. Das Service Mesh kann dadurch beispielsweise dafür sorgen, dass sich die beteiligten Services gegenseitig authentifizieren und ihre Verbindungen automatisch mit mTLS verschlüsseln. Für die eigentliche Anwendung kann dies weitgehend transparent erfolgen – der Anwendungscode muss dafür nicht eigens eine mTLS-Verbindung implementieren. Die nachfolgende Abbildung verdeutlicht das Konzept:

Bekannte Service-Mesh-Lösungen sind Istio und Linkerd. Nachfolgend ein paar Erläuterungen zu den beiden Lösungen zum besseren Verständnis:

Istio unterstützt die automatische Verwendung von mTLS zwischen sogenannten Workloads innerhalb des Mesh.

Ein Workload ist in diesem Kontext eine Anwendung oder Anwendungskomponente, die Kubernetes ausführt und verwaltet. Die eigentlichen Programme laufen dabei in Containern, die Kubernetes in Pods organisiert.

Linkerd aktiviert standardmäßig mTLS für die TCP-Kommunikation zwischen in das Mesh eingebundenen Pods und stellt den beteiligten Sidecar-Proxys kurzlebige Zertifikate zur Verfügung, die automatisch erneuert werden.

Ein Sidecar-Proxy ist ein kleiner Proxy, der direkt neben einem Microservice läuft und dessen Netzwerkkommunikation übernimmt. „Sidecar“ heißt er, weil er den eigentlichen Service wie ein Beiwagen begleitet – in Kubernetes laufen Anwendung und Proxy typischerweise gemeinsam im selben Pod.

Ein Beispiel hierfür ist Envoy. Envoy ist ein quelloffener, leistungsfähiger Proxy, der speziell für moderne verteilte Anwendungen und Microservice-Architekturen entwickelt wurde.

Auch außerhalb interner Microservice-Architekturen kommt mTLS zum Einsatz. Beispielsweise verwenden bestimmte Payment-APIs mTLS zur Authentifizierung von Backend-Systemen. Dabei weist sich ein angebundenes System gegenüber der API mit einem Client-Zertifikat aus.

Mit curl könnte der Laborservice der NovaHealth beispielsweise so auf eine API zugreifen:

curl --cert labor-service.crt \
     --key labor-service.key \
     --cacert ca.crt \
     https://api.novahealth-solutions.de/patienten/laborwerte

Dabei haben die Parameter folgende Bedeutung:

  • --cert: Client-Zertifikat des Laborservices
  • --key: zum Client-Zertifikat gehörender privater Schlüssel
  • --cacert: CA-Zertifikat, anhand dessen curl das Zertifikat des Servers überprüft

Auf der anderen Seite prüft der Server das vom Client präsentierte Zertifikat. Dabei können unter anderem die Zertifikatskette, die Gültigkeitsdauer und die darin enthaltene Identität überprüft werden.

Wichtig ist dabei: Ein Client-Zertifikat sollte nicht einfach anhand des Common Name (CN) als vertrauenswürdig betrachtet werden. Entscheidend sind unter anderem eine gültige Zertifikatskette zu einer vertrauenswürdigen CA und die für die jeweilige PKI festgelegten Zertifikatsmerkmale.

mTLS bietet eine starke Möglichkeit, technische Kommunikationspartner zu authentifizieren. Es beantwortet beispielsweise die Frage: Ist das tatsächlich der zugelassene Laborservice?

Damit ist aber noch nicht automatisch geklärt, was dieser Laborservice innerhalb der API tun darf:

  • Darf er alle Patientendaten abrufen?
  • Darf er Laborwerte nur schreiben oder auch löschen?
  • Darf er überhaupt z.B. auf den Endpunkt /patienten zugreifen?

Das sind Fragen der Authentifizierung und insbesondere der Autorisierung auf Anwendungsebene.

💡 Merke: TLS schützt die API-Kommunikation. mTLS kann zusätzlich beide Kommunikationspartner mit Zertifikaten authentifizieren. Welche API-Funktionen ein Client anschließend verwenden darf, muss jedoch auf Anwendungsebene geregelt werden.

Und genau dort machen wir in den nächsten Themen weiter: Wir schauen uns an, mit welchen Verfahren sich Clients gegenüber einer API authentifizieren und wie der Zugriff auf API-Ressourcen kontrolliert werden kann. Zuvor wollen wir jedoch erst einmal sehen, ob du das aktuelle Thema mTLS verinnerlicht hast:

Nach oben scrollen