web-dev-qa-db-ja.com

Telnetがプロトコルと見なされるのはなぜですか?単純なTCP send / echoプログラムではありませんか?

これは概念的な質問に似ています。いくつかの説明が必要です。


今日、私はいくつかのソケットプログラミングのことを学び、 Beej's Guide to Network Programming に基づいて簡単なチャットサーバーとチャットクライアントを書きました。 (チャットサーバーはクライアントメッセージを受信し、他のすべてのクライアントにメッセージを送信します)

チャットサーバー をコピーして、独自の チャットクライアント を作成しました。

チャットクライアントは、stdin入力をサーバーに送信し、サーバーからソケットデータを印刷するプログラムにすぎません。

後で、ガイドがtelnetを使用してサーバーに接続できると説明していることに気付きました。私が試してみましたが、うまくいきました。


私はTelnetに慣れていなかったので、長い間、正確には何なのかわかりませんでした。

だから今私の経験は私を混乱させます:

Telnetは単純なTCP send/echoプログラムではありませんか?プロトコルであることが特別な理由は何ですか? ?ダムチャットクライアントプログラムで[アプリケーション]プロトコルが作成されません。

ウィキペディアから Communication_protocol

電気通信では、通信プロトコルはrulesのシステムであり、通信システムの2つ以上のエンティティがあらゆる種類の物理的なバリエーションを介して情報を送信できるようにします。量。

Telnetはどのような規則を作成しますか? telnet Host port、開いているTCP生の入出力用のストリームソケットですか?それは規則ではありません。

10
Rick

Telnetは RFC 854 で定義されています。プロトコル(およびその他のプロトコル)を構成するものは、一連のルール/制約です。そのようなルールの1つは、TelnetがTCPを介して行われ、ポート23が割り当てられることです。これは簡単なように見えるかもしれませんが、どこかで指定する必要があります。

好きなだけ送信することはできません。いくつかのものには制限と特別な意味があります。たとえば、「ネットワーク仮想端末」を定義します。これは、Telnetが確立されたときに、プリンター、白黒モニター、ANSIコードをサポートするカラーモニターなど、さまざまな端末が存在する可能性があるためです。

また、次のようなものがあります:

要約すると、WILL XXXはいずれかの当事者によって送信され、その当事者の希望(オファー)がオプションXXXの実行を開始することを示し、XXXを実行し、XXXを肯定および否定しないことを示します。同様に、DO XXXは、相手(つまり、DOの受信者)がオプションXXXを実行することを希望(要求)することを示すために送信されます。 NVTは、オプションが有効になっていないときに残されるものであるため、DO N'TおよびWO N'T応答は、両端が処理できる状態で接続を残すことが保証されています。したがって、すべてのホストは、サポートされていないオプションをまったく認識しないようにTELNETプロセスを実装し、理解できないオプション要求に拒否を返す(つまり拒否する)ことができます。

現代では、ほとんどのものはもはやそれほど重要ではありません(そして、プロトコルとしてのtelnetは、セキュリティが不足しているという理由だけでなく、もはやあまり使用されていません)。端末と実際にインターフェースする必要があります。

15
Michael Stum

2つの端末を接続するときにtelnetが「機能する」という事実自体がプロトコルの決定です。telnetの設計者は、TCP接続の両端に「ネットワーク仮想端末」を持つモデルを使用することを決定しました、それらの仮想端末を基本的な端末機能(実際にはテレタイプ)でモデル化することにしました。

それ以上に、telnetは単なるTCPベースのエコーサービスではありません。さまざまな目的で、インバンドで送信される制御コードをサポートします。 RFC 854 で体系化されています。

7
Stephen Kitt

サブシステムと呼ばれる"Telnet"が提案されていますネットワークシステムプリミティブの周りのシェルプログラムで、テレタイプまたは同様の端末をサービスを提供するホストでテレタイプとして機能するリモートホスト。

これは、Wikipediaの「telnet」で言及されているRFC 15からのものです。この記事では、最初にtelnetを「アプリケーションプロトコル」と呼びます。

RFC 15は1969年9月のものです-ほんの数日前に、ちょうど50年前に最初の「インターネット」接続を確立した男との興味深いインタビューを聞きました。彼の話はそのようになりました:

"N。Armstrongとは異なり、特別なメッセージは考えていませんでした。しかし、「lo」(「login」)と入力すると、システムがクラッシュしました。「lo」(「lo and behold ")は、インターネットを介して送信される最初の2文字でした。振り返ってみると、これ以上良いものは考えられませんでした。」

(インタビューの一部を以下に示します: wiki arpanet Kleinrock


TelnetはTCP/IPよりも古いものです。 RFC 15は「ネットワークプリミティブ」について語っています。 TCP/IPが原因で、Telnetは「休憩」であるアプリケーション層(RFC854の「交渉済みオプション」)を処理するためだけに残されました。

はい、TelnetはTCPがなくても非常に簡単です。 RFC 15は次で終わります:

TELNETサブシステムは、「レベル0」のネットワークプログラムであり、すぐに超えることができます。しかし、それは非常に単純で、かなりすぐに機能します。


本質的に2つの(異なる)システムが1つの「言語」で通信する必要があるため、「プロトコル」はtelnetで使用されます。

RFC 854でも概念が説明されています。

TELNETプロトコルは、3つの主要なアイデアに基づいて構築されています。まず、「ネットワーク仮想端末 ...」のコンセプトです。


3
rastafile

既存の回答はすでにtelnetがTCP変更なしで入力データをストリーミングする以上のことができることを説明しています;代わりに、「私のダムチャットクライアントプログラムはt [アプリケーション]プロトコルを作成します。 "-質問の一部です(余談ですが、実際の「TCPを介した生データ」の場合、netcatの代わりにtelnetを使用できます)。

プロトコルが単純である、または悪い、またはどこでも明確に指定されていないからといって、プロトコルではないという意味ではありません。 2つのシステムは、プロトコルが「TCPを介した生データ」であっても、合意されたプロトコルなしでは通信できません。一方の端でFTPを、もう一方の端でHTTPを話そうとすると、何らかの方法で問題が発生します-運が良ければ、うまくいきません。そうでない場合、あなたは間違った行動をするでしょう。 (少なくとも、HTTPサーバーと同じホスト上の非標準ポートでFTPデーモンを実行した場合、一部のブラウザーでは、XSSを実行し、被害者のブラウザーをポイントすることでCSRF保護をバイパスすることができました。 to POST FTPサーバーへのPOST $ ===これは、POSTされたコンテンツをエラーメッセージにエコーし、ブラウザはそれをHTTP/0.9応答として解釈し、JavaScriptを喜んで実行します。)

「_my dumb chat client program_と呼んでいるプロトコルは何ですか?私のプログラムから話したいのですが」と質問するのは、完全に有効な質問です。可能な答えの1つは、「TCPを介した生データ」です。ただし、完全な答えではありません。

  • デフォルトのポートがある場合、それはおそらく答えの一部になるはずです。
  • 非常に明確にしたい場合は、「TCP緊急/帯域外データではなく、通常のTCPデータ」という意味です(これはそれは意味をなさないので少しストレッチです、そしてselect()の3番目のfdセットはエラー用であると思う人の量から判断すると、大多数の人は帯域外データが存在することさえ知らないようです-しかし、たとえそれが悪い例であったとしても、私が何をしているのか見てほしいと思います)
  • あなたが考えもしなかったものでさえ、暗黙のうちにプロトコルの一部であるかもしれません:どのようにして接続を閉じますか? close()を呼び出すだけですか、それともshutdown()を使用して、保留中のすべてのデータが最初に配信されることを確認しますか?

「TCP生の入出力用のストリームソケットを開く?それはルールではありません。」と言いましたが、本当にそうですか?「TCPを使用する必要があります」、「データを-is」および「ポートXXXを使用する必要があります」というのは、ルールのようです。

(追記:私はこれを書くのに少し気を取られました;この答えの残りは少し正接です、そして「さて、すべてがプロトコルです-それは何らかの意味を持っていますか?」という自然なフォローアップの質問に答えようとします)

したがって、2つのシステムが互いに通信するたびに、既存のプロトコルを使用するか、新しいプロトコルを作成することに注意してください。手遅れになる前にプロトコルを文書化してください! (つまり、遅くとも、プロトコルが単純なものを超えた場合、または開発者だけでなく、より多くのユーザーがいる場合)。初期のP2Pプロトコルの多くは「公式クライアントのソースはドキュメントである」と言っていました。これは複雑なプロジェクトでは非常に迷惑であり、クライアントが微妙に異なるプロトコルを話し、あちこちで互換性がないことにつながります。

「あなたが生産するものに厳格で、受け入れるものに寛大」という古い格言があります-核心的な感情はいいですが、率直に言って、少なくともそれが適用されがちな方法です。保守性と互換性の問題。私は言います:詳細に指定し(隅から隅まで考えてみてください)、作成および受け入れるものを非常に厳密にしてください。そうすれば、実際のバグを防止/解決することができます。

バグを厳密に解決する例:数年前、特定のbittorrentトラッカーに問題が発生しました:一部のtorrentが一部のクライアントで機能しませんでした。クライアントは文句を言わず、異なる情報ハッシュを取得しただけなので、急流を見つけることができませんでした。彼らは何が起こっているのか理解できず、影響を受けるクライアントはバグが多いに違いないと宣言し、クライアントの使用を停止しました。 Bittorrentは非常に厳密かつ適切に指定されたベンコーディングを使用します。これには正当な理由があります。同じ入力は常にまったく同じエンコードされた出力文字列になるため、[info]ハッシュは同じ入力データに対して常に同じです。私が最初にこれらの急流の1つにぶつかったとき、私はそれを自分の-非常に厳密な-パーサーにフィードしようとしました、そしてすぐにそれは言った:Error: Bencoded dictionary keys not sorted (last='sha1', key='private')

どうしたの?トラッカーは、アップロードされた各torrentに「プライベート」のキーを自動的に追加し始めましたが、ベンコーディングが指定するように辞書のキーを並べ替えるのではなく、単に最後に追加しました-生成されたものに厳密ではありませんでした。一部のクライアントは、急流を部分的にのみデコードし、デコードされていない変更されていない文字列のハッシュを計算しました。一部のクライアントは、トレント全体をデコードし、ハッシュに必要な部分を再エンコードし、プロセスでキーを正しくソートし(有効なベンコーディングを作成)、別のハッシュを取得しました。私の知る限りでは、クライアントはデータが無効であると文句を言うことはありませんでした。それで、どのハッシュが正しかったですか?どちらでもない!ハッシュを計算する両方の方法は正しいですが、急流は壊れていました!クライアントの1人でも不満があった場合、バグはおそらく数か月かかるのではなく、同じ日に修正されたでしょう。 (IIRC私も数年後、まったく無関係な別のトラッカーで同じバグを報告しました。最初のソフトウェアは社内で作成されたため、同じコードベースではありませんでした)

別の例、今回はコーナーケースについて:eDonkey2000 P2Pプロトコルはed2kというカスタムハッシュを使用しました。仕様では、入力データ長がブロックサイズで正確に割り切れるというケースケースでの動作を指定していなかったため、一部のファイルに異なるハッシュを生成し、互換性のない2つの互換性のないバリアントが生まれました。 (「仕様」と言いましたが、これは初期のP2Pプロトコルだったので、仕様がなかったと確信しています。プロトコルをリバースエンジニアリングするときに、特殊なケースがおそらく見落とされていました)

詳細な仕様の必要性について:多くの場合、プロトコルのクライアントまたはファイル形式のパーサーを記述しようとすると、元のプログラマーでさえ、実際にどのようにデータがエンコードされているかわからないという状況に遭遇しました。いくつかのライブラリを使用したことがあり、実際に何が行われるかを詳細に確認したことはありません。 2つの例:

特定のAPIは、暗号化された[可変長]パケットを使用したカスタムUDPプロトコルを使用していました-ドキュメントにはAES128が指定されていましたが、使用されたパディングについては触れられていませんでした。開発者がそれについて質問されたとき、応答は次のようなものでした。

ええと、実際にはわかりません。この関数をこのJavaライブラリで使用しました。ドキュメントには、どのパディングが使用されているかが記載されていないようです。

特定のデバイスのWebサイトには、savefileとのインターフェースについて次のように書かれています。

保存された* .logicdataファイルを作成または変更することはできません。これは、ファイルがboostバイナリシリアル化で生成され、非常に複雑なオブジェクト構造が含まれているためです。実際には、それがどのように機能するかさえ理解していません。 Boostシリアライゼーションは非常に複雑です。

(注:ただし、実際には、データをエクスポートできるようにするのに十分なファイル形式のリバースエンジニアリングを行うのにそれほど長くはかかりません)

いくつかの例は、エンコーディング、ファイル形式、またはカスタムアルゴリズムに関するものでした(ただし、最後のプロトコルを除いて、依然としてプロトコル内で使用されています)が、これはすべてすべてに当てはまると思います。プロトコル、ファイル形式、エンコーディング、カスタムアルゴリズムのいずれであっても、

  • 良い仕様を書く/それを文書化する
    • すべてのコーナーケースについて考えてみてください
    • 必要なすべての詳細を含めるようにしてください
  • 仕様に従って文字を守る/厳格にする
1
Aleksi Torhamo

Telnetプロトコルは非常に単純なプロトコルですが、存在しています。 「存在する」とは、Telnetクライアントが受信したすべてのバイトを、それを読み取るプログラム(通常はシェル)に送信しないことを意味します。

プロトコルは

バイト0xff(255)は、次のバイトがTelnetコマンドであることを意味します。 0xffを送信する場合は、2倍(0xff, 0xff)して、コマンドを送信するつもりがないことをtelnetに通知する必要があります。

つまり、プロトコルは非常に単純で、ほとんど取るに足らないものです。しかし、これは単純なtcpパススルーではありません。


Telnetコマンド

(反対側のソフトウェア/サーバーの代わりに)Telnetに送信できるコマンドに興味がある場合は、RFCを参照してください: https://tools.ietf.org/html/rfc854 。基本的に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.

上記のコマンドは具体的にはTelnetコマンドであることに注意してください。これらは、クライアントまたはサーバー側のターミナルプロトコルの一部ではありません。たとえば、UNIXでプロセスを終了する場合は、通常ctrl-cと入力します。これは通常、ターミナルから0x03としてシェルに送信され、シェルはSIGINTをシェルが実行しているプロセスに送信します。しかし、telnet自体は0xff, 0xf4を定義して、SIGINTをtelnet固有のプロトコルであるプロセスに送信します。同様に、端末は通常、現在の行をクリアするために0x1b, 0x4bを送信しますが、telnetは0xff, 0xf8を定義します。

1
slebetman