Net::FTPでNAT越えする
解決したいこと
- FTPはActiveモードを使った時にデフォルトでNATを越えられない。
- NAT越えのためにはFTPのPORTコマンドを適切に使用する必要がある。
- RubyのNet::FTPにはPORTコマンドあるいは似たようなオプションが無い。
- RubyアプリケーションでNAT越えのFTP通信(EC2から外向き)ができない。
無いなら作る
Net::FTP#port
を生やして、設定したアドレスとポートを元に通信するためのgemを書いた。
使い方
基本的にはGitHubの方に書いてある通り。
require 'net/ftp' require 'net/ftp/port_command' ftp = Net::FTP.new("exmaple.com", "username", "password") ftp.port("203.0.113.5", 10020) # サーバ側からのデータコネクションを待ち受けるアドレスとポート ftp.list # => ["foo.txt", "bar.txt"]
一度設定したアドレスとポートは明示的に解除されるまでずっと有効*1。
ftp.port(nil, nil) # デフォルトの動作に戻す
さいごに
Net::FTPとその周辺のコードを読むのには苦労したけど、読み終わってからの設計・実装はすぐにできた。
コードも実質10行くらいしかないけど、少なくとも自分にとって非常に役に立つ10行になるはずだし、今までで一番良いgemを書いたと思っている。