[OpenBSD]

[前に戻る: 性能] [目次] [次に進む: authpf: 認証ゲートウェイ用 ユーザシェル]

PF: FTP における問題


目次


FTP のモード

FTP は、インターネットがまだ小さく、コンピュータ同士は友好的な接続を持ち、 誰もが他の人たちを知っていた、そのような時代に作成されたプロトコルです。 そのころはフィルタリングの必要性もなく、固いセキュリティは不要な時代でした。 そのためか、FTP はフィルタリングやファイアウォールの通過、あるいは NAT で使用するのに向かない設計となっています。

FTP はふたつの方法、受動的接続 (passive) か能動的接続 (active) のうちのいずれかの方法で 使用することができます。一般的に active か passive かの選択は、ファイアウォールでの FTP の使用に問題があるかどうかで決定されます。現実的には、ユーザが幸せになるために、 両方の方法をサポートすべきでしょう。

FTP の能動的接続モードでは、ユーザがリモートの FTP サーバに接続して 情報やファイルを要求する際に、要求されたデータを転送するために FTP サーバからクライアントに対して新しい接続を行います。これは データ接続 (data connection) と呼ばれる接続です。FTP クライアントは、 この接続を受信するためのランダムな空ポートを選択します。FTP クライアントは、 選択したポート番号を FTP サーバに送信し、そのポートで FTP サーバからの 接続の着信を待ちます。そして、FTP サーバは、クライアントのアドレスの 選択されたポートに対して接続を開始し、データ転送を行います。しかし、これは、 NAT の向う側にある FTP サーバからの接続を、ユーザが受信しようとする場合に 問題となります。NAT がどのように働くのかという理屈を考えるとわかりますが、 FTP サーバは NAT ゲートウェイの外部アドレスの選択されたポートに対して接続して、 データ接続を開始しようとするからです。そして、NAT マシンがこの接続を受信しますが、 NAT マシンはその状態テーブルにパケットのマッピングを持っていないので、 このパケットは廃棄され、それがクライアントに配信されることはないのです。

FTP の受動的接続モード (これは OpenBSD の href="http://www.openbsd.org/cgi-bin/man.cgi?query=ftp&sektion=1&manpath=OpenBSD+3.4" >ftp(1) クライアントのデフォルトのモードです) では、クライアントがサーバに データ接続を待ち受けるためのランダムなポートを選択するよう、要求を出します。 サーバはクライアントに選択したポートの情報を伝え、クライアントはそのポートに接続して データ転送を行います。不運にも、FTP サーバの手前にあるファイアウォールが、着信する データ接続をブロックしてしまうかも知れませんので、これは常に可能だったり、 期待できたりするわけではありません。OpenBSD の ftp(1) クライアントは、受動的接続モードを デフォルトで使用しますが、強制的に能動的接続モードで FTP を使用するには ftp に -A フラグを指定するか、"ftp>" プロンプトで "passive off" コマンドを 発行することで、受動的接続モードを "off" に設定するかのいずれかの方法で可能です。

ファイアウォールの向こう側の FTP クライアント

上記のとおり、FTP は NAT やファイアウォールをうまく通過することができません。

パケットフィルタ (PF) は、FTP プロキシサーバを通過する FTP のトラフィックを リダイレクトすることで、このような状況に対する解決策を用意しています。 この処理は、NAT ゲートウェイやファイアウォールを通過する FTP トラフィックを 「案内」するように動作します。OpenBSD と PF で使用される FTP プロキシは、 ftp-proxy(8) です。これを有効化するには、pf.conf の NAT セクションに以下のような行を追加します。

rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 \
   port 8021

この行の記述は、「内部インターフェイス上のトラフィックは、 ポート 8021 をリスンする、このマシン上で実行されている プロキシサーバにリダイレクトする」という意味になります。

できれば、プロキシサーバが OpenBSD を実行するマシン上で動作するようにしたいのではないでしょうか。 これは、以下のような行を /etc/inetd.conf に 追加することで可能になります。

127.0.0.1:8021 stream tcp nowait root /usr/libexec/ftp-proxy \
   ftp-proxy

そして、システムをリブートするか、HUP シグナルを inetd(8) に送信するかのどちらかを実行してください。HUP シグナルを送信するには以下のようにします。

kill -HUP `cat /var/run/inetd.pid`

ftp-proxy がポート 8021 をリスンし、同じポートを上記の rdr 命令文が FTP トラフィックを送信しているということに注意する必要があるでしょう。ポート 8021 の選択は任意のものですが、8021 は他のいかなるアプリケーションによっても 定義されていないので、これは良い選択であると言えるでしょう。

ftp-proxy(8) は、PF フィルタの背後の FTP クライアントを助けるためのものであって、PF フィルタの背後の FTP サーバを扱うために使用するものではないということに注意してください。

PF による FTP サーバの "自己防御"

この場合、PF はファイアウォール専用のコンピュータ上ではなく、FTP サーバ 自身の上で実行されます。受動的接続の FTP 接続に対するサービスを行う場合、 FTP はランダムに選択した、高い番号の TCP ポートを着信データ用に使用します。 デフォルトでは、OpenBSD に附属の FTP サーバ ftpd(8) は、49152 から 65535 の範囲のポートを使用します。 明らかに、これらのポートは、(FTP の制御用ポートである) ポート 21 と同様、 フィルタルールを通過できなければなりません。
pass in on $ext_if proto tcp from any to any port 21 keep state
pass in on $ext_if proto tcp from any to any port > 49151 \
   keep state

もし、その必要性があれば、これらのポートの範囲を大幅に厳しくすることができます。 OpenBSD の ftpd(8) プログラムの場合、これは sysctl(8) の変数 net.inet.ip.porthifirst および net.inet.ip.porthilast を使用して制御することができます。

PF で NAT を実行する外部の ファイアウォールにより保護されている FTP サーバ

この場合は、ファイアウォールは FTP サーバへのトラフィックをリダイレクトする必要があり、 またリダイレクトされるポートはブロックしてはいけません。この議論のために、問題の FTP サーバが、今回も、デフォルトのポートの範囲を使用する標準的な OpenBSD の ftpd(8) であると仮定します。

以下は、この目的を達成するためのルールのサブセットの例です。

ftp_server = "10.0.3.21"

rdr on $ext_if proto tcp from any to any port 21 -> $ftp_server \
   port 21
rdr on $ext_if proto tcp from any to any port 49152:65535 -> \
   $ftp_server port 49152:65535

# in on $ext_if
pass in quick on $ext_if proto tcp from any to $ftp_server \
   port 21 keep state
pass in quick on $ext_if proto tcp from any to $ftp_server \
   port > 49151 keep state

# out on $int_if
pass out quick on $int_if proto tcp from any to $ftp_server \
   port 21 keep state
pass out quick on $int_if proto tcp from any to $ftp_server \
   port > 49151 keep state

FTP についてのより詳しい情報

FTP のフィルタリングについてのより詳しい情報や、一般的に FTP がどのように 動作するのかということの回答を、以下の白書に見つけることができるでしょう。

[前に戻る: 性能] [目次] [次に進む: authpf: 認証ゲートウェイ用 ユーザシェル]


[back] www@openbsd.org
Originally [OpenBSD: ftp.html,v 1.12 ]
$Translation: ftp.html,v 1.13 2004/02/01 12:35:38 toshi Exp $
$OpenBSD: ftp.html,v 1.12 2004/02/25 18:31:45 jufi Exp $