PerlでFTPプログラムを作る際、パッシブモードが原因で、うまくプログラムが動かない方必見です。
root権限でrsyncの利用により、サーバ間でファイルを移動し、ファイルのバックアップを行っていたが、sshのrootログインが禁止になったので、FTPでファイルを移動するプログラムに書き換えて欲しいという依頼がありました。
Perlには、FTPモジュールという便利なモジュールがあり、簡単にFTPアクセスを行うプログラムを書くことができます。そこで、
use Net::FTP;
open (STDERR, ">>エラー出力ファイル名");
$ftp=Net::FTP->new(サーバーIP)||warn("Could't connect host.\n");
$ftp->login(ユーザー名,パスワード)||warn("login failed.\n");
$ftp->cwd(接続先でのファイルのあるディレクトリ);
$ftp->get(移動するファイル名)||warn("file GET failed.\n");
$ftp->quit;
close STDERR;
として、アイ・コンピュータサービスから、プログラムを実行したところ、うまくファイルをGETすることができました。ところが、お客様の環境でプログラムを実行すると、うまくファイルをGETすることができません。サーバ間に、 SonicWALLが入っているのが原因で、passiveモードでしか、FTPのやり取りができないのです。
FTPモジュールには、pasv()メソッドがあり、『$ftp->pasv()』をプログラムに追加したところ、一応プログラムはまわるようになりましたが、ファイルGETの箇所でエラーが発生します。
悩んだあげく、Passiveコンストラクタを使用したところ、うまくファイルをGETすることができました。Passiveコンストラクタは、0以外の値を設定すると、全てのデータ転送はパッシブモードを使って行われるとのことなので、1を設定してみました。
以下は、PASVモードでFTP接続する時のプログラムのサンプルです。『Passive => 1』を、3行目に付け加えます。
$ftp=Net::FTP->new(サーバーIP, Passive => 1)||warn("Could't connect host.\n");
pasv()メソッドの使い方をよく調べていないのですが、悩む前に、Passiveコンストラクタを利用した方が、手っ取り早いです。2005/2/15
参考:vsftpdでTCP 20番から待ち受けポートを変更
|