GCE に構築した FTP サーバに接続ができない?!解決方法!
投稿者:Taneda
オンプレミス環境で稼働中のシステムをパブリッククラウドへ移行する場合、移行に合わせてシステムのモダナイゼーションをできると一番良いのですが、なかなかそうもいかないものです。
特にファイルインタフェースはユーザ側の要望などの理由から生き残ってしまうことも多いのではないでしょうか?個人的な感覚ですが、FTPもまだまだ現役で活躍している印象です。
このブログではGoogle Cloud Platfoem(GCP)の仮想マシンであるGCE上にFTPサーバ(vsftpd)を立てる際に陥りやすい問題の解決方法の1つをご紹介します。
ファイアウォール等の設定は問題ないのに何故か接続できない場合には一度チェックしてみてください。
解決方法
いきなりですが解決方法です。
/etc/vsftpd/vsftpd.conf に以下の一行を追記してみてください。
pasv_address=[VMインスタンスに割り当てた外部IPアドレス]
解説
GCPの観点とvsftpdの観点から解説します。
GCPの外部IPアドレスについて
GCEに割り当てる外部IPアドレスはVMインスタンスのインタフェースに割り当てられる訳ではなく、静的NATとして機能していると考えてよいでしょう。
実際にOS上でコマンドを実行してみると以下のようになっており、OSからは外部IPアドレスは認識されないことがわかります。
$ ip addr show
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1460 qdisc pfifo_fast state UP group default qlen 1000
link/ether 42:01:0a:80:0f:da brd ff:ff:ff:ff:ff:ff
inet 10.128.15.218/32 brd 10.128.15.218 scope global noprefixroute dynamic eth0
valid_lft 86382sec preferred_lft 86382sec
inet6 fe80::4001:aff:fe80:fda/64 scope link noprefixroute
valid_lft forever preferred_lft forever
この、OSからは外部IPアドレスは認識されないことがこの後説明するvsftpdの設定に効いてきます。
vsftpd 側の設定 (pasv_address) について
FTP サーバに対してパッシブモードで接続する場合、コントロールコネクションの中でデータコネクション用の IP アドレスとポート番号をクラアント側に通知します。
データコネクションでは通知された IPアドレス/ポートに対して接続を要求します。
FTPクライアントに通知されるデータコネクション用IPアドレス/ポートは以下のパラメータで指定することができます。
- IP アドレス:pasv_address
- ポート:pasv_min_port / pasv_max_port
ただし、pasv_addressが指定されていない場合はインタフェースに割り当てられているIPアドレスをクライアント側に通知します。そのため、NATの背後にあるFTPサーバに対してパッシブモードで接続する場合は、pasv_addressを指定しないとデータコネクションの宛先がローカルIPアドレスとなり接続がタイム・アウトしてしまいます。
まとめ
GCPの外部IPアドレスの仕組みを知ることで、pasv_addressの設定が必要となる理由がご理解いただけたのではないでしょうか?
なお、GCPの外部 IPアドレスだけでなくAWSの Elastic IP addressも同様の仕組みが用いられているため、ご紹介した内容はAWS上にFTPサーバを構築する際も利用できます。
おまけ
インターネットとVPNの両方からFTPサーバにアクセスが必要な場合はインターネット側からの接続にのみpasv_addressを設定する必要があります。そのため複数の設定ファイルを作成して、複数のFTPサービス(vsftpd.service)を起動してください。
ListenポートがどちらもTCP/21でないといけないとかでなければポート単位でサービスを分ける方式をおすすめします。
分割の単位 | GCPの設定 | vsftpdの設定 |
---|---|---|
インタフェース | 複数のネットワーク インターフェースを持つインスタンスの作成※ | listen_addressを指定 |
IPアドレス | エイリアス IP 範囲の構成 | listen_addressを指定 |
ポート | 特になし | listen_portを指定 |
※ 仮想マシン作成後にインタフェースの追加はできなので注意してください。