i移転先予定のブログURLはこちら(作成中):http://www.sawanoboly.net/wp/
旧ブログはこちらでも保管しときます:http://www.sawanoboly.net/wp_old/
telnet ですかー!?
と、分からないかもしれないネタはこの辺にして、「telnet があれば、サーバ間でファイルの転送ができる(前編)」と題して FTP (File Transfer Protocol) の仕様を確認するコラム。
FTPというと、通常のPORTコマンドを使うやり取りを初めて理解したときは驚いた。
「PORTコマンドの発行を受け付けたサーバは、接続元ポートTCP/20 でクライアントにむけてTCPセッションを張りに来る。」
そうやって接続されたセッションがデータ転送ポートとして、ファイルリストのテキストデータや、バイナリデータの転送に使用される。
嘘やん、そんなのこちらポート空けてないのにどうすんの?って思う節があるかもしれないが、最近のファイアウォールやルータはその辺をヨロシクやってくれて、意識しなくてよいようになっている。
しかしそうではないルータの下にいるFTPクライアントの為に、PASVを使うという手順がある。
FTPサーバがPASVコマンドを受け付けると、任意のポートでLISTEN のTCP状態を取り、クライアントに通知します。
[PASV] → [227 Entering Passive Mode (192,168,10,15,239,11)]
カッコ内がカンマ区切りで、IPアドレス・待ち受けポートです。このメッセージからは「IPアドレス:192.168.10.15、ポート:61195」 でLISTENしますよ、と言うこと。ちなみに 61195 は 「239 * 256 + 11」 で計算します。
PASVでポートの通知を受けたFTPのクライアントは、当然LISTENしているポートにTCPセッションを張りに行き、データはこのポートから送信されます。
と、ここでPASVで教えてもらったポートに telnet で接続するとどうなるか試した(※実験はPASVも telnet で発行しました。)ら、ちゃんとセッションが張れる。
そのまま最初に接続したコマンド用のセッションで、LISTなど発行すればPASVで張ったほうのセッションからリストデータが、RETRをすればファイルの中身が流れてくるといった具合。
基本的に接続元の制限などない模様なので、これはこれで危なっかしいとも思えるが、もうちょっと突っ込んで考えてみる。
使わないから意識していなかったが、FTPはサーバ同士のデータ転送という役割を与えられたプロトコルでもある、と言うのを形だけ知っていた。
上の割り込み実験から、「PASV で待ちうけ、PORTで接続」 とすればサーバ間の転送ができるんじゃないかと思って、RFCを読んでみた。
RFC:959(原文)(日本語訳)
すると、「5.2. CONNECTIONS」 の所にしっかり書いてあった、今でこそ一般的ではないやり方だけど、RFCでは一番シンプルなFTPの使い方としてサーバ間のデータ転送が紹介されている方法だった。
コントロールはクライアントから、データの転送は2台のサーバ間で。
サーバA(SV-A)からサーバB(SV-B)にファイルを転送したい場合、ざっとこういう手順で達成できるはず。図が崩れてたらごめんなさい、Firefoxだと一応きれい。
┌──────┐ ┌──────┐
│ SV-A │ │ SV-B │
└──────┘ └──────┘
↑ ↑
│ │
│telnet 21 │telnet 21
│ ┌──────┐ │
└←│ Ctrl │→┘
└──────┘
|
コントロールするクライアントから、両方にtelnet でFTPログイン |
LISTEN
┌──────┐ ┌──────┐
│ SV-A │ ★ SV-B │
└──────┘ └──────┘
│ ↑
│ │
│ │PASV
│ ┌──────┐ │
└─│ Ctrl │→┘
└──────┘
|
SV-B にPASVコマンドを発行、ポートをLISTENさせる |
LISTEN
┌──────┐ ┌──────┐
│ SV-A →───→★ SV-B │
└──────┘ └──────┘
↑ │
│ │
│PORT(SV-B) │
│ ┌──────┐ │
└←│ Ctrl │─┘
└──────┘
|
SV-Bが待ち受け中なので、SV-AへPORTコマンドを送る。送信内容はSV-BのIPアドレスとポート すると、SV-A と SV-B の間でFTPデータ用のセッションが確立するはず |
┌──────┐→data→┌──────┐
│ SV-A ====== SV-B │
└──────┘ └──────┘
↑ ↑
│ │
│RETR(File) │STOR(File)
│ ┌──────┐ │
└←│ Ctrl │→┘
└──────┘
|
後編作成後に認識間違いを修正。図も修正。 初版ではここの解釈に嘘があった、STORで待ち構え、RETRで送るというオペレーションが必要ということだ。 (初版)データコネクションが確立したら、STORコマンドでファイルの転送が行えるはず。 RFCではSV-B側でRETRコマンドが必要とあったが、この辺がよく分からない。 |
さて、手元に実験できるサーバがないので今度試してみよう。
後編につづく
(1)
(0)
(1)
(0)
Total: 2
最近のコメント