2015年7月28日火曜日

node.jsからどうしてもFTPアクティブ接続がしたい貴方に

 私もそんな少数派の一人であります。
 なぜなら接続先がパッシブ接続を受け付けてくれないからであります(ちゃんと構成してくれよ…)。

 そもそもnode.jsとか以前に、アクティブ接続をするからには、FTPサーバからのデータコネクションを受け入れるポートが開いてないといけません。
 ポート決め打ちせずFTP接続モジュールだけ特別扱いする方法もあるのですが、安易にiptablesの、SSHとかHTTPを許可してる行に寄り添う場所に
# accept FTP
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8686    -j ACCEPT
を追加いたしました。こんなんでマジいいのか?

※実際追加したポート番号は8686ではなくいちおう内緒ですので8686をアタックしてこないようお願いいたします。



 さてnode.jsにはアクティブ接続をしてくれるFTPクライアントがありません。jsftpもftpも残念ながらパッシブ接続しかできないのです。

 そこでlftpをchild_process.execから利用ということになります。command引数は、たとえばls情報がほしい場合は

'lftp -e "set ftp:ssl-allow off;set ftp:passive-mode off;set ftp:auto-passive-mode no;set ftp:port-range 8686-8686;recls -1B nanika/path;exit;" -u oresama,oresamapass 123.456.789.012'

という感じになります。
 こうするとexecのコールバックのstdout引数にファイル・ディレクトリ一覧が改行区切りで入ってきます。
 パッシブとかSSLに絶対ならないようこれでもかと設定しています。これらのうちどれかの設定は省けるかもしれませんが面倒なので試していません。
 FTPクライアントからFTPサーバに通知するデータコネクション受け入れポートをつねに、さっきiptablesで穴開けた8686番一択に固定しています。こんなことしてFTP標準的には許されるんでしょうか、よく知りません。

 まぁ動いているのでとりあえずいいかとしておきますが、そんなんヤベーよというお教えお待ちしております。

※ちなみにreclsの-Dはなぜか動作しませんでした(--長い名前のほうも)。