· 7 min read

SYN Flood Asymmetric Routing: SYN Proxy in DDoS Tunnels

A SYN flood is hard to stop with a classic SYN proxy when routing is asymmetric, because the proxy has to see both directions of the TCP handshake and your return traffic usually bypasses it. In a GRE tunnel setup, clean traffic comes back through the tunnel but replies leave through your normal transit. The practical answer is to use stateless or inbound-only validation at the scrubbing edge, and to run SYN proxy or SYN cookies on the hosts or firewall that see both directions.

This article explains why the problem exists, how SYN and SYN-ACK floods differ, and what you can configure today.

SYN flood vs. SYN-ACK flood

The two attacks look similar in graphs but need different handling.

SYN flood SYN-ACK flood
Packets arriving at victim TCP SYN (flags 0x02) TCP SYN-ACK (flags 0x12)
Source IPs Spoofed or botnet Real third-party servers (reflection)
Source port Random Usually a service port like 80, 443, 22
Target Listening port, backlog and conntrack Firewall state, CPU, link capacity
Why it works Exhausts half-open connection state Attacker spoofs your IP in SYNs sent to many servers, so they answer you

In a SYN-ACK flood your servers never sent a SYN, so there is no matching connection. Dropping these packets is easy in principle, but only if some device can tell that no SYN went out. That is where asymmetric routing hurts.

Why asymmetric routing breaks SYN proxy

A SYN proxy answers the client's SYN itself with a cookie-based SYN-ACK. If the client returns a valid ACK, the proxy opens a real connection to the backend. After that it must translate sequence numbers for the rest of the connection, because the client agreed on the proxy's initial sequence number and the backend picked its own.

This requires the proxy to sit in the path of both directions. With a tunnel-based design:

  1. Your prefixes are announced from the scrubbing edge, so inbound traffic hits the scrubber first.
  2. Clean traffic is delivered to your router over GRE.
  3. Your servers reply through your own transit or IX, not back through the tunnel.

The scrubber therefore sees SYN, ACK and data from the client but never the server's SYN-ACK or data. Three things go wrong:

Some scrubbing designs work around this by forcing return traffic through the tunnel, which makes the path symmetric. That is a design choice, so confirm with your provider whether it is supported.

Mitigation options that work with asymmetry

1. Stateless validation at the edge

Instead of full proxying, the edge validates the client and then steps aside:

Both need only inbound state, so they survive asymmetric return paths. The cost is added latency on the first connection from each new source, and some odd clients may fail the check. Test with your actual traffic mix.

2. Run SYN cookies or SYNPROXY where state is symmetric

Your own server or Linux firewall box sees both directions by definition. Enable SYN cookies and, if needed, the netfilter SYNPROXY target:

# Kernel basics
sysctl -w net.ipv4.tcp_syncookies=1
sysctl -w net.ipv4.tcp_synack_retries=2
sysctl -w net.ipv4.tcp_max_syn_backlog=8192
sysctl -w net.netfilter.nf_conntrack_tcp_loose=0
sysctl -w net.ipv4.tcp_timestamps=1

# SYNPROXY for a protected web port (192.0.2.10:443)
iptables -t raw -A PREROUTING -p tcp -d 192.0.2.10 --dport 443 --syn -j CT --notrack
iptables -A INPUT -p tcp -d 192.0.2.10 --dport 443 \
  -m conntrack --ctstate INVALID,UNTRACKED \
  -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1436
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

Note the --mss 1436: it is set for a GRE tunnel path (see below). SYNPROXY protects the host from half-open state, but it still burns CPU, so it does not replace upstream filtering for volumetric attacks.

3. Fix MSS and MTU on the tunnel

With IPv4 GRE the outer header adds 24 bytes. On a 1500-byte underlay, the tunnel MTU is 1476 and the TCP MSS should be at most 1436. Clamp it on the tunnel interface:

! Cisco IOS / IOS-XE
interface Tunnel0
 ip mtu 1476
 ip tcp adjust-mss 1436
# Juniper
set interfaces gr-0/0/0 unit 0 family inet mtu 1476
set interfaces gr-0/0/0 unit 0 family inet tcp-mss 1436
# MikroTik
/ip firewall mangle add chain=forward protocol=tcp tcp-flags=syn \
  out-interface=gre-tunnel1 action=change-mss new-mss=1436 passthrough=yes

Without this, SYN handling can look fine while real users still stall on large responses.

4. Rate-limit SYN-ACKs to servers that rarely make outbound connections

For a block of pure inbound servers, legitimate SYN-ACKs are rare. They only arrive when those servers connect outward, for example to APIs or DNS over TCP. A policer is safer than a hard drop.

Juniper edge filter:

set firewall policer SYNACK-LIMIT if-exceeding bandwidth-limit 10m burst-size-limit 150k
set firewall policer SYNACK-LIMIT then discard

set firewall family inet filter PROTECT-SERVERS term SYNACK from destination-address 192.0.2.0/24
set firewall family inet filter PROTECT-SERVERS term SYNACK from protocol tcp
set firewall family inet filter PROTECT-SERVERS term SYNACK from tcp-flags "syn&ack"
set firewall family inet filter PROTECT-SERVERS term SYNACK then policer SYNACK-LIMIT
set firewall family inet filter PROTECT-SERVERS term SYNACK then accept
set firewall family inet filter PROTECT-SERVERS term REST then accept

MikroTik (raw table, before conntrack):

/ip firewall raw
add chain=prerouting protocol=tcp tcp-flags=syn,ack,!fin,!rst \
    dst-address=192.0.2.0/24 limit=2000,100:packet action=accept
add chain=prerouting protocol=tcp tcp-flags=syn,ack,!fin,!rst \
    dst-address=192.0.2.0/24 action=drop

Adjust the numbers to your normal baseline. The same match can be sent upstream as a BGP FlowSpec rule (protocol TCP, TCP flags SYN+ACK, destination prefix, rate-limit action), which keeps the junk off your transit links. See our FlowSpec guide for safety practices.

5. Make the return path symmetric where you can

If your tunnel provider supports return traffic over the tunnel, use source-based routing for the protected prefix. On Linux:

ip rule add from 192.0.2.0/24 table 100
ip route add default dev gre1 table 100

On routers the equivalent is policy-based routing or a VRF/routing instance for the protected space. The tradeoff: all outbound traffic from that prefix now crosses the tunnel, which may add latency and consume tunnel capacity. Many networks do this only for specific customers or only during attacks.

Detecting SYN and SYN-ACK floods from flow data

Flow telemetry (NetFlow v5/v9, IPFIX, sFlow) gives you a fast first signal:

Remember that NetFlow TCP flags are cumulative (OR-ed) per flow. Single-packet flows from floods are accurate, but long-lived flows mix flags. With packet sampling, small floods may be under-counted, so tune pps thresholds per IP and per prefix, not just per link. Our posts on NetFlow detection thresholds and carpet bombing cover baselines and prefix-wide attacks.

Common mistakes

Where NixMon fits

NixMon detects floods from NetFlow, IPFIX and sFlow with per-IP and per-prefix bps/pps thresholds, then can trigger BGP FlowSpec, RTBH, or on-prem NixGuard actions. For networks with their own ASN and at least one /24, NixGuard Edge announces your prefixes from the scrubbing edge and delivers clean traffic over a GRE tunnel with a BGP session inside, in always-on or on-demand mode. If you are unsure how asymmetric your return path is, test it before you rely on any proxy-style mitigation. You can try the platform with the 15-day free trial, no credit card required.

Frequently asked questions

Why does SYN proxy not work well with a DDoS tunnel?

A SYN proxy must see both directions of the connection to translate sequence numbers after the handshake. In a typical GRE tunnel setup, inbound traffic passes through the scrubber but server replies leave via your own transit, so the proxy only sees half of the flow and cannot maintain the session.

How is a SYN-ACK flood different from a SYN flood?

A SYN flood sends SYN packets to exhaust connection state on a listening service. A SYN-ACK flood is usually reflection: the attacker spoofs your IP in SYNs sent to third-party servers, which then send SYN-ACKs to you. The source IPs are real servers, often with service source ports like 80 or 443.

Can I filter SYN-ACK floods with BGP FlowSpec?

Yes, if your routers support it. A rule can match TCP protocol, SYN+ACK flags and your destination prefix, with a rate-limit or discard action. Prefer rate-limiting if the prefix includes hosts that make outbound connections, since they legitimately receive SYN-ACKs.

What MSS should I use on a GRE tunnel?

For IPv4 GRE over a 1500-byte underlay, the tunnel MTU is 1476 and the TCP MSS should be 1436 or lower. Clamp MSS on the tunnel interface so large packets are not dropped or fragmented.

Test flood detection on your own flows with the 15-day free trial.Learn more