Top Nav

Passive Mode FTP with iptables

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:


Edit /etc/vsftpd/vsftpd.conf and add the following lines:


Edit /etc/proftpd.conf and add to the Global section:

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:

Next edit /etc/sysconfig/iptables and add a rule to allow TCP port 21. The new line is marked in red:

Now restart the iptables service:

You can verify that the correct port range has been registered with lsmod like this:

and you’ll get something like this:

And that’s all it takes to get passive mode ftp working behind iptables.

One extra note: If your server is NATed behind a physical firewall then you’ll probable need to load the “ip_nat_ftp” iptables module.

On a AWS EC2 server with vsftpd I had to add “pasv_address=x.x.x.x” to the /etc/vsftpd/vsftpd.conf file where x.x.x.x was the public (elastic) address of the server. On an AWS EC2 server with Plesk and proftpd I had to add “MasqueradeAddress x.x.x.x” to a new file at /etc/proftpd.d/1-pasv_addr.conf.

  • Michael Hodgdon

    Solved my issue with the Extra note. iptables-config was missing the module ip_nat_ftp.

  • Castet01

    essaie ceci:

    export IPT=’sudo /sbin/iptables’

    $IPT -A INPUT -m state –state NEW,RELATED -p tcp ! –tcp-flags ALL SYN -j DROP

    # http + ftp + active ftp + pasv ftp
    $IPT -A OUTPUT -p tcp –dport 80 -m state –state ESTABLISHED,NEW -j ACCEPT
    $IPT -A OUTPUT -p tcp –dport 21 -m state –state ESTABLISHED,NEW -j ACCEPT
    $IPT -A OUTPUT -p tcp –dport 20 -m state –state ESTABLISHED -j ACCEPT
    $IPT -A OUTPUT -p tcp –dport 50000:60000 -m state –state RELATED,ESTABLISHED -j ACCEPT

  • fulgorek

    Works like a charm ;D

  • Diego

    [root@development ~]# lsmod | grep conntrack_ftp
    nf_conntrack_ftp 12913 0
    nf_conntrack 79645 3 nf_conntrack_ftp,nf_conntrack_ipv4,xt_state
    [root@development ~]#
    [root@development ~]#
    [root@development ~]# service iptables restart
    iptables: Flushing firewall rules: [ OK ]
    iptables: Setting chains to policy ACCEPT: filter [ OK ]
    iptables: Unloading modules: [ OK ]
    iptables: Applying firewall rules: [ OK ]
    iptables: Loading additional modules: ”nf_conntrack_ftp” [FAILED]

    Any ideas?

    • leerb

      What linux/kernel version?

      Your’s if referencing nf_conntrack_ftp instead of ip_conntrack_ftp but I don’t know what the difference is.

    • Alex

      make sure you have these line:


      (not nf_conntrack_ftp)

      • Sure some versions require ip_conntrack_ftp instead of nf_conntrack_ftp.

  • Pingback: Passive Mode FTP with iptables « Silicon Technix()

  • Pingback: Allow FTP through IPTables()

  • Pingback: Passive Mode FTP with iptables « Linux T&T()

  • Michael2

    Work with IPv6 too. I have added “ip_conntrack_ftp” to /etc/modules. Thanks!.