FTPのアクティブモードとパッシブモード + vsftpdでの設定方法 | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。


テーマ:

普段からサーバー管理などで良く使うFTPですが、ひとえにFTPといっても内部的には2つの通信モード(アクティブモード(ポートモード)パッシブモード)が存在しています。

この辺の問題に絡み、FTPを設定したけどサーバーとうまく通信ができないなどの問題が起きる可能性もでてきますので、どっちのモードで動かすのが良いのかを理解しておく必要が出てきます。


まず、FTPの通信には2つのコネクションが必要になります。


1. FTPのコマンドなどをやり取りする制御用のコネクション

2. FTPを用いてデータやサーバー情報を転送をするためのコネクション


このうち2.のデータ転送用のコネクションの扱い方が2つの通信モードによって異なってきます。

具体的に2つの通信モードにて、サーバーへのFTPコネクションの確立からサーバー情報の取得までの流れを見てみたいと思います。


今回確認する構成は、下記のようになっています。


クライアント(192.168.0.100) → サーバー(192.168.0.200)


※ いづれもLinux環境です。



パッシブモードによる通信


まずパッシブモードによって通信の流れを見てみます。
最近のFTPクライアントの多くは、デフォルトでパッシブモードの通信を採用してたりします。


# ftp
ftp> open 192.168.0.200
Connected to 192.168.0.200.
220 (vsFTPd 1.2.1)
530 Please login with USER and PASS.
530 Please login with USER and PASS.
KERBEROS_V4 rejected as an authentication type

Name (192.168.0.200:root): foo
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.

デフォルトでパッシブモードの通信となるため明示的に指定はしていませんが、これでパッシブモードによるFTP接続ができました。

まず、このときの通信状況を見てみます。


# netstat -n
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address               Foreign Address          State
tcp        0      0 192.168.0.100:41900         192.168.0.200:21         ESTABLISHED

# netstat -n
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address               Foreign Address          State
tcp        0      0 192.168.0.200:21            192.168.0.100:41900      ESTABLISHED

クライアントからサーバーのポート21番へのコネクションが、制御用のコネクションです。
クライアントのポート番号は任意ですので接続のたびに変わります。


次に、クライアントからファイルをPUTしてみます。


ftp> put hoge.txt
local: hoge.txt remote: hoge.txt
227 Entering Passive Mode (192,168,0,200,4,74)
150 Ok to send data.

このときの通信状況を見てみると


# netstat -n
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address               Foreign Address          State
tcp        0  95568 192.168.0.100:40886         10.100.0.240:1086        ESTABLISHED
tcp        0      0 192.168.0.100:41900         10.100.0.240:21          ESTABLISHED

# netstat -n
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address               Foreign Address          State
tcp        0      0 192.168.0.200:1086          192.168.0.100:40886      ESTABLISHED
tcp        0      0 192.168.0.200:21            192.168.0.100:41900      ESTABLISHED

いづれも下に表示されている21番ポートは先ほど接続している制御用コネクションですが、その上のサーバー側のポート1086番に接続しているのがデータ転送用のコネクションです。

クライアント側の40886番ポートは接続のたびに変わりますが、サーバー側の1086番ポートは、サーバー側の設定によりある範囲に固定することができます(後述)


パッシブモードを図示すると下記のようになります。


A Day In The Boy's Life-FTP-パッシブモード



アクティブモード(ポートモード)による通信


次に、アクティブモードによる通信状況を同様に見てみます。


# ftp
ftp> passive
Passive mode off.
ftp> open 192.168.0.200
Connected to 192.168.0.200.
220 (vsFTPd 1.2.1)
530 Please login with USER and PASS.
530 Please login with USER and PASS.
KERBEROS_V4 rejected as an authentication type
Name (192.168.0.200:root): foo
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.

このときの通信状況を見てみると


# netstat -n
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address               Foreign Address          State
tcp        0      0 192.168.0.100:46674         192.168.0.200:21         ESTABLISHED

# netstat -n
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address               Foreign Address          State
tcp        0      0 192.168.0.200:21            192.168.0.100:46674      ESTABLISHED

ここまではパッシブモードと状況は変わりません。
次に、同じようにファイルをPUTしてみます。


ftp> put hoge.txt
local: hoge.txt remote: hoge.txt
200 PORT command successful. Consider using PASV.
150 Ok to send data.

この間の通信を見てみると


# netstat -n
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address               Foreign Address          State
tcp        0  95568 192.168.0.100:59660         192.168.0.200:33468      ESTABLISHED
tcp        0      0 192.168.0.100:46674         192.168.0.200:21         ESTABLISHED

# netstat -n
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address               Foreign Address          State
tcp        0      0 192.168.0.200:33468         192.168.0.200:59660      ESTABLISHED
tcp        0      0 192.168.0.200:21            192.168.0.200:46674      ESTABLISHED

サーバー側では59660番ポートを、クライアント側では33468番ポートを使ってデータを転送していることがわかります。

これらの状況からはわかりづらいですが、パッシブモードとアクティブモードとではどちら側から通信を開始するのか、という点が異なります。

FTPのアクティブモードの通信状況を図示すると下記のようになります。


A Day In The Boy's Life-FTP-アクティブモード


この辺りの動作については、下記の記事がわかりやすく解説されています。


FTPサーバの公開 @ パソコンおやじ


異種なるFTPのサーバ公開方法 @ Kung Noi


アクティブモードの場合は、クライアント側のIPやポートの情報をサーバーに伝え、サーバーから通信を開始してもらい、パッシブモードは逆でサーバーのIPやポート情報をもらって、クライアント側から再度データ転送用のコネクションを開始します。

アクティブモードは、サーバー側から通信を開始するためF/Wに引っかかったり、それを通す工夫をしようとしても使われるポートが不定の為、ACLを書きにくいというような問題があります。

そのために、パッシブモードというもう一つのモードが存在しています。



アクティブモードによるサーバー側の通信ポートの固定


サーバーとクライアントの通信ポートが接続のたびに変わるという状況は、色々不都合があります。

例えば、先の参考にさせていただいた記事の中で書かれているようなNAT環境での問題以外にも、F/WでFTPの通信を許可したいが、アクティブモードでは通信ポートがはっきりしないため、どこまでの範囲の穴を開けておけばよいかがわからないというような問題もあります。

極端に広い範囲で許可をしてしまうと、それはそれでセキュリティ上の問題にもなります。


vsftpdでは、アクティブモードによる通信のサーバー側の通信ポートを固定するオプションがあります。


connect_from_port_20=YES

このオプションを有効にすることでサーバー側のポートが20番に固定されます。

20番以外のポートを使いたい場合は、上記のオプションに加えて下記を指定します。(この場合、3000番ポートを使用)


ftp_data_port=3000

実際にFTPの通信状況を見てみると


tcp        0      0 192.168.0.100:33479          192.168.0.200:3000        ESTABLISHED

tcp        0 101360 192.168.0.200:3000           192.168.0.100:33479       ESTABLISHED


サーバー側のポートが3000番に固定されていることがわかります。

ただし、これは先ほど述べたように通信元のポート番号になるということに注意が必要です。



パッシブモードによるサーバー側の通信ポートの固定


次にパッシブモードの場合です。

パッシブモードの場合は、ポートをある範囲で受け付けるように指定します。


pasv_enable=YES
pasv_min_port=1050
pasv_max_port=1100

上記の場合は、1050番から1100番の範囲のポートが使われます。

こちらは、アクティブモードとは違い、通信先のポート番号になります。


tcp        0      0 192.168.0.100:33486         192.168.0.200:1075        ESTABLISHED

tcp        0 134664 192.168.0.200:1075          192.168.0.100:33486       ESTABLISHED


FTPと言えども採用する通信モードによって、通信の方向と、使われるポート番号が異なるので、環境に応じて適切なモードで運用する必要が出てきます。


2010.01.18 追記

FTPパッシブモードとアクティブモードの通信状況の図を追加