前回は、FTPのコネクション管理など基本的な概念について解説した。今回はそのほかのコマンドや機能について見てみよう。
前回説明しなかった、そのほかのコマンドについて解説しよう。また、別表に用意したコマンド一覧も参考にしてほしい(こちらをクリックすると、別ウィンドウでコマンド一覧を表示します)。
CWDは「Change Working Directory」、CDUPは「Change Directory to UP」の意味だ。FTPでは「ワーキングディレクトリ」という考え方がある。今現在ユーザーがログインして作業中のディレクトリ位置を指す。UNIXのシェルやDOSプロンプトと同じ考え方だ。「カレントディレクトリ」と呼ばれることもある。
CWDは指定したディレクトリへと、ワーキングディレクトリを移動するコマンドだ。ディレクトリ名は、絶対パスでも現在のワーキングディレクトリからの相対パスでも構わない。CDUPは現在のディレクトリの1つ上、つまり親ディレクトリへ移動するコマンドだ。ディレクトリの書式はUNIX方式を採用している。サーバがWindowsであっても、「/dir1/subdir1」といった「/」(スラッシュ)を用いた表記を行う。
また、一般にFTPで使用されるディレクトリは「仮想ディレクトリ」だ。必ずしもサーバ側のファイルシステムをそのまま適用することはない。FTPサーバの仕様にもよるが、通常はHTTPのドキュメントルートのように、FTP向けに用意された「仮想ルート」が最上位ディレクトリとなり、それ以下のディレクトリしかユーザーには提供されない。これはセキュリティ確保のためである。
NLSTとLISTは共に、ワーキングディレクトリのファイル一覧表示を行うためのコマンドだ。OSのコマンドである「ls」や「dir」と同じ機能である。クライアントがファイルの送受信に先立って、サーバのファイル情報を得るために使用される。この結果はデータコネクションを用いて得られる。つまり、事前にデータコネクションの確立が必須である。
NLSTは単にファイル名だけの一覧を表示する。ファイル名やディレクトリを指定すると、該当するファイル/ディレクトリのみ表示する。NLSTコマンドでは、属性などの表示は省かれる。これは、サーバ側のOSによって属性情報が変わることもありえるからだ。相手がどのOSであっても、基本的な最低限の情報を得るのがNLSTコマンドの目的である。
これに対してLISTコマンドでは、属性を含めた詳細な情報を表示する。表示形式のベースとなっているのはUNIXの「ls」コマンドだ。アクセス権限やファイルサイズなども含めて表示される。
ただし、FTPサーバがWindowsなどの場合には、このフォーマットが変わることもありえる。これらの結果フォーマットについては仕様上はなんら規定はしていない*1。UNIX型の表示フォーマットを前提にしてしまうことは、本来はできないので注意が必要だ。実際、Windows 2000のFTPサービスでは、表示形式をMS-DOS形式に変更することもできる。
なお、NLSTコマンドは引数として表示オプションを受け入れることができる。元来はUNIXの「ls」コマンドのオプションを想定していたが、現在では「-al」オプションのみ利用できることが多い。-alオプションによる結果は、LISTコマンドと同様になる。
*1◆fontsize=-1◇こうした問題を解決すべく、拡張仕様が現在IETFのワーキンググループで検討されている。MLSTコマンド(拡張リストの取得)やMDTMコマンド(ファイル時刻の取得)などで、より正規化されたフォーマットでファイルリストを得ようという試みだ。こうした流れは、GUI製品が主流となってきた現在、大変重要な仕様であり、将来新たなRFCで修正される可能性も高い。そのほか、レジューム機能(RESTコマンドの拡張)など興味深い仕様も多く含んでいるので、詳しくはこちらからたどれる"Extensions to FTP"を参考にしてほしい
SITEコマンドは標準のFTPコマンドでは実行できない、サーバOSに応じた任意のコマンドを実行する。引数は、その実行するコマンドそのものである。例えば、CGIプログラムをサーバへ転送した後に、アクセス権限に実行権を付加したい場合もある。サーバがUNIX/Linuxであれば、次のようにアクセス権を変更できる。
元々はFTPコマンドで表現できない機能を、新たな追加コマンドを用意するのではなく、このSITEコマンドで対応できるようにしたものだ。なお、必ずしもすべてのOSコマンドが無条件で実行できるわけではない。多くのサーバでは、実行可能なOSコマンドは制限されている。どのOSコマンドが許可されているか、「HELP SITE」コマンドで確認することもできる。
現在実行中のデータコネクションの転送を中止する。
先頭がXで始まるコマンドは「実験的」コマンドだ。正式には仕様に含められていない可能性がある。ただし、正式なコマンドに昇格した後も、互換性のために「正式なコマンド名」と「実験時のコマンド名」は双方とも残し続けることが推奨されているので、ほとんどの場合は、正式なコマンドとセットになっているはずだ。
FTPの利用には一点、大きな問題がある。それはファイアウォール環境での利用だ。前回説明したように、コントロールコネクションはクライアントからサーバへ、データコネクションはサーバからクライアントへ接続される。つまり、ファイアウォール環境下では、データコネクションは外部から内部へ張られるのだ。これはセキュリティ違反となり、FTPは使用できないことになる。
そこで、ファイアウォール環境で外部のFTPサーバと通信するFTPクライアントでは、PASVコマンドを用いるのが普通だ。PASVは「パッシブモード」と呼ばれる動作モードへの切り替えコマンドだ。PASVコマンドが引数なしで与えられると、サーバは次のようなレスポンスを返す。
227 Entering Passive Mode (192,168,1,11,87,195)
この ( ) 内の表記は、PORTコマンドの引数と同じだ。PORTコマンドと同じく、サーバが「このIPアドレスのこのポートへデータコネクションを接続せよ」と答えているわけだ。サーバ側でデータコネクションを準備するので、これに応じて、クライアントはこのアドレスとポートへデータコネクションを確立可能になる。
このように、パッシブモードによって、データコネクションもクライアントからサーバへ向けて張ることができるため、ファイアウォールをスムーズに通過できるようになるのだ。また、パッシブモードに対して、PORTコマンドを用いた通常の動作を「アクティブモード」と呼ぶ。
ほかのプロトコル同様、日本語など多言語環境におけるFTPの振る舞いについても言及しておかなければなるまい。とは言うものの、FTPにおける多言語対応の話は簡単である。まったく考慮されていないのだ。ただし、使用できないという意味ではない。
元々FTPはSMTPなどと違い、通信は8ビット環境を(正確にはデータコネクションにおいて)許容している。つまり、SJISであろうとEUCであろうと、ファイル名などに使用するのは自由だ。この8ビットコードがそのままクライアントへ届けられるだけのことだ。
当然、ファイルの内容が8ビットだったとしても、すでに述べたようにバイナリモードで転送すればそのままのコードで転送されるし、アスキーモードの場合は改行コードが(クライアントやサーバの実装にもよるが)OSに応じて変換されるだけである。
逆に言えば、プロトコルはまったく関与しないので、文字コードに対する対応はFTPクライアントやサーバが行わなければならないということだ。実際のFTP関連製品などでは、サーバ側の文字コードはそのOSに依存しており、それをFTPクライアントが各種文字コードに応じて変換するなどして、対応している場合が多いようだ。
なお、近年ではUTF8を使用するようにしようとの拡張仕様も登場しつつある。
FTPの特徴であるデータコネクションを用いた、少し面白い使い方を紹介してみよう。FTPサーバから別のFTPサーバへの直接ファイル転送である。
普通の感覚では、あるサーバから別のサーバへとファイルを転送したい場合には、FTPクライアントを用いて一度ローカルHDDへファイルを保存して、再度別のFTPサーバへあらためてファイルを送信する、という方法が一般的だろう。HTTPでのファイルのダウンロード/アップロードでは、専用のCGIでも作らない限りこの方法でしか行えない。しかし、FTPではプロトコルの動作だけでサーバ間の直接ファイル転送が可能だ。
(1) まず、FTPクライアントがファイルの送信元FTPサーバと送信先FTPサーバそれぞれに、コントロールコネクションを用いて普通にログインする
(2) 次に、送信先FTPサーバに対してPASVコマンドを実行して、送信先FTPサーバへのデータコネクションのIPアドレス(つまり送信先FTPサーバ自身のIPアドレス)とポート番号を入手する。この時点で、送信先FTPサーバではデータコネクションの受け入れ準備が整うはずだ
(3) そして今度は、PASVコマンドで入手した送信先FTPサーバのIPアドレスとポート番号を用いて、送信元FTPサーバに対して「PORT」コマンドを用いて「送信先FTPサーバのIPアドレスとポート番号」を送り、送信元FTPサーバと送信先FTPサーバ間でデータコネクションを作成する
(4) 最後に、送信先FTPサーバにはSTORコマンドを、送信元FTPサーバへはRETRコマンドをそれぞれ発行すれば、データコネクションを通じて、送信元FTPサーバから送信先FTPサーバへとファイルが転送できる。あるいは、データコネクションを張る方向(PASVとPORTコマンドを発行するサーバ)は逆でもよい
これは、別に裏技というわけではない。実はRFC959にも記載されている真っ当な使用方法だ。特に、クライアント/サーバ間の回線が遅い場合などには、非常に重宝できる手法である。ただし、こうした使い方を実装しているFTPクライアントはあまりないようだ。
FTPの柔軟性と洗練されたプロトコル特性を示す、興味深い一例である。
POP3の回に、Telnetによる接続確認方法について説明したことを覚えているだろうか。FTPではコネクションが複数必要になるなど若干複雑だが、Telnetベースのアプリケーションであることに変わりはない。当然、Telnetで動作をシミュレーションしてみることも可能だ。
FTPは動作が多少複雑な分、実際に試してみることで、より理解も深まるだろう。以下に例を挙げてみよう。まず試すのは最も簡単な、サーバ上のファイル一覧の表示だ。
(1) まずTelnetで、FTPサーバのポート21番に接続する。例えばWindowsのDOSプロンプトで「telnet FTPサーバ 21」と入力する。サーバからグリーティングメッセージが表示されるはずだ。これがコントロールコネクションになる
(2) USERコマンドとPASSコマンドを用いてログインを行う。ログインできれば、その旨が表示され、ログインユーザーの初期ディレクトリがワーキングディレクトリとなる
(3) 目的のディレクトリへ移動しよう。CWDコマンドで移動したら、PWDコマンドでワーキングディレクトリを確認する
(4) 通常のFTPコマンドであれば、ここでPORTコマンドを実行して、サーバからのデータコネクションの接続を待てばよいのだが、残念ながらTelnetではそこまでのシミュレーションはできない。サーバ機能をローカルPCで起動するには、専用のプログラムでも用意しない限り行えないからだ。そこで、パッシブモードを使用することにする。データコネクションにもこちらからTelnetで接続してみるわけだ。
「PASV」と入力しよう。レスポンスから、データコネクションはサーバのIPアドレスが「192.168.1.11」、ポート番号が「27481」であることが分かった。そこで、別のDOSプロンプトから「telnet 192.168.1.11 27481」を実行する。何もサーバから表示は返ってこないが、これでデータコネクションにも接続できた
(5) LISTコマンドを最初のDOSプロンプトで入力する
(6) データコネクション用DOSプロンプトにLISTコマンドの結果、ワーキングディレクトリのファイル一覧が表示される。結果が表示されるとサーバが接続を切るので、Telnetは自動的に終了する
(7) LISTコマンドの代わりにRETRコマンドを用いれば、ファイル内容を受信(画面に表示)することもできる。STORコマンドの場合は、EOF(End Of File)を示すバイトコードを最後に挿入するのが面倒だが、コピー/ペーストでデータコネクションのTelnetの画面に貼り付ければ、とりあえずの送信はできる。色々試してみてほしい
FTPは、これまで解説したインターネット・プロトコルとも少し勝手の違う特異な特徴を持つ。これは、OSによるファイルシステムなどの差異をどのように吸収すべきかという、現在では当然となったマルチプラットフォーム対応への、もっとも早い時期におけるチャレンジの結果の1つでもある。
しかし決して、古びた使い物にならないプロトコルではなく、現在のインターネット興隆期にこそ広く利用されている事実は、その完成度の高さを示すものだろう。インターネットの技術を作り上げてきた連綿たる技術者たちから現在の私たちへの、まさに「贈り物」であるわけだ。
最後に:
約半年に渡った本連載も今回が最終回となった。インターネットを支える技術を、動作原理とその歴史的背景から分かりやすく解説したいという筆者のもくろみは、少しは成功しただろうか。
できる限り読者の貪欲な知的好奇心に答えられたならよいなと願いつつ、ここまでお読みいただいた皆さんに、最後に心からお礼申し上げたい。ありがとうございました。
Copyright © ITmedia, Inc. All Rights Reserved.