1

Okay so I use the simple linux ftp client to download/upload files off ftp servers. I have an iptables firewall which blocks most of the ports and I have to close the firewall for it to work. Although port 21 is open but I guess that explains why the download works and not the upload. The following command works perfectly with the firewall on:

wget ftp://user:[email protected]

I just have problems when I actually connect to the server and try to "put"/upload a file to the server. Here is an example netstat output of the port used at that time but it's always different.

netstat -a | grep ServerIP
tcp        0 197520 myIP.:59622 ServerIP:ftp-data ESTABLISHED
tcp        0      0 myIP.:40341 ServerIP:ftp      ESTABLISHED

Both the ports on myIP range are blocked and I'm failing to guess what ports do I have to open. Google search fails as well. Secondly, if I try something like this on iptables, it gives me an error:

-A INPUT -p tcp --match multiport --dport 40000:40500 -j ACCEPT
iptables-restore v1.4.8: too many ports specified

Secondly, why would I need to open the ports when I have the following line before the ports were blocked in the configuration file:

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

2 Answers 2

3

A possible cause is that you use active FTP.

FTP has an active and a passive mode.


Active:

In active mode FTP the client connects from a random unprivileged port (N > 1023) to the FTP server's command port, port 21. Then, the client starts listening to port N+1 and sends the FTP command PORT N+1 to the FTP server. The server will then connect back to the client's specified data port from its local data port, which is port 20.

Passive:

In order to resolve the issue of the server initiating the connection to the client a different method for FTP connections was developed. This was known as passive mode, or PASV, after the command used by the client to tell the server it is in passive mode. In passive mode FTP the client initiates both connections to the server, solving the problem of firewalls filtering the incoming data port connection to the client from the server. When opening an FTP connection, the client opens two random unprivileged ports locally (N > 1023 and N+1). The first port contacts the server on port 21, but instead of then issuing a PORT command and allowing the server to connect back to its data port, the client will issue the PASV command. The result of this is that the server then opens a random unprivileged port (P > 1023) and sends P back to the client in response to the PASV command. The client then initiates the connection from port N+1 to port P on the server to transfer data.

-- Active FTP vs. Passive FTP, a Definitive Explanation


This means that you have two options:

  1. Easy option: Use the passive mode
  2. Hard option: Allow incoming connections from port 20, from any host which you have already an established connection from.

I'd choose option 1

4
  • I know that already but I don't see PASV might help because it has to be dealing with ports that are blocked as well. So whether it's PASV or Active, it has to use some ports and I only have a small range of accepted ports and those too are rate-limited to some extent.
    – Asad Moeen
    Jul 18, 2013 at 19:44
  • I see now. Well it's impossible to predict the ports of the outgoing traffic. The system chooses for every application a random port unless the application is a server and binds a specific socket. Therefore you should manage the rules on basis of the destination port. Jul 18, 2013 at 20:53
  • Any ideas why does the rule of accepting ESTABLISHED state doesn't work?
    – Asad Moeen
    Jul 19, 2013 at 5:55
  • @AsadMoeen The ESTABLISHED rule is not working because it matches established streams, not established IPs. In other words, it's going to match things based on the 5-tuple (source IP, dest IP, protocol, source port, dest port). See my answer. Jul 19, 2013 at 15:02
1

To accomplish option 2 from Christopher Perrin's answer, you can use the recent match extension. It adds source IP address to a list that you can check against in subsequent rules. For these rules, I've assumed eth0 is your WAN interface.

iptables -A FORWARD -o eth0 -p tcp --dport 21 -m state --state ESTABLISHED -m recent --name trustedftp --set
iptables -A FORWARD -i eth0 -p tcp --sport 20 -m recent --name trustedftp --seconds 30 --rcheck -j ACCEPT

I haven't tested this, but I think it should work.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .