ネットの海の片隅でスマートフォン用の表示で見るネットの海の片隅で技術ネタの放流、あるいは不法投棄。Array[String]期待通りに動きます。pipeこのコードは正常に動作せず、例外を投げます。Array[String]EC2でもコレは動くので、接続先のFTPサーバがPASVモードを受け入れてくれるならPASVで繋げばOK。何が起こっているのかコントロールコネクションFTPクライアントがサーバとの間にコントロールコネクションを確立するまでには、概ねこんなことが起こっています。図がテキトーなのはご容赦ください*1。EC2上のクライアントがサーバに接続要求を送ろうとする。AWSのNATが送信元アドレスをプライベートアドレスからパブリックアドレスに書き換えてサーバに送る。サーバが返答をパブリックアドレス宛てに送り返す。NATが送信先アドレスをEC2のプライベートアドレスに書き換えてクライアントに届ける。NATが正常に仕事をしているため、コントロールコネクションが正常に確立されます*2。データ転送コネクションActiveモードでデータ転送コネクションの確立を試みるときは、概ねこんなことが起こっているはずです。EC2上のクライアントがサーバにFTPのPORTコマンドを送ろうとする。AWSのNATが送信元アドレスをプライベートアドレスからパブリックアドレスに書き換えてサーバに送る。PORTコマンドで指定した接続先アドレスとポートはTCPセグメントのヘッダ部ではなくデータ部に入っているため、書き換えられない。サーバがPORTコマンドで指定されたアドレス・ポートに接続しようとするが、プライベートアドレスであるため接続に失敗する。PORTコマンドでプライベートアドレスをサーバに送ってしまっているのが原因であって、EC2固有の問題ではなく一般的なNAT越えの問題です。解決のための方針PORTコマンドでパブリックアドレスを送る正攻法です。Groupで許可してあるポートを指定すれば良いと思います。ちなみに、RubyのNet::FTPクラスには任意のPORTコマンドを設定するメソッドはありません。NATがPORTコマンドのIPアドレスを書き換える市販のルータ製品にはFTPのPORTコマンド中に含まれているIPアドレスに対してNATと同様の処理を行なってくれる製品が結構あります*3。EC2を使っている場合にはそういった機能は使えません。仮に無理矢理実現するとなると、VPC内にプロキシを立ててEC2のデフォルトゲートウェイをそのプロキシに設定、プロキシにPORTコマンドを書き換える機能を実装するといった流れになると思います。まとめいにしえのプロトコルFTPは現代においては少し辛いものがある。解決したらまたエントリ書きます。追記Rubyだけですが、解決策を書きました。ネットの海の片隅で*1:描くのが楽そうだったのでシーケンス図を使いましたが、シーケンス図として見ないでください。*2:PASVモードのときはデータ転送コネクションもこの形式で確立されるため、正常にデータ伝送ができます。(3)月別アーカイブはてなブログをはじめよう!s_osaさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。