What kernel modules are required for FTP related connection to work with iptables?

2

I am setting up restrictive firewall on my PC, which is running Gentoo with kernel 4.8.17. I want to enable FTP PASSV mode for outgoing connections using this rule:

iptables -A OUTPUT -p tcp -m tcp --sport 1024: --dport 1024: -m conntrack --ctstate RELATED -j ACCEPT

PASSV FTP works fine with NEW added to the above rule, which is too permissive for my needs. Also my config works fine on another box(with older kernel). I compared kernel options from both configs, but I can't figure out what's missing. So what modules are necessary for RELATED connections to work with iptables?

My kernel is configured with following options:

host ~ # zcat /proc/config.gz | grep 'NETFILTER\|_XT_\|_NF_' | grep -v "^#"
CONFIG_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y
CONFIG_NETFILTER_INGRESS=y
CONFIG_NETFILTER_NETLINK=y
CONFIG_NF_CONNTRACK=y
CONFIG_NF_LOG_COMMON=m
CONFIG_NF_CONNTRACK_PROCFS=y
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CONNTRACK_FTP=m
CONFIG_NF_CT_NETLINK=y
CONFIG_NETFILTER_XTABLES=y
CONFIG_NETFILTER_XT_TARGET_LOG=m
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
CONFIG_NETFILTER_XT_MATCH_HELPER=m
CONFIG_NETFILTER_XT_MATCH_SOCKET=m
CONFIG_NETFILTER_XT_MATCH_STATE=m
CONFIG_NF_DEFRAG_IPV4=y
CONFIG_NF_CONNTRACK_IPV4=y
CONFIG_NF_CONNTRACK_PROC_COMPAT=y
CONFIG_NF_LOG_IPV4=m
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_FILTER=y
CONFIG_NF_LOG_IPV6=m

I have following modules loaded:

host ~ # lsmod 
Module                  Size  Used by
xt_state                1543  0
xt_helper               1619  0
nf_conntrack_ftp        7270  0

My iptables looks like this:

host ~ # iptables -nvL --line-numbers
Chain INPUT (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
2        0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
3        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 ctstate NEW

Chain FORWARD (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     all  --  *      lo      0.0.0.0/0            0.0.0.0/0           
2        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp spts:1024:65535 dpts:1:1024 ctstate NEW
3        0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
4        0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spts:1024:65535 dpt:53 ctstate NEW
5        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp spts:1024:65535 dpts:1024:65535 ctstate RELATED
6        0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 255

bezet

Posted 2017-09-17T19:32:54.267

Reputation: 123

Answers

3

Since kernel 4.7 (so applies to kernel 4.8.17):

https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl.txt

nf_conntrack_helper - BOOLEAN  
    0 - disabled (default)
    not 0 - enabled

    Enable automatic conntrack helper assignment.
    If disabled it is required to set up iptables rules to assign
    helpers to connections.  See the CT target description in the
    iptables-extensions(8) man page for further information.`

So doing:

echo 1 > /proc/sys/net/netfilter/nf_conntrack_helper

should revert to the pre-kernel 4.7 default and make it work.

Now the new (and more secure) method is described in this blog: https://home.regit.org/netfilter-en/secure-use-of-helpers/

A.B

Posted 2017-09-17T19:32:54.267

Reputation: 2 008

Thanks! The echo 1 works, even without reloading. The 'new' one requires additional kernel module, so I will test it later. – bezet – 2017-10-17T11:30:36.720

Indeed reading the blog I linked to tells toggling the parameter after module is loaded is good enough (it just won't affect already present flows). I'll remove the reload line in the answer. – A.B – 2017-10-17T11:58:51.590

0

I already used the ip_conntrack_ftp kernel module, but your nf_conntrack_ftp module seems to be the nftable version. It then may be ok.

However, to allow passive outbound connections you could try:

iptables -A INPUT  -p tcp -m tcp --sport 1024: --dport 1024: -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 
iptables -A OUTPUT -p tcp -m tcp --sport 1024: --dport 1024: -m conntrack --ctstate ESTABLISHED -j ACCEPT

you should also tell iptables that he has to first track the FTP command channel (unpriviledged ports are only for data transfert)

iptables -A INPUT  -p tcp -m tcp --sport 21 -m conntrack --ctstate ESTABLISHED -j ACCEPT 
iptables -A OUTPUT -p tcp -m tcp --dport 21 -m conntrack --ctstate ESTABLISHED,NEW -j ACCEPT

Credit: here, related to inboud passive connection (ie. iptables rules are added on a server)

vera

Posted 2017-09-17T19:32:54.267

Reputation: 760

Sorry, but that's not useful. First of all: ip_conntrack_ftp and nf_conntrack_ftp is the same module. Secondly your 1st and 2nd rule are already in my iptables(#2 in INPUT, #3 in OUTPUT), as I already allow all established traffic. Regarding your 3rd rule, it is for server configuration, so it does not apply. The 4th rule is also already covered by my iptables(#2 in OUTPUT). – bezet – 2017-09-18T11:18:19.550

I gueesed that the module was not causing issue, but as I wasn't sure I mentioned it. Considering rules, you're also right , I correct my #3 rule (dport -> sport), but you should also add the ̀ESTABLISHED` to your #2 in OUTPUT (also edited my #4 rule) – vera – 2017-09-18T12:45:16.447

It's already there(although I admit that it's hard to read those overly long lines). My OUTPUT #2 rule allows NEW(from unprivileged to privileged ports) and OUTPUT #3 allows all "existing" traffic(RELATED, ESTABISHED). Looking at those rules I've just realized that my OUTPUT #3 is broader then #5(specialized FTP traffic), which makes #5 useless. It doesn't solve my issue though. – bezet – 2017-09-20T12:21:45.387