連載
» 2003年07月11日 00時00分 公開

TCP/IPアレルギー撲滅ドリル(5):器用な二刀流、FTPでファイル転送!

[福永勇二,インタラクティブリサーチ]

素朴な疑問

  • FTP、二刀流に生まれた定め
  1. FTPはちょっとスペシャルなんだそうですね
  2. どんなときにFTPって使うんでしょうか?
  3. 某サイトのダウンロードでは「FTP」のほかに「HTTP」って書いてありましたよ
  4. 同じダウンロード機能があるのなら、FTPかHTTPかどっちかにしちゃえばイイのに……
  • フクザツは承知のうえ! FTPをのぞいてみよう
  1. FTPが二刀流ってどういう意味ですか?
  2. 二刀流がアダになるって話、もうちょっと詳しくしてください
  3. じゃあセキュリティ対策をした場所からはFTPできないのですか?
  • もっとFTPを掘り下げて、掘り下げて
  1. ズバリFTPのコマンドを教えてください
  2. このFTPコマンドってコマンドプロンプトのFTPで使うんですよね?
  • FTPだってこの手で実験!ほら理屈どおり
  1. ちょっとフクザツなFTPこそ接続の様子が見たいのですが……

FTP、二刀流に生まれた定め

FTPはちょっとスペシャルなんだそうですね

 世の中には器用な人がいるもんです。例えばいま話題の宮本武蔵。あの刀を両手に持って戦う二刀流を編み出した人です。右手で四角形を描きながら、左手で円を書くのさえ難しいというのに、長い刀を両手で操るなんて驚きです。まあ、そのくらい特別な人だったからこそ、後世にも名前が残っているわけですが……。

 ところで、日ごろから私たちがよく利用するプロトコルの中にも、宮本武蔵よろしく、2つの通信路を器用に使い分けるものがあります。FTPです。きっと、インターネットからファイルをダウンロードするときに見たことがある方も多いことでしょう。ファイルダウンロードではHTTPと人気を二分している感じです。

 宮本武蔵が特別な人だったように、二刀流を使いこなすFTPも、ほかのプロトコルとはちょっと雰囲気が違います。今回は、ぜひその辺りのスペシャルさを見ながら、FTPの中身を探ってみたいと思います。

どんなときにFTPって使うんでしょうか?

 ファイル(File)を転送(Transfer)しちゃうプロトコル(Protocol)。それぞれの頭文字をくっつけると今日の主役「FTP」になります。そう、FTPはファイルのやりとりを専門に行うためのプロトコルなんです。だから、ファイルダウンロードのコーナーで見たことがあるのは、当然といえば当然ですね。

某サイトのダウンロードでは「FTP」のほかに「HTTP」って書いてありましたよ

 おっ、スルドイ。おっしゃるとおりFTPだけがファイルダウンロード用のプロトコルではありません。連載第2回「HTTP語でブラウザとしゃべってみよう」で紹介した「HTTP」はHTMLファイルを読み出すプロトコルですが、見方を変えればHTMLファイルをダウンロードするプロトコルです。実際、HTTPではHTMLファイル以外にも、さまざまな種類のファイルをダウンロードすることができます。その某サイトでは、ファイル転送専用のFTPのほかに、こちらのHTTPも使えるようになっているわけですね。

同じダウンロード機能があるのなら、FTPかHTTPかどっちかにしちゃえばイイのに……

 はい、そういう意見はあります。でもなかなか簡単ではないようです。FTPはファイル転送機能が豊富だけど、あっぱれなハズの二刀流がアダになる場合があります。一方、HTTPはというと、考え方はシンプルでほかのコンテンツと一緒に管理できるメリットがあるけど、とても凝った使い方をしようとすると、ちょっと物足りなくなったりもするようです。

 無理やり人間に例えるなら、多才で優秀だけど扱いが小難しい人にお願いするか、気立てはいいけど、ちょっとばかり単純な人にお願いするか、といった程度の違いでしょうか。

 そんな理由から、どちらか一方を選ぶのは難しいので、利用者の利用状況に応じて使い分けられるよう、FTPとHTTPの両方を並べてあるサイトが多いようです。

フクザツは承知のうえ! FTPをのぞいてみよう

FTPが二刀流ってどういう意味ですか?

 比較するために、これまでに登場したHTTP、SMTP、POP3のことをちょっと思い出してみましょう。例えばHTTPだったら、WebブラウザからWebサーバに接続して、その接続を通してコマンドを送ったり、コマンドのレスポンスを受け取ったり、またHTMLを受け取ったりしました。FTPを見るまでは、きっとこれが当然のように感じる方も多いでしょうね。

 でもFTPは違うんです。ちょっとリッチな感じとでもいうんでしょうか、コマンドをやりとりする接続のほかに、もう1つ別の接続を用意し、そちらをファイルのデータのやりとり専用に使います。これって、ほら二刀流でしょう?

 でも、どうしてFTPは二刀流なのでしょうか? その理由の1つは、ファイルを送っている途中であっても、ファイルのやりとりをきめ細かくコントロールしようとしたからだといわれています。

 1本の接続でデータもコマンドも送ろうとすると、どうしてもコマンドがデータに紛れ込んできてしまい、コマンドの処理が遅れたりして、大ざっぱなコントロールしかできません。FTPのように、コマンドはコマンド専用の接続で送るようにすれば、たとえ大量のデータが送信待ちの状態になっていても、それとは別に迅速に処理されるはずです。

 このようにFTPはファイル転送専用に考えられたプロトコルだけあって、いろんなところに効率的なファイル転送ができるよう工夫されています。

二刀流がアダになるって話、もうちょっと詳しくしてください

 正確にいうと、二刀流がアダになっているわけじゃありません。問題になっているのは、2つ目の接続を用意するやり方です。これがちょっといま風じゃないので、いろいろとセキュリティを気にしているネットワークでは、2つ目の接続を用意できないことがあって、FTPを使えない場合があるというお話です。

 FTPソフトやブラウザがFTPサーバに接続するときは図1のような手順で接続します。FTPサーバに接続すると、まずFTPソフトやブラウザは「USER ユーザー名」「PASS パスワード」コマンドを送り、FTPサーバにログインできる利用者であることを確認します。

図1 ごく普通のFTP接続の流れ。FTPサーバからの逆接続もあってフクザツです(画面をクリックすると拡大表示します) 図1 ごく普通のFTP接続の流れ。FTPサーバからの逆接続もあってフクザツです(画面をクリックすると拡大表示します

 次にバイナリファイルの転送なら「TYPE I」コマンドを、アスキーファイルの転送なら「TYPE A」コマンドをそれぞれ送ります。それぞれの違いですが、「バイナリファイルの転送」を指定すると、ファイルの内容には手を付けず、そのまま送られます。一方、「アスキーファイルの転送」を指定すると、転送するファイルをテキストファイルと見なして、改行コードなどの変換を自動的にやってくれます。

 さて、ここからFTPならではの話が始まります。次に送るコマンドは「PORT」です。図ではコマンドは「PORT 192,168,1,5,4,76」となっていますね。このコマンドが一体何をしているかというと、FTPサーバに対して「IPアドレス 192.168.1.5のマシンの、ポート番号 4×256 + 76 (=1100番)」に対して、データ転送用の接続を行ってくださいとデータ接続先を知らせているのです。

 FTPサーバがファイル取得を要求する「RETR ファイル名」コマンドを受け取ったら、先にPORTコマンドで指定されたIPアドレスとポート(ここでは192.168.1.5 ポート番号1100番)に接続要求を出します。接続ができたら、要求されたファイル本体を転送します。

 データ転送が無事に終わったら、データ転送用の接続は自動的に切断されます。これを確認したら、最後に「QUIT」コマンドをFTPサーバに送ります。このコマンドでコントロール用の接続も切断され、FTPの利用が終わるというシナリオです。

 さて、この中でいま風じゃないのはどこでしょうか? それは「FTPサーバがFTPソフトに対して接続要求をする」という点です。FTPソフトからしてみれば、「自分はFTPサーバにアクセスしたはずなのに、なぜか途中からFTPサーバからアクセスされる」わけです。HTTP、SMTP、POP3では、こんなことは絶対に起きません。ここがこの問題のミソです。

 普通、会社などのネットワークでは、社内から社外への接続は、かなり緩やかに許可することが多いのですが、社外から社内への接続は非常に厳しく制限します。どこかよそから社内のネットワークに侵入されてはたまりませんから、当然、そういう設定になっちゃいますよね。

 そんなネットワークでFTPを使うと、データ転送用の接続を作ろうとFTPサーバがFTPソフトに接続しようとしても、残念ながら受け付けてもらえません。データ転送用の接続が準備できなければ、必然的にデータ転送もできませんね。つまり、「FTPならではの二刀流、それも準備の仕方が問題になって、ファイル転送ができない」という状況になってしまうわけです。

じゃあセキュリティ対策をした場所からはFTPできないのですか?

 いえいえ、心配しなくて大丈夫です。「FTPサーバからの逆接続」のせいでFTPが利用できない人は非常に多いため、さすがにちゃんと対策が用意してあります。その対策とは「FTPサーバからの逆接続をやめて、FTPソフトからFTPサーバに対してデータ転送用の接続を要求する」という手順を使う方法です。

 図2を見てください。 「TYPE I」までは先の図と同じです。違うのはそこから先。FTPソフトは「PASV」コマンドを送っていて、FTPサーバからは「227 Entering Passive Mode (10,0,1,200,106,218)」という結果が返ってきています。

図2 FTPサーバからの逆接続をしないPassiveモードでの接続(画面をクリックすると拡大表示します) 図2 FTPサーバからの逆接続をしないPassiveモードでの接続(画面をクリックすると拡大表示します

 そう、これがFTPサーバからの逆接続をしないためのカナメのメッセージなのです。これはFTPサーバがFTPソフトに対してのお知らせで、「IPアドレス10.0.1.200のサーバの、ポート番号 106×256 + 218 (=27354番)」に対してデータ転送用の接続をするよう知らせるものです。

 このメッセージを受け取ったFTPソフトは、コントロール用の接続とは別に、新たにネットワーク接続を準備し、FTPサーバ10.0.1.200のポート番号27354に接続します。この接続は、FTPソフトからFTPサーバへの接続、つまり内部から外部への接続ですから、ネットワークが接続制限をする可能性はほとんどありません。

 こうしてデータ転送用の接続さえ出来上がれば、後は標準的なFTPの接続手順(逆接続あり)と何ら変わりありません。RETRコマンドでファイルを取得するなど、ファイル転送を実行することが可能となります。

 このように、データ転送用の接続をFTPソフト側から要求する手順を、「Passiveモード」といいます。FTPソフトを使ったことがある人なら、どこかで見たことがあるかもしれません。もし、社内ネットワークからFTPができないとか、ADSLを使っていてFTPができないといった症状に遭遇したときには、まずこのモードを使ってみることをお勧めします。

もっとFTPを掘り下げて、掘り下げて

ズバリFTPのコマンドを教えてください

 はい、ズバリいきましょう。FTPの主要なコマンドは表1のものがあります。

種類 コマンド パラメータ 機能 データ転送接続
認証 USER ユーザー名 ログインするユーザー名を指定する  
PASS パスワード パスワードを指定する  
転送方法 PORT IPアドレス+ポート 接続するIPアドレスとポートを指定する (*1)
PASV Passiveモードでの接続を指定する
TYPE "A": アスキーモード "I": バイナリモード 転送するファイルのタイプを指定する  
ファイル操作 RETR ファイル名 FTPサーバからファイルをダウンロードする  
STOR ファイル名 FTPサーバにファイルをアップロードする  
RNFR ファイル名 変更するファイルやディレクトリの名前を指定する  
RNTO ファイル名 変更後のファイルやディレクトリの名前を指定し、変更処理を開始する  
DELE ファイル名 ファイルやディレクトリを削除する  
CWD [ディレクトリ名] カレントディレクトリを変更する  
CDUP 1つ上の階層のディレクトリに移動する  
PWD カレントディレクトリを表示する  
RMD ディレクトリ名 ディレクトリを削除する  
MKD ディレクトリ名 ディレクトリを作る  
STAT [ファイル名] FTPサーバやファイルの情報を報告する  
ABOR 直前の転送コマンドなどの実行を中止する  
一覧 NLST [オプション] [ファイル/ディレクトリ] カレントディレクトリのファイル一覧を表示する。オプションも指定できる
LIST [ファイル/ディレクトリ] カレントディレクトリのファイル一覧を表示する
その他 QUIT 接続を終了する  
HELP [コマンド] 利用可能なコマンド一覧を表示する  
NOOP 何もしない  
(*1) IPアドレスの各けたの数値、ポート番号を256で割った値、ポート番号を256で割った余り、それぞれをカンマで区切って並べる
表1 ftpの主要なコマンド一覧

 このコマンドはコントロール用の接続(ポート21番)に対して送信します。コマンドの種類は大きく分けて、認証を行うもの、転送方法を指定するもの、ファイル操作を行うもの、一覧を表示するもの、その他に分けられます。各コマンドの機能は非常にシンプルなので、表を見れば理解できると思います。

 なおコマンドの中には、その実行順序が決まっているものがあります。PASSコマンドを実行する前にはUSERコマンドを使用しなければいけません。またRNTOコマンドを実行する前にはRNFRコマンドを実行しないといけません。

 データ転送接続が「要」となっているコマンドは、そのコマンドを実行する前に、PORTコマンドかPASVコマンドを使って、データ転送接続を準備する必要があります。またデータ転送用の接続は、1つのコマンドの実行が終わるたびに切断しますので、「要」となっているコマンドを実行する前には、毎回「PORT」コマンドか「PASV」コマンドを実行しないといけません。

 与えたコマンドの実行結果は、telnetと似たような3けたの数字で返ってきます(表2)。

1けた目の数 意味
1 正常終了。後続する処理を待つ
2 正常終了。動作を完了する
3 正常終了。後続するコマンドを待つ
4 一時的な問題のため異常終了
5 永続的な問題のため異常終了

2けた目の数 意味
0 文法エラー
1 情報提供
2 接続に関するもの
3 認証に関するもの
4 未使用
5 ファイルシステムに関するもの
表2 レスポンスコードの1けた目と2けた目の意味

 そのうち1けた目はエラーの大きな分類を示し、2けた目はエラーの要因を示します。具体的なエラー番号としては、 以下のようなものがあります。

200 コマンド正常
227 Passiveモードに切り替わった
331 ユーザー名正常、パスワード要求
500 文法エラー、コマンド理解不能

このFTPコマンドってコマンドプロンプトのFTPで使うんですよね?

 いいえ、違います。似ていてちょっとややこしいのですが、この表のコマンドは、あくまでもFTPソフトとFTPサーバ間でやりとりするプロトコル上のコマンドです。例えばファイルを取得するとき、FTPのプロトコル上でのコマンドは「RETR」ですが、コマンドプロンプトのFTPで打ち込むコマンドは「get」です。

 またコマンドプロンプトのFTPでは「mget」と打ち込めば複数ファイルを一度にダウンロードできますが、FTPのプロトコル上には、それに該当するコマンドはありません。ソフトウェアの内部で「RETR」を何度も繰り返し実行して、複数のファイルを一度にダウンロードしているように見せているだけです。

 どちらも文字のコマンドなので、とてもよく似たものに見えますが、コマンドプロンプトのFTPで使うコマンドは、人間が使いやすくなるように、またFTPのプロトコル上のコマンドは、なるべく単純で処理がしやすいように作られていると考えれば、理解もしやすいんじゃないでしょうか。

FTPだってこの手で実験! ほら理屈どおり

ちょっとフクザツなFTPこそ接続の様子が見たいのですが……

 FTPだってちゃんとTelnetで接続実験ができますよ。早速やってみましょう。そうそう実験を始める前に、FTPサーバにログインするためのユーザー名とパスワードを準備しておいてください。

 ここで気を付けておきたい点を1つ。実験に使うFTPサーバが、あなたの利用プロバイダで提供するものでない場合、FTP接続時のユーザー名とパスワードが、そのままの形でインターネット上を流れる可能性が高くなります。とても重要なFTPサーバなのであれば、実験には使わない方が無難です。できれば、利用プロバイダが提供するFTPサーバで実験してみるのがいいでしょう。

 Tera Termを起動したら、FTPサーバのポート21番に接続します。FTPサーバより“220”から始まるメッセージが返ってきたら、「USER ユーザー名」と入力し、さらに「PASS パスワード」を入力します。問題なく認証できたら「TYPE I」と入力して、転送モードをバイナリ(改行などの変換なし)に設定しておきます(画面1)。

220 ftp.atmarkit.co.jp FTP server ready.
USER foo
331 Password required for foo.
PASS AbCdEfGh
230 User foo logged in.
TYPE I
200 Type set to I.
PWD
257 "/home/foo" is current directory.
PASV
227 Entering Passive Mode (10,0,1,200,106,218)
LIST
150 Opening ASCII mode data connection for /bin/ls.
226 Transfer complete.
PASV
227 Entering Passive Mode (10,0,1,200,130,11)
RETR index.html
150 Opening BINARY mode data connection for index.html (68116 bytes).
226 Transfer complete.
QUIT
221 Goodbye.
Connection closed by foreign host.
画面1 コントロール用の接続でコマンドをやりとり

 さて、ここからがFTP特有の動作です。ここではPassiveモードで接続してみましょう。「PASV」コマンドを送ると、FTPサーバから「227 Entering Passive Mode (10,0,1,200,106,218)」のようなメッセージが返ってくるはずです。

 これが返ってきたら、もう1つTera Termのウィンドウを開いて、カッコの中に書いてあるIPアドレス/ポートに接続してください。最初の4つの数字がIPアドレスを表します。この例なら10.0.1.200です。最後の2つの数字はポート番号です。5けた目の数字に256を掛けたものに6けた目の数字を足したものが、接続するポート番号になります。106,218なら256×106+218=27354ですね。

 後から接続したTera Termのウィンドウには何も現れないと思いますが、それで問題ありません。このウィンドウがデータ転送用の接続になります。

 これでデータ転送用の接続ができました。先のウィンドウに戻り「LIST」コマンドを入力します。するとどうでしょうか? 後から接続したTera Termのウィンドウにファイルの一覧が表示されますね(画面2)。確かに、理屈どおり、FTPは二刀流の動作をしているようです。

total 48392
-rw-r--r-- 1 foo staff 383 Aug 21 2002 .cshrc
-rw-r--r-- 1 foo staff 4067 Aug 21 2002 .emacs
-rw------- 1 foo staff 2396 Jun 22 23:18 .history
-rw-r--r-- 1 foo staff 624 Aug 23 2002 .login
-rw-r--r-- 1 foo staff 290 Aug 22 2002 .mailrc
-rw------- 1 foo staff 321 Dec 30 1999 .message
-rw------- 1 foo staff 83 Aug 23 2002 .message~
-rw-r--r-- 1 foo staff 11 Aug 21 2002 .mh_profile
-rw-r--r-- 1 foo staff 1203 Aug 22 2002 .profile
-rw-r--r-- 1 foo staff 68116 Feb 10 10:03 index.html
-rw------- 1 foo staff 26046 Dec 7 2002 mbox
drwxr-xr-x 2 foo staff 512 Mar 29 2000 namazu
画面2 LISTコマンドで取得したファイル一覧

 ファイルの一覧が分かったら、次はファイルを取り出してみましょう。データ転送用の接続は、ファイルの一覧を表示した直後に切断されているので、さっきと同じように「PASV」コマンドを送り、表示されたポートにTera Termを接続しておきます。

 ファイルのダウンロードは「RETR ファイル名」とします。もちろんファイル名は先のファイル一覧の中にあるものを選んでください。指定したファイルがテキストファイルなら、後から接続したウィンドウにテキストファイルの内容が表示されているはずです(画面3)。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD 
HTML 4.0 Transitional//EN">
<HTML lang="ja">
<HEAD><!--ひらがな 漢字コード識別用--> 
<META HTTP-EQUIV="Content-Type" content="text/html;charset=SHIFT_JIS">
<META NAME="KEYWORDS" CONTENT="IT,情報技術,質問,ニュース,メールマガジン,掲示板,BBS,Windows,Linux,XML,ネットワーク,LAN">
<META NAME="DESCRIPTION" CONTENT="プロフェッショナルなIT技術者・管理者のためのコンテンツとコミュニティ満載の問題解決サイト。製品や技術に関する高度な解説記事や、掲示板、質問コーナーなど。">
<title>@IT - アットマーク・アイティ</title><link rel="stylesheet" type="text/css" 
href="/stylesheet/top.css">
<script language="JavaScript">
<!--
function MM_swapImgRestore() { //v3.0
var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) 
x.src=x.oSrc;
}
function MM_preloadImages() { //v3.0
var d=document; if(d.images){ if(!d.MM_p) 
d.MM_p=new Array();
var i,j=d.MM_p.length,a=MM_preloadImages.arguments; 
for(i=0; i<a.length; i++)
if (a[i].indexOf("#")!=0){ 
d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}
(以下省略)
画面3 RETRコマンドで取得したファイル

 もしファイルがテキストファイルでなければ、文字化けのような画面を表示することでしょう。本来表示できないファイルを、無理やり表示しようとするためそのような画面になります。

 ファイルのダウンロードに成功したら最後の「QUIT」を入力します。これでFTP接続が終了します。

 さて、いかがでしょうか? 二刀流の話とかセキュリティの問題とか、FTPにまつわる話はちょっとややこしいものが多いのですが、こうやって自分で試してみると、そんなに難しい感じがしないでしょう?まさに百聞は一見にしかずです。

次回予告

次回はさらに難関(?)のDNSをお送りする予定です。



Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。