Linux – Forward FTP traffic to a local sever through iptables

ftpiptableslinuxnat;networking

I have a load balanced infrastructure which has an edge server as the load balancer and some web servers as backend servers and a cpanel server which is my ftp server. I want to forward ftp traffic through iptables to the ftp server which is behind my load balancer server. The scenario is as follows:

LB:
ens19: public_ip
ens18: 192.168.1.105

ftpserver:
eth0:192.168.1.110

the OS of LB is CentOS 7 and the OS of ftpserver is CentOS 6. I have disabled firewalld and installed iptables. the Rules for nat ftp traffic is as follows:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited

-A FORWARD -j LOG

-A FORWARD -i ens19 -o ens18 -p tcp --syn --dport 21 -m conntrack --ctstate NEW -j ACCEPT

-A FORWARD -i ens19 -o ens18 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A FORWARD -i ens18 -o ens19 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT


*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -i ens19 -p tcp --dport 21 -j DNAT --to-destination 192.168.1.110:21
-A POSTROUTING -o ens18 -p tcp --dport 21 -d 192.168.1.110 -j SNAT --to-source 192.168.1.105
-A POSTROUTING -s 192.168.1.0/24 -o ens19 -j MASQUERADE
COMMIT

I also added the following line to iptables-config file:
IPTABLES_MODULES="ip_nat_ftp ip_conntrack_ftp"

and the net.ipv4.ip_forward = 1.

after I want to connect to ftp I get the following error:

$> ftp public_ip
Connected to public_ip.
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 1 of 50 allowed.
220-Local time is now 11:19. Server port: 21.
220-This is a private system - No anonymous login
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.
Name (public_ip:sinai): ftp_user_name
331 User ss@mihankhabar.net OK. Password required
Password:
230 OK. Current restricted directory is /
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful
425 Could not open data connection to port 29806: Connection timed out
ftp> 

I think login process is done completely and the problem is for transferring data. May you please help me to resolve this issue?

Thanks in advanced.

Best Answer

So its connecting OK, but not transferring data. FTP uses 21TCP to establish a connection, but 20TCP to send/receive data. Try duplicating your forward/SNAT/DNAT rules for 20TCP too:

-A FORWARD -i ens19 -o ens18 -p tcp --syn --dport 20 -m conntrack --ctstate NEW -j ACCEPT

-A PREROUTING -i ens19 -p tcp --dport 20 -j DNAT --to-destination 192.168.1.110:21

-A POSTROUTING -o ens18 -p tcp --dport 20 -d 192.168.1.110 -j SNAT --to-source 192.168.1.105

Or you could try passive mode FTP. In that scenario, the server connects back to the client (port 20 again) to transfer data, so that outbound connection should traverse the NAT router OK.