FTP Passive モードフロー
FTP Active モードフロー - Shammerismで、FTP の Active 時の動作を見てみたが、今度は Passive 時の動作を見てみることにした。
コントロール通信
データのやりとりとコントロールのやりとりが別になっているのはActiveと同じ。違いは、サーバーがデータ送信のためのソケットをクライアントに Active オープンするのではなく、サーバーがデータ送信のためのソケットを Passive オープンされるという点。Active の時は、クライアントがサーバーに「このポートに接続しに来て」というのを伝えたが、Passive の場合はサーバーがクライアントに「このポートに接続しに来て」と伝える動作になる。
パケットフローをtsharkで見る
最初のパケットは以下のようなもの。FTPサーバーが動作していることをクライアントに通知するものだろうか。
File Transfer Protocol (FTP) 220 (vsFTPd 2.3.5)\r\n Response code: Service ready for new user (220) Response arg: (vsFTPd 2.3.5)
上記を受けて、クライアントはログイン情報を渡す。まずはユーザー名。
File Transfer Protocol (FTP) USER user\r\n Request command: USER Request arg: user
ユーザー名を受け取ったサーバーは、パスワードを要求する。
File Transfer Protocol (FTP) 331 Please specify the password.\r\n Response code: User name okay, need password (331) Response arg: Please specify the password.
クライアントはパスワードを渡す。平文なのか。。。
File Transfer Protocol (FTP) PASS password\r\n Request command: PASS Request arg: password
認証情報に問題なければ、サーバーはログインできたことをクライアントに通知。
File Transfer Protocol (FTP) 230 Login successful.\r\n Response code: User logged in, proceed (230) Response arg: Login successful.
これは、、、なんだっけか。心当たりがないが、クライアントからサーバーに投げている。SYSTというのはどうやらFTPのコマンドでシステム名を要求するもののようだが。勝手に実行されるのか?
File Transfer Protocol (FTP) SYST\r\n Request command: SYST
SYSTに対するサーバーの応答が以下。
File Transfer Protocol (FTP) 215 UNIX Type: L8\r\n Response code: NAME system type (215) Response arg: UNIX Type: L8
このタイミングでクライアントがActiveポートを通知している。
File Transfer Protocol (FTP) PORT 192,168,1,2,201,157\r\n Request command: PORT Request arg: 192,168,1,2,201,157 Active IP address: 192.168.1.2 Active port: 51613
そして、サーバーは通知されたポートを受理している。
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.
そして、クライアントから ls を実行。
File Transfer Protocol (FTP) LIST\r\n Request command: LIST
記載はしないが、このタイミングでサーバーからクライアントのポート51613に対して 3 Way Handshake が実行されている。どうやら、ls などのコントロール系のコマンドもデータ用のソケットが開いてそこで返されていたが、クライアントは ls の結果を表示させる前にサーバーから以下のような応答をコントロール通信で受け取っていた。
File Transfer Protocol (FTP) 150 Here comes the directory listing.\r\n Response code: File status okay; about to open data connection (150) Response arg: Here comes the directory listing.
応答はTCPのペイロードで「FTP Data」で始まるテキストになっていた。そして、サーバーからの応答の送信完了が以下のパケット。
File Transfer Protocol (FTP) 226 Directory send OK.\r\n Response code: Closing data connection (226) Response arg: Directory send OK.
asciiのファイル取得のため、asciiを実行したが、その際にはクライアントから以下のような内容のパケットがコントロール通信で送られる。
File Transfer Protocol (FTP) TYPE A\r\n Request command: TYPE Request arg: A
asciiに対するサーバーからの応答。
File Transfer Protocol (FTP) 200 Switching to ASCII mode.\r\n Response code: Command okay (200) Response arg: Switching to ASCII mode.
ここで passive をやってみた。クライアントからサーバーへは以下のパケットが送られる。
File Transfer Protocol (FTP) PASV\r\n Request command: PASV
passive に対するサーバーからの応答は以下。接続対象ポートを伝えてくるのはActiveモードの時と同じ。
File Transfer Protocol (FTP) 227 Entering Passive Mode (10,0,0,15,250,201).\r\n Response code: Entering Passive Mode (227) Response arg: Entering Passive Mode (10,0,0,15,250,201). Passive IP address: 10.0.0.15 Passive port: 64201
この直後、すぐに64201と接続していた。接続後に以下のget要求がコントロール通信で送信されているが、passiveの時間とgetの時間の間が短すぎて、passiveの直後にすぐに3 way handshake するのか、get があったから 3 way handshake したのかよくわからなかった。以下はクライアントからサーバーへの get 要求のパケット。
File Transfer Protocol (FTP) RETR run.txt\r\n Request command: RETR Request arg: run.txt
以下はサーバーの応答だが、上記のRETRの直後(次のパケット)だった。この時点ではまだファイル自体は送信されていなかった。今試した例では、この応答パケットの次からファイルが送信されていた。
File Transfer Protocol (FTP) 150 Opening ASCII mode data connection for run.txt (262 bytes).\r\n Response code: File status okay; about to open data connection (150) Response arg: Opening ASCII mode data connection for run.txt (262 bytes).
そして、ファイルの送信後に64201のソケットはクローズされ、そのクローズ後に以下の応答をコントロール通信で返している。
File Transfer Protocol (FTP) 226 Transfer complete.\r\n Response code: Closing data connection (226) Response arg: Transfer complete.
そして、クライアントでbyeを実行。コントロール通信でQUITがサーバーへ送信される。
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.
この後、コントロール通信がクローズされてやりとりが終了する。また見る機会があるかわからないが、今度見るときはコマンドとコマンドの間の実行間隔をわざと長くしてみよう。