a tomato

トマトが大好きです

iptablesでアクティブモードFTPが通るように設定する

ftpクライアント側でiptablesを利用するケースが発生し、ftp通信を許可する設定(tcp:20, tcp:21)をしたところ、ls等のデータコネクションで通信を行うコマンドがエラーになってしまいました。

ftp 192.168.10.1
Connected to 192.168.10.1 (192.168.10.1).
220 (vsFTPd 2.2.2)
Name (192.168.10.1:kzdev): xxxxx
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
425 Failed to establish connection.

これは、クライアント側からデータコネクションを確立にいくため、ランダムポート(1024〜65535)から動的に選択されてしまいます。そのため、tcp:20, tcp:21を開いてもランダムポートでの通信が通らないのです。

これだと、通信を行うには、iptablesを無効にしてしまうか、ランダムポートを全て許可しなければならず、ファイアウォールの意味をなさなくなってしまいます。 こんな時に使えるのが、ip_conntrack_ftpです。

このモジュールは、制御ポートを通してクライアントから通知されるデータコネクションやパッシブモードで利用するポート番号を自動的に開閉してくれる便利なモジュールです。

まずは、モジュールが存在しているか確認を行います。

$ lsmod | grep ftp

ない場合は、以下を実行してカーネルモジュールをロードする

$ modprobe ip_conntrack_ftp 
$ lsmod | grep ftp
nf_conntrack_ftp       11953  1 nf_nat_ftp
nf_conntrack           79206  4 nf_nat_ftp,nf_nat,nf_conntrack_ipv4,nf_conntrack_ftp

参考

Linuxコマンド集 - 【 modprobe 】カーネルモジュールをロードまたはアンロードする:ITpro

iptablesの起動スクリプトである/etc/sysconfig/iptables-configに以下の行を記述する。

IPTABLES_MODULES="ip_conntrack_ftp"

iptablesにモジュールをロードさせるため、サービスを再起動させる。

$ service iptables restart

これで、iptablesが有効な状態でFTP接続とデータコネクションの通信が無事に通るようになりました。