Debian, ferm, vsftpd, NAT and passive ftp

I just had a terrible time trying to figure out how to enable passive ftp to a vsftpd in a NAT. So I decided I'd probably help someone if I documented the steps needed to get this to work.

First of all, the firewall is configured with ferm. It's on your NAT gateway, of course. Configure a NAT as you would normally and then make a forwarder using the example from the ferm manpage. I changed it a bit since I don't want to forward on an interface, but on an IP address:

def &FORWARD_TCP($inc, $proto, $port, $dest) = {
        table filter chain FORWARD interface ethZ daddr $dest proto $proto dport $port ACCEPT;
        table nat chain PREROUTING daddr $inc proto $proto dport $port DNAT to $dest;

Forward ftp to the internal ftp server

&FORWARD_TCP(x.x.x.x, tcp, ftp, y.y.y.y);

Replace ethZ with the interface that contains the public IP address. Keep in mind that if you use aliases (ethZ:0 or something like it), you need to specify the actual physical NIC device (ethZ). Also, replace x.x.x.x with the public IP address by which someone needs to connect to the FTP server. And replace y.y.y.y with the internal address of the FTP server.

Now, load the connection tracking modules into the kernel. THIS IS IMPORTANT!

modprobe ip_conntrack_ftp

modprobe ip_nat_ftp

The last part is the easiest, disable SSL connections in vsftpd. You can't do this with encrypted connections, because than ip_conntrack_ftp will not be able to READ the ports it needs to open for the client! There is no way around this, as far as I know. (Except of course, not using FTP at all... Which is why we prefer SCP... But that's a whole other story.)

Add this to you vsftpd.conf:


Also, be sure to NOT use the pasv_address directive in your vsftpd.conf! It sounds like something you want, but trust me, you do not want it enabled :)

That's it, this works for me :)

Technorati tags:


Comments powered by Disqus