From 775ada6d9f4c9dc440f5aeca00354eb87f6e0696 Mon Sep 17 00:00:00 2001 From: Jesper Dangaard Brouer Date: Wed, 28 Aug 2013 15:14:38 +0200 Subject: [PATCH 1/4] netfilter: more strict TCP flag matching in SYNPROXY Its seems Patrick missed to incoorporate some of my requested changes during review v2 of SYNPROXY netfilter module. Which were, to avoid SYN+ACK packets to enter the path, meant for the ACK packet from the client (from the 3WHS). Further there were a bug in ip6t_SYNPROXY.c, for matching SYN packets that didn't exclude the ACK flag. Go a step further with SYN packet/flag matching by excluding flags ACK+FIN+RST, in both IPv4 and IPv6 modules. The intented usage of SYNPROXY is as follows: (gracefully describing usage in commit) iptables -t raw -A PREROUTING -i eth0 -p tcp --dport 80 --syn -j NOTRACK iptables -A INPUT -i eth0 -p tcp --dport 80 -m state UNTRACKED,INVALID \ -j SYNPROXY --sack-perm --timestamp --mss 1480 --wscale 7 --ecn echo 0 > /proc/sys/net/netfilter/nf_conntrack_tcp_loose This does filter SYN flags early, for packets in the UNTRACKED state, but packets in the INVALID state with other TCP flags could still reach the module, thus this stricter flag matching is still needed. Signed-off-by: Jesper Dangaard Brouer Acked-by: Patrick McHardy Signed-off-by: Pablo Neira Ayuso --- net/ipv4/netfilter/ipt_SYNPROXY.c | 4 ++-- net/ipv6/netfilter/ip6t_SYNPROXY.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index 94371db6aecc..90e489eb1c0a 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c @@ -269,7 +269,7 @@ synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) synproxy_parse_options(skb, par->thoff, th, &opts); - if (th->syn && !th->ack) { + if (th->syn && !(th->ack || th->fin || th->rst)) { /* Initial SYN from client */ this_cpu_inc(snet->stats->syn_received); @@ -285,7 +285,7 @@ synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) XT_SYNPROXY_OPT_ECN); synproxy_send_client_synack(skb, th, &opts); - } else if (th->ack && !(th->fin || th->rst)) + } else if (th->ack && !(th->fin || th->rst || th->syn)) /* ACK from client */ synproxy_recv_client_ack(snet, skb, th, &opts, ntohl(th->seq)); diff --git a/net/ipv6/netfilter/ip6t_SYNPROXY.c b/net/ipv6/netfilter/ip6t_SYNPROXY.c index 4270a9b145e5..a5af0bfef126 100644 --- a/net/ipv6/netfilter/ip6t_SYNPROXY.c +++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c @@ -284,7 +284,7 @@ synproxy_tg6(struct sk_buff *skb, const struct xt_action_param *par) synproxy_parse_options(skb, par->thoff, th, &opts); - if (th->syn) { + if (th->syn && !(th->ack || th->fin || th->rst)) { /* Initial SYN from client */ this_cpu_inc(snet->stats->syn_received); @@ -300,7 +300,7 @@ synproxy_tg6(struct sk_buff *skb, const struct xt_action_param *par) XT_SYNPROXY_OPT_ECN); synproxy_send_client_synack(skb, th, &opts); - } else if (th->ack && !(th->fin || th->rst)) + } else if (th->ack && !(th->fin || th->rst || th->syn)) /* ACK from client */ synproxy_recv_client_ack(snet, skb, th, &opts, ntohl(th->seq)); From f4de4c89d89df5ead42de9fea895f5b8155270da Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 29 Aug 2013 10:32:09 +0200 Subject: [PATCH 2/4] netfilter: synproxy_core: fix warning in __nf_ct_ext_add_length() With CONFIG_NETFILTER_DEBUG we get the following warning during SYNPROXY init: [ 80.558906] WARNING: CPU: 1 PID: 4833 at net/netfilter/nf_conntrack_extend.c:80 __nf_ct_ext_add_length+0x217/0x220 [nf_conntrack]() The reason is that the conntrack template is set to confirmed before adding the extension and it is invalid to add extensions to already confirmed conntracks. Fix by adding the extensions before setting the conntrack to confirmed. Reported-by: Jesper Dangaard Brouer Signed-off-by: Patrick McHardy Acked-by: Jesper Dangaard Brouer Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_synproxy_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c index d23dc791aca7..6fd967c6278c 100644 --- a/net/netfilter/nf_synproxy_core.c +++ b/net/netfilter/nf_synproxy_core.c @@ -356,12 +356,12 @@ static int __net_init synproxy_net_init(struct net *net) goto err1; } - __set_bit(IPS_TEMPLATE_BIT, &ct->status); - __set_bit(IPS_CONFIRMED_BIT, &ct->status); if (!nfct_seqadj_ext_add(ct)) goto err2; if (!nfct_synproxy_ext_add(ct)) goto err2; + __set_bit(IPS_TEMPLATE_BIT, &ct->status); + __set_bit(IPS_CONFIRMED_BIT, &ct->status); snet->tmpl = ct; From 7cc9eb6ef78d0dcb97d543ea19966486e98afa0b Mon Sep 17 00:00:00 2001 From: Jesper Dangaard Brouer Date: Thu, 29 Aug 2013 12:18:46 +0200 Subject: [PATCH 3/4] netfilter: SYNPROXY: let unrelated packets continue Packets reaching SYNPROXY were default dropped, as they were most likely invalid (given the recommended state matching). This patch, changes SYNPROXY target to let packets, not consumed, continue being processed by the stack. This will be more in line other target modules. As it will allow more flexible configurations of handling, logging or matching on packets in INVALID states. Signed-off-by: Jesper Dangaard Brouer Acked-by: Patrick McHardy Signed-off-by: Pablo Neira Ayuso --- net/ipv4/netfilter/ipt_SYNPROXY.c | 8 ++++++-- net/ipv6/netfilter/ip6t_SYNPROXY.c | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index 90e489eb1c0a..67e17dcda65e 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c @@ -285,11 +285,15 @@ synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) XT_SYNPROXY_OPT_ECN); synproxy_send_client_synack(skb, th, &opts); - } else if (th->ack && !(th->fin || th->rst || th->syn)) + return NF_DROP; + + } else if (th->ack && !(th->fin || th->rst || th->syn)) { /* ACK from client */ synproxy_recv_client_ack(snet, skb, th, &opts, ntohl(th->seq)); + return NF_DROP; + } - return NF_DROP; + return XT_CONTINUE; } static unsigned int ipv4_synproxy_hook(unsigned int hooknum, diff --git a/net/ipv6/netfilter/ip6t_SYNPROXY.c b/net/ipv6/netfilter/ip6t_SYNPROXY.c index a5af0bfef126..19cfea8dbcaa 100644 --- a/net/ipv6/netfilter/ip6t_SYNPROXY.c +++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c @@ -300,11 +300,15 @@ synproxy_tg6(struct sk_buff *skb, const struct xt_action_param *par) XT_SYNPROXY_OPT_ECN); synproxy_send_client_synack(skb, th, &opts); - } else if (th->ack && !(th->fin || th->rst || th->syn)) + return NF_DROP; + + } else if (th->ack && !(th->fin || th->rst || th->syn)) { /* ACK from client */ synproxy_recv_client_ack(snet, skb, th, &opts, ntohl(th->seq)); + return NF_DROP; + } - return NF_DROP; + return XT_CONTINUE; } static unsigned int ipv6_synproxy_hook(unsigned int hooknum, From 1205e1fa615805c9efa97303b552cf445965752a Mon Sep 17 00:00:00 2001 From: Phil Oester Date: Sun, 1 Sep 2013 08:32:21 -0700 Subject: [PATCH 4/4] netfilter: xt_TCPMSS: correct return value in tcpmss_mangle_packet In commit b396966c4 (netfilter: xt_TCPMSS: Fix missing fragmentation handling), I attempted to add safe fragment handling to xt_TCPMSS. However, Andy Padavan of Project N56U correctly points out that returning XT_CONTINUE in this function does not work. The callers (tcpmss_tg[46]) expect to receive a value of 0 in order to return XT_CONTINUE. Signed-off-by: Phil Oester Signed-off-by: Pablo Neira Ayuso --- net/netfilter/xt_TCPMSS.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index 6113cc7efffc..cd24290f3b2f 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c @@ -60,7 +60,7 @@ tcpmss_mangle_packet(struct sk_buff *skb, /* This is a fragment, no TCP header is available */ if (par->fragoff != 0) - return XT_CONTINUE; + return 0; if (!skb_make_writable(skb, skb->len)) return -1;