[PHP-users 35666] ftp関数について

gotou1213 @ gmail.com gotou1213 @ gmail.com
2012年 2月 16日 (木) 03:28:26 JST


ある環境のPHP(5.3.2)のftp関数で、パッシブモードを指定しているにも関わらず、
FTPサーバのログを見ると PORT コマンドが発行されていることがあり、
PHPのftp拡張のソースコードを元に調査したところ、
下記のようなコードで、意図せず PORT コマンドが発行されることがわかりました。

============================================================
`iptables -F`;
`iptables -A INPUT -j REJECT -p tcp --sport 20`;

$ftp = ftp_connect($addr, $port, 1);

ftp_login($ftp, $id, $pw);

ftp_pasv($ftp, true);
/* (1) */ ftp_put($ftp, "0001.txt", __FILE__, FTP_BINARY);

`iptables -A INPUT -j DROP -p tcp --sport 21`;

/* (2) */ ftp_put($ftp, "0002.txt", __FILE__, FTP_BINARY);

`iptables -R INPUT 2`;

/* (3) */ ftp_put($ftp, "0003.txt", __FILE__, FTP_BINARY);
/* (4) */ ftp_put($ftp, "0004.txt", __FILE__, FTP_BINARY);

ftp_close($ftp);
============================================================

元々アクティブモードでは通信できないサーバに対して、
  (1)でファイルを正常にアップロードした後、
  (2)の ftp_put の応答が何らかの原因で DROP され、
  その後、(3)と(4)でファイルのアップロードを試みた、
という動作をイメージしています。

このとき (2)〜(4) でそれぞれ次の通り PHP Warning が発生しています。
  (2) Warning: ftp_put(): Transfer complete in /tmp/ftp.php on line 22
  (3) Warning: ftp_put(): Entering Passive Mode (192,168,1,100,225,80). in /tmp/ftp.php on line 26
  (4) Warning: ftp_put(): PORT command successful in /tmp/ftp.php on line 27

FTPサーバ側では次の通りログが記録されています(コマンド 応答コード バイト数 の順)。
  "USER hoge" 331 -
  "PASS (hidden)" 230 -
  "PASV" 227 -
  "TYPE I" 200 -
  "STOR 0001.txt" 226 1760
  "PASV" 227 -
  "PORT 192,168,1,101,136,135" 200 -
  "PORT 192,168,1,101,199,141" 200 -
  "STOR 0004.txt" 425 0
  "QUIT" 221 -

ftp拡張のソースを見た感じ、(2)の ftp_put の中で発行されている PASV コマンドの
応答が DROP されると、その次の(3)からはアクティブモードになってしまうようです。

また、PHP Warning の内容も、以下のように1個ずれたような感じになっています。
  (2) のエラーメッセージは (1) の転送完了のメッセージ
  (3) のエラーメッセージは (2) の PASV の応答メッセージ
  (4) のエラーメッセージは (3) の PORT の応答メッセージ

単にアクティブ/パッシブだけの問題であれば、ftp_put の前に
必ず ftp_pasv を呼べば解決するかと思ったのですが、
エラーメッセージがずれる問題は、実際にコマンドと応答の対応が
ずれていてまともな通信が行えない状態になっているようなので、
この問題を解決するには、ftp関数でなんらかのエラーが発生した場合は
必ず接続を閉じて再接続する以外に方法が無さそうに思うのですが、
上記のような症状について、なにか良い情報をお持ちの方はいらっしゃらないでしょうか?


PHP-users メーリングリストの案内