Das Netz der Zukunft: Protokollstandardisierung in der Sackgasse?
Ohne Netzwerkprotokolle gäbe es kein Internet. Organisationen wie IETF [1], OASIS [2] und W3C [3] haben sich zur Aufgabe gemacht, Standards für einen reibungslosen Datenverkehr im Internet festzulegen. Standards stehen für Stabilität und Verlässlichkeit, jedoch kaum für eine schnelle Veränderung, die in agilen Projekten und im Rahmen von Continuous Delivery/Deployment gefordert wird. Neue Entwicklungen wie das Internet of Things und verteilte Systeme mit Microservices bringen Anforderungen hervor, denen neue Standards gerecht werden sollen. Es entsteht jedoch ein unübersichtlicher Wald aus Lösungen für nicht genau definierte Probleme. Die Vielzahl von Standards lässt das Internet der Zukunft wie den Turmbau zu Babel erscheinen.
Dienstorientierte Protokolle
Jedes Netzwerkprotokoll wird definiert durch Regeln und Formate (Syntax), die das Kommunikationsverhalten (Semantik) der beteiligten Instanzen bestimmen [4]. Für viele Protokolle sind die Regeln und Formate für Syntax und Semantik als Internetstandard festgeschrieben. Ein Internetstandard ist eine Spezifikation, die einen großer Vorteil für das Internet darstellt, höchste Reife bewiesen hat und von einer breiten Öffentlichkeit unterstützt wird [5].
Die pragmatische Vorgehensweise bei der Standardisierung brachte mit TCP/IP einen soliden Protokollstack hervor. Generationen von erfahrenen Entwicklern verbesserten die Implementierungen der einzelnen Protokolle immer weiter, damit die Kommunikation schnell, fehlerfrei und unabhängig von Hardware und Betriebssystem verfügbar ist. Basierend auf den Transportprotokollen TCP und UDP, wurden dienstorientierte Anwendungsprotokolle für den Austausch von Daten zwischen Prozessen standardisiert.
Beispiele sind FTP für die Übertragung von Dateien, SMTP für den Versand von E-Mail und HTTP für die Übertragung von HTML-Dateien an einen Internetbrowser. Die Aufgabe dieser Protokolle ist klar umrissen und vollständig bekannt. Der Anwender kann ohne jeden Zweifel erkennen, welches Protokoll zu einem bestimmten Problem passt. Überschneidungen sind kaum vorhanden.
HTTP – Das universelle Protokoll
Natürlich können Protokolle für anderes als den ursprünglichen Zweck verwendet werden. In großem Stil geschieht dies mit HTTP. Die einfache Struktur des Protokolls und die geringe Festlegung auf ein bestimmtes Datenformat – alles kann übertragen werden, solange es Text ist – machen HTTP flexibel einsetzbar. Was dabei selten beachtet wird, sind die dynamischen Eigenschaften von HTTP, die bei kleinteiliger Maschine-zu-Maschine-Kommunikation zu einem Problem werden [6].
Einige dieser Eigenschaften haben ihre Ursache bereits im TCP Protokoll. Der Slow-Start-Algorithmus zur Vermeidung von Übertragungsfehlern durch zu häufiges Neu-Senden von Datenpaketen, verhindert die Nutzung der vollen Bandbreite direkt nach dem Aufbau einer Verbindung. Beim Versand kleiner Nachrichten über jeweils eine eigene Verbindung, kann deshalb die volle Bandbreite des Netzes nicht genutzt werden.
Ein weiteres Problem ist der Verbindungsaufbau von TCP mittels eines 3-Wege-Handshakes. Der Initiator (Client) schickt eine Anfrage an den Listener (Server), der daraufhin antwortet. Der Initiator muss die Antwort erneut bestätigen, damit die Verbindung zustande kommt.
Die Zeit die für das Senden eines Pakets bis zum Empfang einer Antwort benötigt wird (RTT – Round Trip Time), summiert sich. Weitere Round Trips kommen dazu, wenn die Verbindung via TLS abgesichert wird. Das Beenden einer TCP-Verbindung erfordert ebenfalls eine Kommunikation, die wiederum Zeit benötigt.
Mittels eines einfachen Experiments kann der Einfluss von TCP auf kleinteilige Kommunikation untersucht werden [7]. Abb.1 zeigt den Versuchsaufbau. Eine kleine Nachricht (wenige Zeichen) wird zu einem Server geschickt, der diese an den Client zurücksendet. Dabei wird entweder immer die gleiche TCP-Verbindung genutzt oder für jede Nachricht eine eigene aufgebaut und wieder geschlossen. Abb.2 zeigt, wie drastisch im letzteren Fall die Anzahl der Nachrichten pro Sekunde sinkt.
Head of Line Blocking
Die pragmatische Antwort auf das beschriebene Verhalten, wäre eine einzige Verbindung zu nutzen. Hier verhindert jedoch das so genannte Head of Line Blocking (HOLB) unter Umständen eine schnelle Reaktion des Systems. HTTP überträgt, wie die meisten Protokolle, eine Nachricht komplett, bevor die Nächste gesendet wird. Eine kleine, wichtige Nachricht muss dann warten, bis die vorherige, eventuell große Nachricht, fertig wird. Für den Benutzer ist nur erkennbar, dass das System blockiert.
Die moderne HTTP-Version HTTP/2 verwendet Multiplexing, um das HOLB-Problem zu vermeiden und eine asynchrone Kommunikation über eine einzelne TCP-Verbindung zu erreichen.
Das Dilemma
Das HTTP-Beispiel zeigt, wie sich ein für einen bestimmten Zweck entwickeltes und optimiertes Protokoll, für einen anderen Anwendungsfall als ungeeignet herausstellen kann. Recycling von bestehenden Standards für neue Aufgaben erhöht das Risiko, in einem Projekt die optimalen Ziele zu verfehlen oder gar zu scheitern. Das Dilemma dabei ist die unscharfe Definition der Leistungen, die Protokolle im Umfeld von IoT, Machine-to-Machine und neuen Architekturen wie Microservices bereitstellen müssen. Selbst wenn die Aufgaben im eigenen Projekt klar sind, ist es schwer, einen Standard zu finden, der exakt und nicht nur ungefähr dazu passt. Die Folge sind eine Vielzahl unterschiedlicher, jedoch ähnlicher neuer Standards, die wiederum Teilprobleme lösen. Die Lösung ist in Systemen deshalb oft der Einsatz von mehreren alternativen Protokollen.
Abb.3 zeigt die für OPC UA vorgesehenen Wege für die Kommunikation im Netz. OPC UA ist eine IoT-Standardarchitektur für Machine-to-Machine-Kommunikation. Obwohl der Austausch von Nachrichten über Internet-Standardprotokolle vorgesehen ist, wird ihnen ein proprietäres Nachrichtenprotokoll an die Seite gestellt.
"Engineers design protocols the way monkeys try to get to the moon that is, by climbing a tree, looking around, and finding another tree to climb." (Marshall T. Rose) [8]
Das Zitat von Marshall T. Rose bringt das Problem auf den Punkt. Es wird versäumt, bei der Entwicklung von Protokollen das gesamte Problemfeld zu untersuchen. Lediglich Einzelaspekte der eigenen Anwendung werden betrachtet. Die daraus resultierenden Standards, haben dann Eigenschaften wie Leichtgewichtigkeit, Einfachheit, Schnelligkeit und so weiter. Das sind sehr schwammige Attribute, die kaum Auskunft über die Leistungen geben und individuell interpretierbar sind. Was ist mit Asynchronität, Sicherheit, Erweiterbarkeit und Skalierbarkeit?
Veränderung ist beständig
Ist ein Protokoll erst als Standard verabschiedet, gibt es selten neue Versionen. Neben dem Protokoll selbst, wird eine Portnummer festgelegt. Diese so genannten Well Known Ports sind nötig, damit ein Client sich mit dem gewünschten Dienst verbinden kann. Beispielsweise wird für HTTP der Port mit der Nummer 80 und für FTP 21 verwendet [9].
Damit Dienste auf Servern erreichbar sind, müssen entsprechende Regeln in Firewalls vorhanden sein. Einfach eine neue Version des Protokolls auf einem anderen Port zur Verfügung zu stellen, reicht nicht aus. Die alte Version jedoch auf dem gleichen Port durch eine neue zu ersetzen, erfordert Abwärtskompatibilität, damit ältere Anwendungen den Dienst weiter nutzen können.
Abwärtskompatibilität beschränkt die Möglichkeiten für Verbesserungen in einer neuen Version. Es ist ein erheblicher Aufwand notwendig, um Abwärtskompatibilität zu erreichen und die technischen Lösungen sind nicht selten ein fauler Kompromiss. Statt neuer Versionen, werden dann neue Protokolle ins Spiel gebracht. Neue Standards für ähnliche oder nicht genau umrissene Probleme, sind ein mögliches Ergebnis dieses Dilemmas. Leider entsteht so eine Situation, die dazu führt, dass die Standardisierung sinnlos erscheint, weil es für das gleiche Problem verschiedene mögliche Lösungen gibt.
Für agile Softwareprojekte und Continuous Delivery/Deployment von verteilten Systemen, stellt die auf Erhalt angelegte Struktur der Protokollstandardisierung einen Widerspruch und oft auch ein Problem dar. Veränderungen müssen schnell zum Anwender und neue Versionen werden in immer kürzeren Zeitabständen ausgeliefert. Eine Standardisierung über Monate oder gar Jahre wäre undenkbar. Natürlich sollten sich Standards nicht ständig ändern. Eine Forderung nach einer Beschleunigung des Verfahrens, um mehr Protokolle in kürzerer Zeit zu standardisieren, würde die Verwirrung im Protokollwald eher vergrößern. Wie können aber Standards für Anforderungen definiert werden, die noch nicht bekannt sind? Wie soll sich ein Protokoll an zukünftige Gegebenheiten anpassen?
Konvergenz
Auch wenn es immer wieder jemanden gibt, der das Gegenteil behauptet: Die Zukunft kennt niemand. Betrachtet man jedoch aktuelle Lösungen, ist eine Konvergenz der grundlegenden Funktionen in Protokollen erkennbar [10]. Es wird schnell deutlich, dass eine große Anzahl von Standards, dem Austausch von Nachrichten dient. Warum also nicht die Eigenschaften, die sich für einen reibungslosen Nachrichtenaustausch bewährt haben, in einem Standard zusammenfassen?
"You can Solve Any Problem... if you're willing to make the problem small enough." (Marshall T. Rose) [8]
Genau das war das Ziel, als 2001 die IETF das Blocks Extensible Exchange Protocol (BEEP) veröffentlichte. Es wurde ein universelles Nachrichtenprotokoll geschaffen, das sich an viele Aufgaben leicht anpassen lässt. Mechanismen, die sich in Anwendungsprotokollen bewährt haben, wurden in BEEP integriert. Auf dieser Basis können Entwickler ihre Interprozesskommunikation und Schnittstellen modellieren, ohne sich mit den Details der Übertragung auseinander setzen zu müssen. Komplexe Anforderungen wie Asynchrone Kommunikation, Kanäle und Flusskontrolle, stehen für eine skalierbare Kommunikation bereit. Eine herausragende Eigenschaft von BEEP ist jedoch die Möglichkeit, eigene Profile zu entwickeln, die Syntax, Semantik und Kommunikationsmuster festzulegen und über eine einzige TCP-Verbindung bereitgestellt werden können. Es ist ohne weiteres möglich, HTTP, MQTT oder andere Protokolle als Profil nachzubilden. Prozesse die sich verbinden, müssen nur einen Port kennen und erhalten eine Liste der zur Verfügung stehenden Dienste. Das Problem der Abwärtskompatibilität wird mit BEEP gelöst, indem zwei Versionen eines Profils gleichzeitig betrieben werden.
Kontinuierliche Verbesserung
Verschiedene Versionen eines Dienstes oder gar unterschiedliche Dienste über einen einzigen TCP-Port zur Verfügung zu stellen, entkoppelt die Funktionalität von der Netzwerkinfrastruktur [11]. Die optimale Lösung für neue Anforderungen, wird durch kontinuierliche Verbesserung gefunden und ohne Kompromisse dem Anwender bereitgestellt. Abb.4 zeigt einen BEEP-basierten Protokollstapel mit verschiedene Profilen. Abwärtskompatibilität ist überflüssig, weil Profile, falls nötig, einfach hinzugefügt werden. Ältere Anwendungen nutzen eine frühere Version des Profils, während neue Anwendungen von den erweiterten Funktionen einer neuen Version profitieren. Auch das Verhalten bereits im Einsatz befindlicher Protokolle, ist leicht nachzubilden. Das erleichtert die Anpassung vorhandener Anwendungen. Zum Beispiel könnte ein Internetbrowser ein BEEP-basiertes HTTP-Profil nutzen, das von einem Webserver bereitgestellt wird. Ebenso würde ein MQTT-Profil den Umstieg auf ein BEEP-basiertes Internet of Things möglich machen. Reichen die vorhandenen Versionen nicht mehr aus, bieten neue Profile neue Lösungen.
Natürlich können BEEP-Profile wie Anwendungsprotokolle auch jeweils einen eigenen Port nutzen. Sogar eine Standardisierung von Profilen ist möglich [12]. So können alte Gewohnheiten und neue Arbeitsmethoden kombiniert und gewinnbringend genutzt werden.
Das Internet wird größer
Die Qual der Wahl bei Protokollen, ist im Internet of Things besonders für Hersteller von Geräten ein Problem. Je besser ein Gerät integrierbar ist, also je mehr Protokolle es unterstützt, desto besser ist es in unterschiedlichen Umgebungen einsetzbar. Protokolle müssen jedoch für die jeweilige Plattform angepasst werden. Je mehr Protokolle eingebaut sind, desto größer ist der Aufwand alle auf einem aktuellen Stand zu halten, was sich auf den Preis auswirkt. BEEP-Profile sind bei weitem nicht so komplex wie vollständige Implementierungen von Anwendungsprotokollen, was die Aufgabe erleichtert.
Sogar Profile, die mittels Metadaten – wie beispielsweise einer XML-Datei – anpassbar wären, sind denkbar. Der Anwender kann dann Syntax und Semantik der Kommunikation selbst bestimmen. Das Internet of Things bietet eine weitere Besonderheit: Die Kommunikation findet nicht mehr ausschließlich über TCP/IP statt. Transportwege wie Bluetooth, eine direkte RS232-Verbindung oder andere Kurzstreckenverbindungen werden genutzt.
Im klassischen Internet wird das Websocket-Protokoll für die Kommunikation mit Diensten im Netz genutzt. Websockets verwenden wie HTTP den Port 80 und ermöglichen eine bidirektionale Kommunikation. BEEP ist unabhängig vom Transport der Daten spezifiziert. Das eröffnet die Möglichkeit, den Transport der Daten zu ändern und die vorhandenen Profile zu nutzen. Entwickler können die gleichen Schnittstellen verwenden und es sind nur minimale Anpassungen für vorhandene Anwendungen an neue Transportwege nötig. Abb.4 zeigt, wie BEEP-Profile über verschiedene Transporttechniken nutzbar sind. Bemerkenswert ist dabei, dass ein Full-Duplex-Stream, wie bei einer RS232-Verbindung, für asynchrone Nachrichten ausreicht.
Höhere Komplexität = Geringere Sicherheit
Je mehr Protokolle in einem System genutzt werden, desto komplexer ist es. Je komplexer die Kommunikation im Internet ist, desto leichter ist sie angreifbar. Neben unterschiedlich starken Sicherheitsmechanismen, kommt der "Menschliche Faktor" als Unsicherheit dazu. Je komplizierter es wird, Sicherheit zu erzeugen und zu validieren, desto häufiger wird darauf verzichtet.
Netzwerkprotokolle müssen sich beim Aufbau einer Verbindung auf eine Verschlüsselung einigen. Das kostet Zeit. Kommen verschiedene Anwendungsprotokolle zum Einsatz, bringt jedes seine eigenen Sicherheitsmechanismen mit. Häufig wird mittels TLS für TCP oder DTLS für UDP (Transport Layer Security) der Transport verschlüsselt. Ist das nicht möglich, bleibt die Verschlüsselung der Daten in der Anwendung selbst (Application Layer Security). Eine Verschlüsselung auf IP-Ebene oder via VPN (Network Layer Security) sichert den gesamten Datenverkehr ab. Es ist nicht nötig, jede einzelne Verbindung abzusichern.
Auch wenn TLS und DTLS Standardprotokolle sind, muss die Nutzung im jeweiligen Anwendungsprotokoll vorgesehen sein. Das gilt natürlich auch für BEEP. Der Standard bringt bereits Profile für die Nutzung von TLS/DTLS mit, jedoch können sie optional eingesetzt werden. Zusätzlich ist die Unterstützung von SASL vorgesehen. Ist eine BEEP-Session aufgebaut und abgesichert, wird auf alle Profile verschlüsselt zugegriffen. Profilentwickler können sich auf die Funktionalität konzentrieren und müssen sich nicht mit der sicheren Übertragung beschäftigen. Das ist ein wichtiger Unterschied zur bisherigen Praxis in Anwendungsprotokollen. Wird in Zukunft ein neuer Sicherheitsstandard benötigt, muss kein neues Protokoll, sondern nur ein neues Profil für die Nutzung entwickelt werden. Eine Anpassung der vorhandenen Profile ist nicht nötig. So werden selbst komplexe Schnittstellen und Dienste einfach und zeitsparend abgesichert.
Fazit
Das Transmission Control Program, der Vorgänger von TCP/IP wie wir es heute kennen, ist eine monolithische Implementierung von Funktionen, die dann in IP und TCP aufgeteilt wurden. Der Internet Pionier Jon Postel regte die Aufteilung 1977 in der Internet Engineering Note Nummer 2 oder IEN 2 an [13].
Die aktuelle Situation ist durchaus vergleichbar. Immer wieder werden grundlegende Funktionalitäten für den Austausch von Nachrichten in Anwendungsprotokollen implementiert. Die Qualität der unterschiedlichen Ausprägungen variiert von Standard zu Standard und von Implementierung zu Implementierung. Warum also nicht eine weitere Schicht schaffen, die diese grundlegenden Aufgaben erledigt, damit sich Entwickler wieder auf die anstehenden Probleme konzentrieren können, anstatt sich mit den Details von Anwendungsprotokollen auseinandersetzen zu müssen. Viele dieser Details, die sich im Laufe der Zeit herauskristallisierten, beschreibt RFC3117 [14].
BEEP ist vielleicht nicht die Lösung der Zukunft, jedoch zeigt der Standard (2001) wie eine generelle Lösung für das eigentliche Problem, den Austausch von Nachrichten, aussehen kann. Anders als zu den Zeiten von Jon Postel, als eine kleine Gruppe von Internetpionieren – eine Vision vor Augen – das Ziel hatte, das Internet besser zu machen und dabei Fragen der Politik und der kaufmännischen Verwertung zurückstellte [15], scheinen heute jedoch Firmen wie Google (HTTP/2) und IBM (MQTT) ihre proprietären Protokolle zu standardisieren. Das dabei geschäftliche Interessen keine Rolle spielen, kann wohl ausgeschlossen werden. Bis in diesem Umfeld ernsthaft an einer allgemeinen Lösung und einer neuen Schicht im Protokollstapel gearbeitet wird, bleibt BEEP, der Standard mit dem für die Suche im Internet unglücklich gewählten Namen, eine Alternative für diejenigen, die bereits jetzt ihre Systeme mit flexibler Erweiterbarkeit auf Protokollebene ausrüsten wollen [16].
- Internet Engineering Task Force (IETF)
- OASIS
- W3C
- Wikipedia: Netzwerkprotokoll
- The Internet Standards Process
- Analysis of HTTP Performance problems
- Github: TCP Small Message Benchmark
- BEEP, understanding why it was created
- Service Name and Transport Protocol Port Number Registry
- Maik Wojcieszak: Anwendungsprotokolle im Vergleich
- Maik Wojcieszak: Portorientierte Entwicklung und BEEP
- BEEP Standard Profiles
- Comments on Internet Protocol and TCP - IEN # 2
- On the Design of Application Protocols
- Getting Started in the IETF
- BEEP community site