Making passive FTP work

Q Unfortunately, I have recently had my system security compromised and I am now running iptables to filter traffic into my Fedora server. The server runs a corporate website and anonymous FTP for software downloads. I am allowing incoming traffic to port 80 and ports 20 and 21. However, I am unable to download files from the server via FTP when connecting using passive transfers - the connection just times out. Can you help me?

A The reason passive FTP is not working is that in passive transfer mode the server tells the client to open a new connection to it on an arbitrary high port (above 1024). However, the firewall needs to be configured to accept traffic on this port in particular, as if you open up all the high ports then essentially your server will be wide open again. This was a classic problem with older software firewalls and packet filters (such as ipchains and ipfwadm). However, iptables can do stateful connection tracking. First you'll need to verify that you have ip_conntrack and ip_conntrack_ftp compiled into the kernel or compiled as a loadable module (this should be the case with a stock Fedora kernel). With this done you can add the following iptables rules:

# The following two rules allow the inbound FTP connection
iptables -A INPUT -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
# The next 2 lines allow active ftp connections
iptables -A INPUT -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT
# These last two rules allow for passive transfers
iptables -A INPUT -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT

In the active FTP transfer rules above the client sends the server a high port to connect to and the server connects to this port from port 20 to initiate the transfer. However, if the client is also behind a firewall that isn't stateful then this will not work, and passive transfers will be required.

Back to the list