This target will process TCP three-way-handshake parallel in netfilter context to protect either local or backend system. This target requires connection tracking because sequence numbers need to be translated. The kernels ability to absorb SYNFLOOD was greatly improved starting with Linux 4.4, so this target should not be needed anymore to protect Linux servers.

--mss maximum segment size
    Maximum segment size announced to clients. This must match the backend.

--wscale window scale
    Window scale announced to clients. This must match the backend.

--sack-perm
    Pass client selective acknowledgement option to backend (will be disabled if not present).

--timestamps
    Pass client timestamp option to backend (will be disabled if not present, also needed for selective acknowledgement and window scaling).

Example:

Determine tcp options used by backend, from an external system

    tcpdump -pni eth0 -c 1 'tcp[tcpflags] == (tcp-syn|tcp-ack)'
        port 80 &
    telnet 192.0.2.42 80
    18:57:24.693307 IP 192.0.2.42.80 > 192.0.2.43.48757:
        Flags [S.], seq 360414582, ack 788841994, win 14480,
        options [mss 1460,sackOK,
        TS val 1409056151 ecr 9690221,
        nop,wscale 9],
        length 0

Switch tcp_loose mode off, so conntrack will mark out-of-flow packets as state INVALID.

    echo 0 > /proc/sys/net/netfilter/nf_conntrack_tcp_loose

Make SYN packets untracked

    iptables -t raw -A PREROUTING -i eth0 -p tcp --dport 80
        --syn -j CT --notrack

Catch UNTRACKED (SYN packets) and INVALID (3WHS ACK packets) states and send them to SYNPROXY. This rule will respond to SYN packets with SYN+ACK syncookies, create ESTABLISHED for valid client response (3WHS ACK packets) and drop incorrect cookies. Flags combinations not expected during 3WHS will not match and continue (e.g. SYN+FIN, SYN+ACK).

    iptables -A INPUT -i eth0 -p tcp --dport 80
        -m state --state UNTRACKED,INVALID -j SYNPROXY
        --sack-perm --timestamp --mss 1460 --wscale 9

Drop invalid packets, this will be out-of-flow packets that were not matched by SYNPROXY.

    iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state INVALID -j DROP