There’s lots of advice on the net about how to setup a server with iptables to allow passive mode FTP. Below is the approach that we’ve found to be most effective.
Start by configuring your FTP daemon to use a fixed range of ports. We use 41361 to 65534 which is the IANA registered ephemeral port range. The exact config depends on what FTP software you’re using:
vsftpd
Edit /etc/vsftpd/vsftpd.conf and add the following lines:
proftpd
Edit /etc/proftpd.conf and add to the Global section:
3 | PassivePorts 49152 65534 |
Now restart your FTP service so the changes take effect.
Next you’ll need to configure the ip_conntrack_ftp iptables module to load. On Redhat/CentOS just edit /etc/sysconfig/iptables-config and add “ip_conntrack_ftp” to the IPTABLES_MODULES like this:
1 | IPTABLES_MODULES= "ip_conntrack_ftp" |
Next edit /etc/sysconfig/iptables and add a rule to allow TCP port 21.
The new line is marked in red:
05 | -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT |
06 | -A INPUT -p icmp -j ACCEPT |
07 | -A INPUT -i lo -j ACCEPT |
08 | -A INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT |
09 | -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT |
10 | -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT |
11 | -A INPUT -j REJECT --reject-with icmp-host-prohibited |
12 | -A FORWARD -j REJECT --reject-with icmp-host-prohibited |
Now restart the iptables service:
1 | /sbin/service iptables restart |
You can verify that the correct port range has been registered with lsmod like this:
1 | lsmod | grep conntrack_ftp |
and you’ll get something like this:
1 | nf_conntrack_ftp 12913 0 |
2 | nf_conntrack 79645 4 nf_conntrack_ftp,nf_conntrack_ipv4,nf_conntrack_ipv6,xt_state |
And that’s all it takes to get passive mode ftp working behind iptables.
P.S: If your server is behind a physical firewall and you are behind NAT, then you’ll probable need to load the “ip_nat_ftp” iptables module.