Iptables – FTP NAT stopped working after kernel upgrade

fedoraiptableskernelnat;upgrade

I'm having some issues with DNAT/SNAT after an upgrade to a newer kernel version. I'm using Fedora 24 as a network firewall and I have a FTP server inside my LAN. The firewall has public and private IP addresses. On the Fedora server, with the kernel 4.6.5-300.fc24.x86_64 the following iptables ruleset works as expected:

    #!/bin/bash

    modprobe iptable_nat
    modprobe nf_conntrack
    modprobe nf_conntrack_ftp
    modprobe nf_nat_ftp

    iptables -P INPUT DROP
    iptables -P FORWARD DROP
    iptables -P OUTPUT ACCEPT

    iptables -F
    iptables -F -t nat
    iptables -X
    iptables -Z

    echo 1 > /proc/sys/net/ipv4/ip_forward
    echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
    echo 1 > /proc/sys/net/netfilter/nf_conntrack_helper

    iptables -A INPUT -i lo -j ACCEPT
    iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

    iptables -t nat -A PREROUTING -d $public_ip -p tcp --dport 21 -j DNAT --to-destination 192.168.0.10:2121

...

    iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
    iptables -A FORWARD -d 192.168.0.10 -p tcp --dport 2121 -j ACCEPT

    iptables -t nat -A POSTROUTING -s 192.168.0.10 -p tcp --sport 2121 -j SNAT --to-source $public_ip

    iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -d 192.168.0.10 -p tcp --dport 2121 -j SNAT --to-source 192.168.0.1

...

The issue only happens when I boot the system with the kernel version 4.10.10-100.fc24.x86_64 (I don't know if other versions between these are affected also).

The problem: users outside my LAN can access and use the FTP service normally with the rules above. The problem affects only users from the LAN who start the FTP connection using a DNS name, which resolves to the public address, so the connection goes back to the LAN and reaches the FTP server. The last line is there so the FTP server doesn't deliver the connection directly to the client.

This only seems to affect FTP connections and additional ports specified in /etc/modprobe.d while loading the nf_conntrack_ftp module (an added rule with port 80, for example, works as excpected). I don't think rp_filter has anything to do with it, because I've disabled it and nothing changed. Also, with iptables LOG I can see the packets travel all the way to the POSTROUTING chain. And while running Wireshark on the FTP server, I checked and confirmed that not one single packet reaches it.

So, my question is: am I doing anything wrong? Is there some new way to do what I need in this kernel version? Or could this be a bug?

Thanks for the help!

Best Answer

Recent kernels no longer automatically attach connection tracking helpers based on compiled in port numbers. Instead you have to add specific rules to the raw table to attach those helpers. So for your example I think you need to add something like this:

iptables -t raw -A PREROUTING -d $public_ip -p tcp --dport 21 -j CT --helper ftp

That should also take care of making sure the helper modules are loaded without the explicit modprobe commands.

Related Topic