ProftpdでNATの外からPASVで接続する

うーん。ハマった。高度なことがしたいわけじゃなくてただFTPプロトコルでファイル転送したいだけなのに。

Proftpdでよかったのかどうかも分からないけども。インストールは

$ sudo apt-get install proftpd

で終わる。途中Standaloneかinetdか聞かれたけどもよくわからないのでStandaloneにしておいた。

LAN内からなら問題なくFTPに接続できるが、外からだとPASVで接続できない。正確には接続はできるけど、LISTできない。

まずLAN内からPassiveで接続してみる。

$ ftp -d mydomain.com
Connected to mydomain.com.
220 ProFTPD 1.3.1 Server (Debian) [::ffff:192.168.1.1]
ftp: setsockopt: Bad file descriptor
Name (mydomain.com:username): username
---> USER username
331 Password required for username
Password:
---> PASS XXXX
230 User username logged in
---> SYST
215 UNIX Type: L8
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> passive
Passive mode on.
ftp> ls
ftp: setsockopt (ignored): Permission denied
---> PASV
227 Entering Passive Mode (192,168,1,1,187,84).
---> LIST
150 Opening ASCII mode data connection for file list
drwxr-xr-x   2 username  group      4096 May  6 05:20 tmp
226 Transfer complete

UserとPasswordいれてpassiveでPASVモード有効。その後lsコマンド。という流れ。

これをルーターの設定が不完全なまま外から同様に試みると

ftp> passive
Passive mode on.
ftp> ls
ftp: setsockopt (ignored): Permission denied
---> PASV
227 Entering Passive Mode (123,123,123,123,195,45).
ftp: connect: Connection refused

Connection refusedと言われて。取得できない。
かといってPORTでいけるかっていうと、ダメらしい。たぶん20番ポートが空いてないから。

ProftpdのconfにはPassiveモードのための設定項目があるけども、どうもルーターが対応している場合、この項目はコメントアウトしたままでいいという話がある。
FTPサーバの構築(ProFTPD)

ルーターの設定は20番と21番を開放して、FTPポートの番号を書く項目もあったので通常の21番にしてある。

Passiveモードの場合、データ転送用のポートは任意の空きポートのレンジを指定してそこを使ってクライアントからコネクションしてもらうらしい(なのでクライアントがNAT内にあっても大丈夫、サーバーが攻めではなく受けだからPassiveということか)。だとすると、使用していないポートをいくつか追加で開放しなくてはいけないのでは?と思ったのだけども、Planexのマニュアルによると

LAN側のFTPサーバをインターネットに公開する場合は、tcpポート21番宛てのトラフィックをLAN側FTPサーバに転送する静的マスカレード設定を行ってください。本製品はFTPpasv/port両方の転送方式をサポートしており、データコネクションポートのマスカレードが必要な場合、本製品が自動的にポートを空けるため、データコネクション用の静的マスカレードは不要です。ただし、WAN側からLAN側FTPサーバへのアクセスには、できるかぎりportモードを利用してください

と書いてあるので、21番だけFTPサーバーに向ければあとは自動でやってくれるんじゃないか?と思っていたのだけど、どうもうまく行かない。

で、解決策かどうかは分からないけど、宛先不明パケットは全部サーバーへ行くように設定してみた。これでWANからPASVでの接続は可能にはなる。

しかしセキュリティ的に危険な気がする。うーん……。

ルーターのPASV対応を信じないでProftpd側の設定でやってみる

まず、適当なポートを開放する。10000-10010とか。
して
/etc/proftpd/proftpd.confを

$ sudo vi /etc/proftpd/proftpd.conf
# In some cases you have to specify passive ports range to by-pass
# firewall limitations. Ephemeral ports can be used for that, but
# feel free to use a more narrow range.
PassivePorts                  10000	10010
# If your host was NATted, this option is useful in order to
# allow passive tranfers to work. You have to use your public
# address and opening the passive ports used on your firewall as well.
MasqueradeAddress		mydomain.com
$ sudo vi /etc/init.d/proftpd restart

PassivePortsとMasqueradeAddressをコメントアウトしてポートのレンジとドメインを書き換えて再起動。

すると、外部からはPASVで接続できるようになるが、今度はLAN内から接続できなくなる。指定したマスカレードアドレスがグローバルIPなので内側から参照できなくてConnection Refusedする。Hostsに書いてあるのも使ってくれない。

内側からならPORTでいけるけど……。