The example rule in the iptables-extensions(8) manpage suggests: iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state UNTRACKED,INVALID -j SYNPROXY --sack-perm --timestamp --mss 1460 --wscale 9 This is allowing invalid PSH,ACK packets to enter the SYNPROXY target since they are matching the INVALID state. This results in the following sequence: client synproxy server | | | | | | ... 3-way handshake via synproxy ... | | | |-------------------->| | | psh,ack |------------------>| | | syn | uh, why syn? I'm | | | already established?! | |<------------------| |<--------------------| rst | | rst | | Problem is that the psh,ack packet is handled by SYNPROXY as it would be the ACK packet (the third step in the handshake), hence SYNPROXY sends it as as SYN packet to the server. The server is not happy, since the handshake already happened time ago, so it sends the RST packet and connection is teared down immediately. Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- net/ipv4/netfilter/ipt_SYNPROXY.c | 2 +- net/ipv6/netfilter/ip6t_SYNPROXY.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index 690b17ef6a44..dfc84d954c34 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c @@ -296,7 +296,7 @@ synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) synproxy_send_client_synack(net, skb, th, &opts); consume_skb(skb); return NF_STOLEN; - } else if (th->ack && !(th->fin || th->rst || th->syn)) { + } else if (th->ack && !(th->fin || th->rst || th->syn || th->psh)) { /* ACK from client */ if (synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq))) { consume_skb(skb); diff --git a/net/ipv6/netfilter/ip6t_SYNPROXY.c b/net/ipv6/netfilter/ip6t_SYNPROXY.c index cb6d42b03cb5..1f4f1e24fd27 100644 --- a/net/ipv6/netfilter/ip6t_SYNPROXY.c +++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c @@ -311,7 +311,7 @@ synproxy_tg6(struct sk_buff *skb, const struct xt_action_param *par) consume_skb(skb); return NF_STOLEN; - } else if (th->ack && !(th->fin || th->rst || th->syn)) { + } else if (th->ack && !(th->fin || th->rst || th->syn || th->psh)) { /* ACK from client */ if (synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq))) { consume_skb(skb); -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html