Shammer's Philosophy

My private adversaria

FTP Active モードフロー

FTPのやり取りをパケットで見る機会があったのでメモ。

コントロール通信

FTPでは、コマンドのやり取りをする接続と実際にファイルをやり取りする接続が分かれている。そして、通常はこのコントロール用にサーバーは21番ポートで待ち受ける。この接続では、ls だとか pwd を始め、Active/Passiveの切り替え、Text/Binaryの切り替えなどもこのコントロール通信で行われ、データの通信に使用するためのポートもこのコントロールで決定する。Activeモードは、FTPサーバーがクライアントに対してデータ通信のための接続を行うモード。サーバーがActiveコネクションを張るのでActiveモードということだ。そのためには、クライアントがポートをオープンし、サーバーに「ポートXXX番に接続しにきてくれ」と伝えないといけない。

パケットフローをtsharkで見る

コントロール通信の最初は以下が返される。

File Transfer Protocol (FTP)
    220 (vsFTPd 2.0.5)\r\n
        Response code: Service ready for new user (220)
        Response arg: (vsFTPd 2.0.5)

ユーザーは、ユーザー名とパスワードを以下のように送付する。

File Transfer Protocol (FTP)
    USER user01\r\n
        Request command: USER
        Request arg: user01
File Transfer Protocol (FTP)
    PASS XXXXX\r\n
        Request command: PASS
        Request arg: XXXXX

問題なければ、サーバーから以下が返ってくる。

File Transfer Protocol (FTP)
    230 Login successful.\r\n
        Response code: User logged in, proceed (230)
        Response arg: Login successful.

ダウンロード前にファイル形式を指定する。

File Transfer Protocol (FTP)
    TYPE I\r\n
        Request command: TYPE
        Request arg: I

Type I は Image だ。これを受けて、サーバーはモードを変更する。

File Transfer Protocol (FTP)
    200 Switching to Binary mode.\r\n
        Response code: Command okay (200)
        Response arg: Switching to Binary mode.

そして、クライアントはデータ通信用のポートをサーバーに通知。

File Transfer Protocol (FTP)
    PORT XX,XX,XX,XX,PP,PP\r\n
        Request command: PORT
        Request arg: XX,XX,XX,XX,PP,PP
        Active IP address: XX.XX.XX.XX
        Active port: PPPP

マスクしているが、XX.XX.XX.XX はクライアントのIPで、PP,PP はポートを16進数にしたもの、PPPPは10進数表記のポートだ。これを受理したサーバーは以下のような応答を返す。

File Transfer Protocol (FTP)
    200 PORT command successful. Consider using PASV.\r\n
        Response code: Command okay (200)
        Response arg: PORT command successful. Consider using PASV.

サーバーからデータ通信用のコネクションを接続しにいく Active モードでなく、サーバーがデータ通信用のポートを開く Passive モードの使用も検討してくれ、っぽいメッセージも見えるが。大抵はActiveモードがデフォルトな印象なのだがそれはさておき、、、この後でクライアントはデータ取得のためのコマンドを発行する。Active モードだとクライアントが取得というより、クライアントはサーバーにデータを送ってもらうという感じなのだが。

File Transfer Protocol (FTP)
    RETR XXX.IMG\r\n
        Request command: RETR
        Request arg: XXX.IMG

ここで指定されたポートに対して 3 way handshake が行われ、3 way handshake 完了時に以下のようにデータ用コネクションの完了がコントロール通信でも行われる(これはサーバー発)。

File Transfer Protocol (FTP)
    150 Opening BINARY mode data connection for XXX.IMG (XXX bytes).\r\n
        Response code: File status okay; about to open data connection (150)
        Response arg: Opening BINARY mode data connection for XXX.IMG (XXX bytes).

この後、データ通信側では指定したサイズのデータ転送が行われ、完了後にデータ通信用コネクションはクローズされる。そして、完了・クローズしたことがコントロール側でも通知される。これもサーバー発。

File Transfer Protocol (FTP)
    226 File send OK.\r\n
        Response code: Closing data connection (226)
        Response arg: File send OK.

これで最低限の一連の流れが終了。次のファイルがあれば、また上記のように TYPE や RETR が繰り返される。終了時にはクライアントが以下のようなメッセージを送付し、

File Transfer Protocol (FTP)
    QUIT\r\n
        Request command: QUIT

サーバーが以下の応答を返してコントロール通信が終了する。

File Transfer Protocol (FTP)
    221 Goodbye.\r\n
        Response code: Service closing control connection (221)
        Response arg: Goodbye.