File Transfer Protocol(ファイル・トランスファー・プロトコル、FTP、ファイル転送プロトコル)は、コンピュータネットワーク上のクライアントとサーバの間でファイル転送を行うための通信プロトコルの一つである。

## 概説

インターネットでSSL/TLSプロトコルを用いたHTTPS通信が主流になるまで使用されていた通信プロトコルの1つである。FTPはクライアントサーバモデルのアーキテクチャとして設計されており、クライアントとサーバの間で制御用とデータ転送用の2つの別のコネクションを使用する。

FTPでは、認証のためのユーザ名・パスワードや転送データは暗号化されず、平文でやり取りされる。そのため現在では、FTPの通信をSSL/TLSにより保護したFTPSや、SSHの仕組みを利用したSSH File Transfer Protocol(SFTP)などの代替のプロトコルに置き換えられている。

用途としては

- ウェブページ用各種データファイル(HTMLソース、画像など)のクライアントのパソコンからウェブサーバへのアップロード
- パソコンソフト配布サイトや、データが入っているFTPファイルサーバからクライアントへのファイルのダウンロード
- LANにおけるファイルの転送

などに使われる。

アップロードやダウンロードについては「FTPクライアントソフト」と呼ばれるソフトウェアで行う。多くのOSにはCUIコマンドで操作するクライアントが付属している。また、GUIで操作できるソフトウェアやホームページ作成ソフトに内蔵されている。

ダウンロードについては、かつて多くのブラウザソフトにダウンロードに特化したFTPクライアントソフトの機能が実装されていたが、2020年代初頭に多くのブラウザがサポートを打ち切った 。

初期のFTPクライアントは、OSがGUIを持っていなかった時期に開発されたコマンドラインプログラムであり、今でもほとんどのOSに同梱されている。多くのFTPクライアントや自動化ユーティリティが開発されており、また、HTMLエディタなどの生産性アプリケーションにも組み込まれてきた。

## 歴史

FTPの元の仕様はアバイ・ブーシャンによって書かれ、1971年4月16日にRFC 114として公開された。1980年まで、FTPはTCP/IPの前身であるNCPで実行されていた。RFC 765(1980年6月)とRFC 959(1985年10月)によりFTPはTCP/IP上で動くバージョンに修正され、これが現行のFTPの仕様の元となっている。その後、RFC 1579(1994年2月)でファイアウォール内からでも使用できるパッシブモードが追加され、RFC 2228(1997年6月)ではセキュリティ拡張が提案された。RFC 2428(1998年9月)ではIPv6に対応し、新しい種類のパッシブモードが定義された。

## プロトコルの概要

### 通信とデータ転送

FTPの動作モードには、データ転送用コネクションの確立方法の違いによりアクティブモード(active mode)とパッシブモード(passive mode)がある。どちらの場合でも、データ転送用コネクションとは別に制御用コネクションを使用する。制御用コネクションは、クライアント側が、特権付きでないランダムなポート番号Nから、サーバのポート21へのTCPのコネクションとして確立する。

- アクティブモード(ポートモードとも言う)では、クライアントが制御用コネクションでFTPコマンド"PORT M"(Mはポート番号)をサーバに送信してポート番号を通知し、通知したポートMでサーバからのデータ転送用コネクションの接続を待ち受ける。サーバはポート20(FTPサーバのデータポート)からクライアントへのデータ転送用コネクションを確立する。
- ファイアウォールやNAT(IPマスカレード)などを使った環境では場合によってはアクティブモードでは接続できないこともある。この場合はパッシブモードを使用する。このモードでは、クライアントは制御用コネクションで"PASV"コマンドをサーバに送信してパッシブモードを利用することを通知し、サーバはクライアントにサーバ側のIPアドレスとポート番号を通知する。クライアントはサーバから通知されたIPアドレスとポート番号へデータ転送用コネクションを確立する。

1998年9月に、両方のモードはIPv6に対応するために更新され、パッシブモードには変更が加えられて拡張パッシブモード(extended passive mode)となった。

サーバは、制御用コネクションを介してASCIIの3桁の数字のステータスコードで応答する。ステータスコードにはテキストによるメッセージがつくことがある。例えば、"200"(または "200 OK")は、最後のコマンドが成功したことを意味する。数字は応答のコードを表し、追加のテキストは人間が読める説明または要求を表す。データ転送用コネクションを介したファイルデータの転送中、制御用コネクションを介して割り込みメッセージを送信することによって転送を中止することができる。

データ転送には以下の4つのデータ表現が利用できる。

- ASCIIモード: テキストデータに使用される。必要に応じて、送信側で送信ホストの文字表現から拡張ASCIIに変換され、受信側では受信ホストの文字表現に変換される。そのため、このモードはプレーンテキスト以外のデータを含むファイルには不適切である。
- バイナリモード(イメージモードとも言う): 送信側のマシンは各ファイルをバイト単位で送信し、受信側はバイトストリームを保存する。送信側・受信側ともデータの変換を行わない。FTPの全ての実装に対してバイナリモードの対応が推奨されている。
- EBCDICモード: EBCDIC文字セットを使用しているホスト間のプレーンテキストに使用される。
- ローカルモード: 同じ設定の2台のコンピュータが独自のフォーマットでデータをASCIIに変換することなく送信できるようにする。

データ転送は以下の3つのモードのいずれかで行うことができる。

- ストリームモード: データは連続したストリームとして送信される。FTPとしては処理は行わず、全ての処理をTCPに任せる。 データがレコードに分割されていない限り、End-of-file標識は必要ない。
- ブロックモード: FTPはデータをいくつかのブロック(ブロックヘッダ、バイト数、データフィールドから構成される)に分割してからTCPに渡す。
- 圧縮モード: 単純なアルゴリズム(通常は連長圧縮)でデータを圧縮してからTCPに渡す。

FTPソフトウェアの中には、「モードZ」と呼ばれるDeflateを使用した圧縮モードを実装しているものがある。このモードはインターネットドラフトに記載されているが、標準化はされていない。

### ログイン

FTPログインは、アクセスを許可するために通常のユーザ名とパスワードのスキームを使用する。ユーザ名はUSERコマンドを使用してサーバに送信され、パスワードはPASSコマンドを使用して送信される。この一連のやり取りは暗号化されていないため、盗聴攻撃に対して脆弱である。クライアントから提供された情報がサーバによって受け入れられた場合、サーバはクライアントにグリーティングを送信し、セッションが開始される。

### Anonymous FTP

FTPサービスを提供するホストは、専らファイル(主に無償のフリーソフトなど)を配布する目的で、匿名でアクセスできるAnonymousアクセスを提供することができる。この場合でも形式上認証が必要であり、ユーザ名として"anonymous"または"ftp"を指定する。パスワードは通常何でもよいが、配布したソフトに瑕疵があった場合などにサーバ管理者が連絡をとることができるよう、ユーザの電子メールアドレスを指定するのがマナー(ネチケット)とされてきた(メールアドレスのドメインがクライアントのIPアドレスの逆引きなどから明らかな場合は、"foo@"のようにドメインを省略することも多い)。サーバによっては、パスワードがメールアドレスの形式を満たさないと利用できないこともある。しかし、近年ではスパム(迷惑メール)などの問題により、むやみにメールアドレスを公開しない風潮が高まっていることから、このマナーは廃れつつある。

### NATやファイアウォールの通過

FTPは通常、クライアントがPORTコマンドを送信し、サーバがクライアントの通知されたポートに接続することによってデータを転送する。これは、インターネット側から内部ホストへの接続を許可しないNATやファイアウォールにおいて問題となる。NATの場合、PORTコマンドで通知するIPアドレスとポート番号は、NATによる変換後のものではなく、変換前のものとなる。

この問題を解決するには2つの方法がある。1つは、PASVコマンドを使用してパッシブモードに移行する方法である。これにより、FTPクライアント側からサーバへデータ転送用コネクションが確立される。これは現代のFTPクライアントにおいて広く使われている。もう1つは、NATがアプリケーション・ゲートウェイを使用してPORTコマンドの値を書き換える方法である。

### HTTPとの違い

FTPでは、Webページでよく見られるような多くの小さな一時的な転送に使用するのが不便であり、HTTPではそれを修正している。

FTPには、現在の作業ディレクトリと他のフラグを保持するステートフルな制御用コネクションがあり、転送するファイルごとに、データを転送するための別のコネクションを必要とする。パッシブモードでは、この別のコネクションはクライアントからサーバへの接続であるが、デフォルトのアクティブモードでは、このコネクションはサーバからクライアントへの接続である。アクティブモードにおけるこの役割の逆転、および全ての転送において使用されるポート番号がランダムであることが、ファイアウォールやNATゲートウェイを通してFTPを使用することを困難にしている。HTTPはステートレスであり、クライアントからサーバへの、Well-knownなポート番号による単一のコネクションを介して、制御とデータを多重化する。これにより、NATゲートウェイやファイアウォールの通過が簡単になる。

FTPの制御用コネクションの設定は、必要な全てのコマンドを送信して応答を待つまでに往復遅延があるため、非常に遅くなる。そのため、毎回セッションを破棄して再確立するのではなく、制御用コネクションを確立した後、それを複数のファイル転送のために開いたままにするのが一般的である。これとは対照的に、HTTPはその方が安価であるため、元々転送ごとにコネクションを切断していた。その後、HTTPには複数の転送に1つのTCP接続を再利用する機能が追加されたが、概念モデルとしてはセッションではなく独立した要求である。

FTPがデータ用コネクションを介して転送している間、制御用コネクションはアイドル状態である。転送に時間がかかりすぎると、ファイアウォールやNATは制御用コネクションが無効であると判断してそれを追跡しなくなり、事実上接続が切断されてしまう。HTTP接続においてはアイドル状態となるのは要求と要求の間のみであり、タイムアウトした後にコネクションがドロップされるのは正常で、予期されたものである。

## Webブラウザの対応

かつてはほとんどの一般的なWebブラウザは、FTPサーバに格納されているファイルを取得することができた。しかし2020年以降主要ブラウザはあいついでFTPサポートを廃止した。

## セキュリティ

FTPは、インターネット初期から存在する古いプロトコルであり、セキュア(安全)なプロトコルとして設計されていない。ユーザ名やパスワードなどの認証情報を含むすべての通信内容を暗号化せずに転送するなどの問題の他、数多くのセキュリティ脆弱性が指摘されている。RFC 2577(1999年5月)では、以下の脆弱性が列挙されている。

- 総当たり攻撃
- FTPバウンス攻撃
- パケットキャプチャ
- Port stealing(次に開いているポートを推測して正当なコネクションを奪う)
- スプーフィング攻撃
- ユーザ名保護
- DoS攻撃

FTPは通信内容を暗号化できない。全ての送信は平文で行われるため、通信経路上でパケットをキャプチャすることで、ユーザ名・パスワード・コマンド・データといった情報を容易に盗聴できる。この問題は、TLS/SSLなどの暗号化メカニズムが開発される前に設計された他のインターネットプロトコル仕様(SMTP、Telnet、POP、IMAPなど)でも同様である。

この問題に対する一般的な解決策は、次の通りである。

1. 安全なバージョンのプロトコルを使用する。例えば、FTPの代わりにFTPS、Telnetの代わりにTelnetSを使用する。
2. SSH File Transfer Protocol(SFTP)やSecure Copy Protocol(SCP)など、ジョブを処理できるより安全なプロトコルを使用する。
3. Secure Shell(SSH)やVPNなどのセキュアトンネルを使用する。

FTPは、Gumblarなどのコンピュータウイルスの標的にもされた。そのため、現在では、FTPではなく前述の FTPS (SSL/TLSを使ったFTP) や SFTP (SSH File Transfer Protocol)、SCP、SSH上でのrsync、など暗号化された手法を用いることが強く推奨される。

### FTP over SSH

FTP over SSHは、Secure Shell接続を介して通常のFTPセッションをトンネリングする方法である。FTPは複数のTCP接続を使用するため、SSHを介してトンネリングすることは特に困難である。多くのSSHクライアントでは、制御チャネル(ポート21による最初のクライアントとサーバの間の接続)用にトンネルを設定しようとすると、そのチャネルだけが保護される。データを転送するときは新しいTCP接続(データチャネル)を確立するため、機密性や完全性の保護はない。

そのため、SSHクライアントソフトウェアがFTPプロトコルの情報を持ち、FTP制御チャネルのメッセージを監視して書き換え、FTPデータチャネルのための新しいパケット転送を自律的に開く必要がある。

## 派生プロトコル

### FTPS

明示的FTPS(Explicit FTPS)は、クライアントがFTPセッションの暗号化を要求できるようにするFTP標準の拡張である。これは、"AUTH TLS"コマンドを送ることによって行われる。サーバには、TLSを使用しない接続の許可・拒否のオプションがある。このプロトコル拡張は、RFC 4217で定義されている。

暗黙的FTPS(Implicit FTPS)は、SSL/TLS接続の使用を必要するFTPの古い標準であり、通常のFTPとは異なるポートを使用するように指定されていた。

### SFTP

SSH File Transfer Protocol(SFTP)は、ファイル転送にSecure Shell(SSH)プロトコルを使用する。FTPとは異なり、コマンドとデータの両方を暗号化し、パスワードや機密情報がネットワークを介して公に送信されるのを防ぐ。FTPサーバやクライアントとは相互運用できない。

### TFTP

Trivial File Transfer Protocol(TFTP)は、クライアントがリモートホストからファイルを取得したり、リモートホストにファイルを保存したりすることを可能にする単純なロックステップのFTPである。TFTPは認証を行わないため実装が非常に簡単であり、主にネットワークブートの初期段階で使用される。TFTPは1981年に最初に標準化された。TFTPの現在の仕様はRFC 1350である。

### Simple File Transfer Protocol

Simple File Transfer Protocolは、TFTPとFTPの中間的なレベルの複雑さを持つFTPとして提案された。RFC 913で定義されている。このプロトコルもSSH File Transfer Protocolと同様"SFTP"と略称されるが、この略称を持つプロトコルの中ではSimple File Transfer Protocolの方が先に標準化されている。このプロトコルはインターネットで広く受け入れられず、このRFCはIETFによって"Historic"(歴史的文書)の状態とされている。

ポート115を介して実行され、多くの場合SFTPの初期設定を受信する。11のコマンドと、ASCII・バイナリ・連続の3つのデータ転送を持つ。 ワードサイズが8ビットの倍数であるシステムでは、バイナリモードと連続モードの実装は同じである。このプロトコルは、ユーザーIDとパスワードによるログイン、階層フォルダーとファイル管理(名前の変更、削除、アップロード、ダウンロード、上書きダウンロード、追加ダウンロード)に対応する。

## その他の同様の目的に使えるプロトコル

- HTTP/WebDAV
- Secure copy(SCP)
- Rcp
- rsync
- Network File System(NFS)
- Server Message Block(SMB)/CIFS (Samba)

## FTPリターンコード

FTPサーバから返されるリターンコードはRFC 959で標準化されている。リターンコードは3桁の数値である。

1桁目は、成功、失敗、エラー・不完全な応答のいずれかを示す。

- 2yz – 成功応答
- 4yz, 5yz – 失敗応答
- 1yz, 3yz – エラー・不完全な応答

2桁目は、エラーの種類を表す。

- x0z – 構文。構文エラーを表す。
- x1z – 情報。情報の要求に応答する。
- x2z – コネクション。制御用コネクションやデータ用コネクションに関するエラーを表す。
- x3z – 認証とアカウント。ログインプロセスとアカウントに関するエラーを表す。
- x4z – 未定義。
- x5z – ファイルシステム。サーバのファイルシステムからのステータスコードを中継する。

3桁目は、2桁目で定義されている各カテゴリの詳細情報を提供するために使用される。