it-swarm.com.de

Warum wird Telnet als Protokoll betrachtet? Ist es nicht nur ein einfaches TCP Sende- / Echo-Programm?

Dies ist eher eine konzeptionelle Frage. Ich brauche einige Klarstellungen.


Heute lernte ich einige Socket-Programmieraufgaben und schrieb einen einfachen Chat-Server und Chat-Client basierend auf Beejs Leitfaden zur Netzwerkprogrammierung . (Der Chat-Server empfängt Client-Nachrichten und sendet Nachrichten an alle anderen Clients.)

Ich habe den Chat-Server kopiert und meinen eigenen Chat-Client geschrieben.

Der Chat-Client ist nur ein Programm zum Senden von stdin Eingaben an den Server und zum Drucken von Socket-Daten vom Server.

Später bemerkte ich, dass der Leitfaden besagt, dass ich einfach telnet verwenden kann, um eine Verbindung zum Server herzustellen. Ich habe es versucht und es hat funktioniert.


Ich war mit Telnet nicht vertraut und weiß lange nicht genau, was es ist.

Jetzt verwirrt mich meine Erfahrung:

Ist Telnet nicht nur ein einfaches TCP Sende-/Echo-Programm? Was macht es so besonders, ein Protokoll zu sein? Mein dummes Chat-Client-Programm erstellt kein [Anwendungs-] Protokoll.

Aus Wikipedia Communication_protocol :

In der Telekommunikation ist ein Kommunikationsprotokoll ein System von Regeln , die es zwei oder mehr Entitäten eines Kommunikationssystems ermöglichen, Informationen über jede Art von Variation eines physischen Systems zu übertragen Menge.

Welche Regeln erstellt Telnet? telnet Host port, öffne einen TCP Stream-Socket für rohe Eingabe/Ausgabe? Das ist keine Regel.

10
Rick

Telnet ist definiert in RFC 854 . Was es (und alles andere) zu einem Protokoll macht, ist eine Reihe von Regeln/Einschränkungen. Eine solche Regel ist, dass Telnet über TCP erfolgt und Port 23 zugewiesen wird - dieses Zeug mag trivial erscheinen, muss aber irgendwo angegeben werden.

Sie können nicht einfach senden, was Sie wollen, es gibt Einschränkungen und besondere Bedeutungen für einige Dinge. Beispielsweise wird ein "virtuelles Netzwerkterminal" definiert. Dies liegt daran, dass es bei der Einrichtung von Telnet viele verschiedene Terminals geben kann: einen Drucker, einen Schwarz/Weiß-Monitor, einen Farbmonitor, der ANSI-Codes unterstützt usw.

Es gibt auch solche Sachen:

Zusammenfassend wird WILL XXX von jeder Partei gesendet, um den Wunsch (das Angebot) dieser Partei anzuzeigen, mit der Ausführung von Option XXX zu beginnen, wobei DO XXX und DON'T XXX ihre positiven und negativen Bestätigungen sind; In ähnlicher Weise wird DO XXX gesendet, um einen Wunsch (eine Anfrage) anzuzeigen, dass die andere Partei (d. h. der Empfänger des DO) mit der Ausführung der Option XXX beginnt, wobei WILL XXX und WON'T XXX die positiven und negativen Bestätigungen sind. Da die NVT übrig bleibt, wenn keine Optionen aktiviert sind, wird garantiert, dass die Antworten DON'T und WON'T die Verbindung in einem Zustand belassen, den beide Enden verarbeiten können. Somit können alle Hosts ihre TELNET-Prozesse so implementieren, dass sie nicht über Optionen informiert sind, die nicht unterstützt werden, und einfach eine Ablehnung an eine nicht verständliche Optionsanforderung zurückgeben (d. H. Ablehnen).

In der heutigen Zeit sind die meisten Dinge nicht mehr so ​​wichtig (andererseits wird Telnet als Protokoll nicht mehr viel verwendet, nicht nur, weil es an Sicherheit mangelt). In der Praxis läuft es also darauf hinaus, zu senden/zu echo, es sei denn, Sie müssen tatsächlich mit Terminals verbinden.

15
Michael Stum

Die Tatsache, dass telnet beim Verbinden zweier Terminals „nur funktioniert“, ist an sich eine Protokollentscheidung: Die Entwickler von telnet haben beschlossen, ein Modell mit „virtuellen Netzwerkterminals“ an beiden Enden von a = zu verwenden TCP Verbindung, und beschlossen, diese virtuellen Terminals auf grundlegende Terminalfunktionen (Teletypen wirklich) zu modellieren.

Darüber hinaus ist telnet mehr als ein einfacher TCP-basierter Echodienst. Es unterstützt In-Band-Steuercodes für verschiedene Zwecke. Es ist in RFC 854 kodifiziert.

7
Stephen Kitt

Es wird ein Subsystem mit dem Namen "Telnet" vorgeschlagen, das ein Shell-Programm um die Grundelemente des Netzwerksystems , mit dem ein Teletyp oder ein ähnliches Terminal auf einem Remote-Host als Teletyp auf dem bedienenden Host fungieren kann.

Dies ist aus RFC 15, das in Wikipedia "Telnet" erwähnt wird. Dieser Artikel beginnt auch mit dem Aufruf von Telnet als " Anwendungsprotokoll ".

Der RFC 15 stammt aus dem September 1969 - vor einigen Tagen hörte ich ein interessantes Interview mit dem Mann, der vor genau 50 Jahren die erste "Internet" -Verbindung hergestellt hatte. Seine Geschichte ging so:

"Im Gegensatz zu N. Armstrong hatten wir an keine spezielle Nachricht gedacht. Aber nachdem wir" lo "(für" login ") eingegeben hatten, stürzte das System ab. Also" lo "(wie in" lo and siehe ") waren die ersten beiden Zeichen, die über das Internet übertragen wurden. Rückblickend hätten wir uns nichts Besseres vorstellen können. "

(Hier ist ein Teil dieses Interviews: Wiki Arpanet Kleinrock )


Telnet ist älter als TCP/IP. RFC 15 spricht von "Netzwerkprimitiven". Aufgrund von TCP/IP war Telnet nur noch für den "Rest", die Anwendungsschicht (die "ausgehandelten Optionen" in RFC854) zuständig.

Ja, Telnet ist auch ohne TCP recht einfach. RFC 15 endet mit:

Das TELNET-Subsystem stellt ein Netzwerkprogramm der Stufe 0 dar, das schnell übertroffen wird. Es ist jedoch einfach genug, um ziemlich bald zu arbeiten.


"Protokoll" wird mit Telnet verwendet, da von Natur aus zwei (unterschiedliche) Systeme in einer "Sprache" sprechen müssen.

RFC 854 erklärt auch das Konzept:

Das TELNET-Protokoll basiert auf drei Hauptideen: Erstens dem Konzept eines " Network Virtual Terminal " ...


3
rastafile

Die vorhandenen Antworten erklären bereits, dass telnet mehr kann als nur Eingabedaten über TCP unverändert zu streamen; ich möchte mich stattdessen auf das "Mein dummes Chat-Client-Programm nicht" streamen). t Erstellen Sie ein [Anwendungs-] Protokoll. "- Teil der Frage. (Abgesehen davon können Sie für tatsächliche" Rohdaten über TCP "netcat anstelle von telnet verwenden.)

Nur weil ein Protokoll einfach oder schlecht ist - oder nirgendwo gut spezifiziert - heißt das nicht, dass es kein Protokoll ist. Zwei Systeme können ohne ein vereinbartes Protokoll nicht kommunizieren, selbst wenn es sich bei diesem Protokoll nur um "Rohdaten über TCP" handelt. Wenn Sie versuchen, FTP auf der einen Seite und HTTP auf der anderen Seite zu sprechen, werden Sie auf die eine oder andere Weise Probleme haben - wenn Sie Glück haben, funktioniert es nicht. Wenn Sie nicht sind, werden Sie falsches Verhalten bekommen. (Zumindest war es früher so, dass Sie, wenn Sie einen FTP-Dämon auf einem nicht standardmäßigen Port auf demselben Host wie ein HTTP-Server ausgeführt haben, in einigen Browsern XSS verwenden und den CSRF-Schutz umgehen können, indem Sie auf den Browser des Opfers zeigen to POST an den FTP-Server, der den POST-Inhalt in Fehlermeldungen wiedergibt, und der Browser interpretiert ihn als HTTP/0.9-Antwort - und führt gerne Javascript aus.)

Es ist eine durchaus gültige Frage: "Welches Protokoll verwendet das Ding, das Sie my dumb chat client program Nennen? Ich möchte von meinem Programm aus mit ihm sprechen." und eine mögliche Antwort wäre "Rohdaten über TCP". Es ist jedoch keine erschöpfende Antwort.

  • Wenn Sie einen Standardport haben, sollte dies wahrscheinlich Teil der Antwort sein.
  • Wenn Sie extrem klar sein möchten, können Sie angeben, dass Sie "normale TCP Daten, nicht TCP dringende/Out-of-Band-Daten") meinen (welche ist ein bisschen langwierig, da es keinen Sinn ergibt, und gemessen an der Anzahl der Leute, die ich gesehen habe, die denken, dass die dritte fd-Menge von select() für Fehler ist, ziehen die meisten Leute an Es scheint nicht einmal zu wissen, dass Out-of-Band-Daten existieren - aber selbst wenn es ein schlechtes Beispiel ist, hoffe ich, dass Sie sehen, worauf ich hinaus will.
  • Sogar Dinge, an die Sie vielleicht noch nicht einmal gedacht haben, könnten implizit Teil des Protokolls sein: Wie schließen Sie die Verbindung? Rufen Sie einfach close() auf oder verwenden Sie shutdown(), um sicherzustellen, dass alle ausstehenden Daten zuerst übermittelt werden?

Sie sagten "Öffnen Sie einen TCP Stream-Socket für rohe Eingabe/Ausgabe? Das ist keine Regel.", Aber ist das wirklich so? "Sie müssen TCP verwenden", "Sie müssen die Daten senden als -ist "und" Sie sollten Port XXX verwenden "klingen für mich wie Regeln.

(S. Ich habe mich ein wenig mit dem Schreiben beschäftigt. Der Rest dieser Antwort ist ein bisschen tangential und versucht, die natürliche Folgefrage zu beantworten: "Okay, also ist alles ein Protokoll - hat das irgendwelche Auswirkungen?")

Denken Sie also daran, dass Sie jedes Mal, wenn Sie zwei Systeme miteinander kommunizieren lassen, entweder ein vorhandenes Protokoll verwenden oder ein neues Protokoll erstellen: Dokumentieren Sie Ihre Protokolle, bevor es zu spät ist! (Dh spätestens dann, wenn das Protokoll nicht mehr einfach ist oder mehr Benutzer als nur die Entwickler hat) ZB. Viele frühe P2P-Protokolle sagten, "die Quelle des offiziellen Clients ist die Dokumentation", was in einem komplexen Projekt äußerst ärgerlich ist und nur dazu führt, dass Clients subtil unterschiedliche Protokolle sprechen und hier und da nicht kompatibel sind.

Es gibt das alte Sprichwort: "Sei streng in dem, was du produzierst und liberal in dem, was du akzeptierst" - das Kerngefühl ist Nizza, aber ehrlich gesagt, zumindest die Art und Weise, wie es angewendet wird, denke ich, dass es Bullcrap ist und nur zu mehr führt Probleme bei der Wartbarkeit und Kompatibilität. Ich sage: Geben Sie im Detail an (versuchen Sie, an jeden Eckfall zu denken) und seien Sie äußerst streng in dem, was Sie produzieren und akzeptieren, und Sie werden wahrscheinlich echte Fehler verhindern/lösen.

Ein Beispiel zur strengen Lösung von Fehlern: Vor Jahren hatte ein bestimmter Bittorrent-Tracker ein Problem: Einige ihrer Torrents funktionierten bei einigen Clients nicht. Die Kunden haben sich nicht beschwert, sie haben nur einen anderen Infohash bekommen und konnten daher den Strom nicht finden. Sie konnten nicht herausfinden, was los war, und erklärten, dass die betroffenen Kunden fehlerhaft sein müssen - hören Sie auf, sie zu verwenden. Bittorrent verwendet Bencoding, das sehr streng und genau spezifiziert ist - und das aus gutem Grund: Dieselbe Eingabe führt immer zu genau derselben codierten Ausgabezeichenfolge, sodass der [info] -Hash für dieselben Eingabedaten immer gleich ist. Als ich zum ersten Mal auf einen dieser Torrents stieß, versuchte ich, ihn in meinen eigenen - sehr strengen - Parser einzuspeisen, und sofort hieß es: Error: Bencoded dictionary keys not sorted (last='sha1', key='private').

Also was ist passiert? Der Tracker fügte automatisch den Schlüssel "privat" zu jedem hochgeladenen Torrent hinzu, fügte ihn jedoch nur am Ende hinzu, anstatt die Wörterbuchschlüssel wie in der Bencoding angegeben sortiert zu halten - es war nicht streng in dem, was er produzierte. Einige Clients haben den Torrent nur teilweise dekodiert und den Hash für die nicht dekodierte, unveränderte Zeichenfolge berechnet. Einige Clients haben den gesamten Torrent dekodiert und den Teil, den sie für das Hash benötigen, neu codiert. Dabei haben sie die Schlüssel korrekt sortiert (eine gültige Bencodierung erstellt) und einen anderen Hash erhalten. Meines Wissens/meiner Erinnerung nach hat sich kein Kunde darüber beschwert, dass die Daten ungültig sind - die Kunden waren nicht streng in dem, was sie akzeptierten. Also, welche Hashes waren richtig? Weder! Beide Methoden zur Berechnung des Hash sind korrekt, aber die Torrents wurden beschädigt! Wenn sich auch nur einer der Kunden darüber beschwert hätte, wäre der Fehler wahrscheinlich am selben Tag behoben worden, anstatt Monate zu dauern. (IIRC Ich habe einige Jahre später auch einen identischen Fehler in einem anderen, völlig unabhängigen Tracker gemeldet. Die Software des ersten wurde intern erstellt, daher war es auch nicht dieselbe Codebasis.)

Ein weiteres Beispiel, diesmal zu Eckfällen: Das eDonkey2000 P2P-Protokoll verwendete einen benutzerdefinierten Hash namens ed2k; In der Spezifikation wurde nicht angegeben, dass das Verhalten im Eckfall der Länge der Eingabedaten genau durch die Blockgröße teilbar ist. Daher wurden zwei inkompatible Varianten geboren, die für einige Dateien einen anderen Hash erzeugen und nicht kompatibel sind. (Ich sagte "Spezifikation", aber da dies ein frühes P2P-Protokoll war, bin ich mir ziemlich sicher, dass es keine Spezifikation gab; der Sonderfall wurde wahrscheinlich beim Reverse Engineering des Protokolls übersehen.)

Über die Notwendigkeit detaillierter Spezifikationen: Beim Versuch, einen Client für ein Protokoll oder einen Parser für ein Dateiformat zu schreiben, bin ich häufig auf eine Situation gestoßen, in der selbst die ursprünglichen Programmierer keine Ahnung haben, wie einige Daten tatsächlich codiert werden, weil sie Ich habe eine Bibliothek benutzt und nie im Detail überprüft, was sie tatsächlich tut. Zwei Beispiele:

Eine bestimmte API verwendete ein benutzerdefiniertes UDP-Protokoll mit verschlüsselten Paketen [variabler Länge] - in der Dokumentation wurde AES128 angegeben, die verwendete Auffüllung wurde jedoch nicht erwähnt. Als die Entwickler danach gefragt wurden, lautete die Antwort wie folgt:

Äh, wir haben eigentlich keine Ahnung, wir haben diese Funktion nur in dieser Java Bibliothek) verwendet, und die Dokumentation scheint nicht zu erwähnen, welches Padding verwendet wird

Die Website eines bestimmten Geräts hat Folgendes über die Schnittstelle zu ihren Sicherungsdateien zu sagen:

Es ist nicht möglich, gespeicherte * .logicdata-Dateien zu erstellen oder zu ändern. Dies liegt daran, dass die Dateien mit Boost-Binärserialisierung generiert werden und eine sehr komplexe Objektstruktur enthalten. In Wahrheit verstehen wir nicht einmal, wie es funktioniert. Die Boost-Serialisierung ist äußerst komplex.

(Hinweis: In der Realität dauert es jedoch nicht so lange, das Dateiformat so weit zurückzuentwickeln, dass die Daten exportiert werden können.)

Einige der Beispiele betrafen Codierungen, Dateiformate oder benutzerdefinierte Algorithmen (obwohl sie bis auf das letzte noch in Protokollen verwendet werden), aber ich würde sagen, dass all dies für alle diese gilt. Egal, ob Sie über ein Protokoll, ein Dateiformat, eine Codierung oder einen benutzerdefinierten Algorithmus sprechen:

  • Schreiben Sie eine gute Spezifikation/dokumentieren Sie sie gut
    • Versuchen Sie, über alle Eckfälle nachzudenken
    • Versuchen Sie, alle erforderlichen Details anzugeben
  • Befolgen Sie die Spezifikation zum Buchstaben/seien Sie streng
1
Aleksi Torhamo

Das Telnet-Protokoll ist ein sehr einfaches Protokoll, aber es existiert. Mit "existiert" meine ich, dass ein Telnet-Client nicht alle empfangenen Bytes an das Programm sendet, das von ihm gelesen wird (normalerweise eine Shell).

Das Protokoll ist

Das Byte 0xff (255) bedeutet, dass das nächste Byte ein Telnet-Befehl ist. Wenn Sie 0xff senden möchten, müssen Sie es verdoppeln (0xff, 0xff), Um Telnet mitzuteilen, dass Sie nicht beabsichtigen, ihm einen Befehl zu senden.

Also ja, das Protokoll ist extrem einfach, fast trivial. Aber es ist kein einfacher TCP-Durchgang.


Telnet-Befehle

Wenn Sie interessiert sind, welche Befehle Sie an Telnet senden können (anstelle der Software/des Servers auf der anderen Seite), können Sie den RFC lesen: https://tools.ietf.org/html/rfc854 . Grundsätzlich definiert Telnet:

  NAME               CODE              MEANING

  SE                  240 (0xf0)    End of subnegotiation parameters.
  NOP                 241 (0xf1)    No operation.
  Data Mark           242 (0xf2)    The data stream portion of a Synch.
                                    This should always be accompanied
                                    by a TCP Urgent notification.
  Break               243 (0xf3)    NVT character BRK.
  Interrupt Process   244 (0xf4)    The function IP.
  Abort output        245 (0xf5)    The function AO.
  Are You There       246 (0xf6)    The function AYT.
  Erase character     247 (0xf7)    The function EC.
  Erase Line          248 (0xf8)    The function EL.
  Go ahead            249 (0xf9)    The GA signal.
  SB                  250 (0xfa)    Indicates that what follows is
                                    subnegotiation of the indicated
                                    option.
  WILL (option code)  251 (0xfb)    Indicates the desire to begin
                                    performing, or confirmation that
                                    you are now performing, the
                                    indicated option.
  WON'T (option code) 252 (0xfc)    Indicates the refusal to perform,
                                    or continue performing, the
                                    indicated option.
  DO (option code)    253 (0xfd)    Indicates the request that the
                                    other party perform, or
                                    confirmation that you are expecting
                                    the other party to perform, the
                                    indicated option.
  DON'T (option code) 254 (0xfe)    Indicates the demand that the
                                    other party stop performing,
                                    or confirmation that you are no
                                    longer expecting the other party
                                    to perform, the indicated option.
  IAC                 255 (0xff)    Data Byte 255.

Beachten Sie, dass die obigen Befehle speziell Telnet-Befehle sind. Sie sind nicht Teil eines clientseitigen oder serverseitigen Terminalprotokolls. Wenn Sie beispielsweise einen Prozess unter Unix beenden möchten, geben Sie normalerweise ctrl-c Ein. Dies wird normalerweise als 0x03 Vom Terminal an die Shell gesendet, die dann SIGINT an den Prozess sendet, den die Shell ausführt. Telnet selbst definiert jedoch 0xff, 0xf4, Um SIGINT an den Prozess zu senden, bei dem es sich um ein Telnet-spezifisches Protokoll handelt. Ebenso senden Terminals normalerweise 0x1b, 0x4b, Um die aktuelle Zeile zu löschen, aber Telnet definiert 0xff, 0xf8.

1
slebetman