Frontend Labs
⋯

Part XVII — Security

This part is defensive: recognize attacks in traffic and counter them. TCP/IP was designed with security as priority #7 (Ch. 1), so most of these are structural, not bugs.

52. Spoofing, SYN floods, RST injection, and off-path attacks

52.1 IP source spoofing — the root enabler

Nothing in IP proves the source address. A host can put any source IP in a packet it sends. This works for the attacker whenever they don't need to see the reply (one-way / blind attacks) or they're on-path (can see replies).

Defense — BCP 38 / BCP 84 (ingress/egress filtering): every network drops outbound packets whose source isn't from its own prefixes, and drops inbound packets claiming to be from its own prefixes. uRPF (unicast Reverse Path Forwarding) automates it: drop a packet if the route back to its source doesn't point out the interface it arrived on (strict) or isn't in the table at all (loose). Widely deployed but not universal — which is why spoofed-source DDoS still exists.

52.2 SYN flood

Send many SYNs (usually spoofed source) and never complete the handshake. Each fills a slot in the server's SYN queue (half-open connections), and the server wastes a SYN-ACK + retransmits. Legit clients can't get a slot → denial of service, at very low attacker bandwidth.

Defenses:

  • SYN cookies (net.ipv4.tcp_syncookies=1, Ch. 24.5) — server keeps no state for half-open connections; reconstructs from the final ACK. The primary defense; engages only under overflow.
  • Larger tcp_max_syn_backlog, shorter tcp_synack_retries.
  • SYN proxy at a firewall/LB/XDP (synproxy in netfilter, or hardware) — completes the handshake on the server's behalf and only hands over real connections.
  • Upstream scrubbing for volumetric versions.
  • Rate-limit SYNs per source (weak vs spoofing) / per subnet.

52.3 RST injection & connection reset attacks

If an attacker can guess or observe the 4-tuple and a valid sequence number window, they can forge a RST (or data) segment and the endpoint will act on it:

  • On-path (same LAN, compromised router, nation-state middlebox): trivial — they see everything. The Great Firewall forges RSTs to both ends to kill connections; some ISPs used RST to throttle P2P.
  • Off-path (blind): must guess the tuple (server IP/port known; client IP maybe known; client port and sequence are the entropy). RFC 5961 makes this much harder: an in-window-but-not-exact RST triggers a challenge ACK instead of an immediate reset, so the attacker needs a near-exact sequence number. (Ironically, the shared rate limit on challenge ACKs became a side-channel — CVE-2016-5696 — now randomized.)

Defenses: randomized ISNs (RFC 6528), RFC 5961 checks, ephemeral source port randomization (more tuple entropy), and — the real fix — TLS/SSH: a forged RST can tear the TCP connection but can't inject or read application data, and the app just reconnects. TCP-AO (RFC 5925, replaces TCP-MD5) authenticates segments for infrastructure sessions like BGP.

52.4 Session hijacking / data injection

On-path attacker injects application data into an unauthenticated stream (classic telnet, http, unencrypted SMTP). Or predicts sequence numbers to do it blind (historic). Defense: encrypt + authenticate everything (TLS, SSH, IPsec, WireGuard). Assume the path is hostile.

52.5 TCP-based reconnaissance

  • SYN scan (nmap -sS): SYN → SYN-ACK (open) / RST (closed) / nothing (filtered). Doesn't complete the handshake ("half-open").
  • FIN/NULL/Xmas scans: rely on RFC-793 behavior (closed port → RST, open → nothing) to slip past stateless filters. Modern stacks/firewalls detect these.
  • Idle/zombie scan: uses a third host's predictable IP ID field to scan fully blind. Defense: randomized IP ID (Linux does per-destination).
  • OS fingerprinting (nmap -O, p0f): initial TTL, window size, MSS, option order/presence, DF bit → identifies the OS. Defense: normalization at a firewall (scrub in pf), or accept that it's low-risk.
  • Banner grabbing, TLS JA3/JA4 client fingerprints.

Defenses: default-deny firewall, rate-limit + alert on scan patterns (nf_conntrack + hashlimit, fail2ban, an IDS), don't expose management ports, and reduce attack surface (fewer listening sockets — audit with ss -tlnp).

52.6 Amplification / reflection (covered more in Ch. 54)

Spoof the victim's IP as source of a small UDP request to a service that returns a large response → the victim is flooded, attacker's bandwidth multiplied. Amplification factors: DNS ANY ~50×, NTP monlist ~550×, memcached ~10 000–50 000×, SSDP ~30×, CLDAP ~55×. Defense: BCP 38 (kills spoofing at source), disable/restrict the abusable services (no open resolvers, NTP noquery, memcached not on UDP/not on the internet), rate-limit responses (DNS RRL).

52.7 Other classics to recognize

Attack Mechanism Defense
ARP spoofing forged ARP → LAN MITM Dynamic ARP Inspection + DHCP snooping, static ARP for gateways, 802.1X
Rogue DHCP / rogue RA hand out attacker as gateway/DNS DHCP snooping, RA Guard
DNS cache poisoning (Kaminsky) race a forged answer into a resolver source-port + query-ID randomization (32-bit entropy), DNSSEC, DoT/DoH to a trusted resolver, 0x20 encoding
DNS rebinding public name flips to 127.0.0.1/RFC1918 after TTL → browser attacks internal services resolver/app rebinding protection (reject private answers for public names), Host allow-listing
TCP "sequence prediction" guess ISN → blind spoof a whole connection RFC 6528 randomized ISN
Slowloris / slow POST / R-U-Dead-Yet open many connections, send headers/body 1 byte at a time → exhaust worker slots request header/body timeouts, min data-rate, connection limits per IP, an async/event-driven front proxy (nginx/HAProxy) that buffers
TCP request smuggling front proxy & backend disagree on request boundaries (CL vs TE) normalize/reject ambiguous framing at the edge, HTTP/2 end-to-end
LAND / teardrop / ping-of-death malformed/overlapping packets crash old stacks patched kernels; drop obviously bogus packets

52.8 War story

A service saw thousands of connections stuck in SYN_RECV and legit users timing out. nstat showed TcpExtTCPReqQFullDoCookies climbing — a SYN flood with spoofed sources. tcp_syncookies was already on and doing its job at the kernel, but the upstream firewall's own connection table was also filling. Adding an XDP SYN filter on the edge hosts (drop SYNs exceeding a per-source rate, validate with cookies before passing) plus asking transit to enable uRPF on the customer link absorbed it. Lesson: SYN floods are cheap and old; have SYN cookies on, know your nstat cookie counters, and have an XDP/scrubbing layer ready.

Try it yourself (defensive)

ss -tlnp                                  # audit every listening socket - attack surface
nstat -az | grep -Ei 'syncookie|challengeack|embryonic|ReqQFull|PAWS|ListenDrops'
sysctl net.ipv4.tcp_syncookies net.ipv4.conf.all.rp_filter net.ipv4.tcp_rfc1337
sysctl net.ipv4.conf.all.accept_redirects net.ipv4.conf.all.send_redirects   # set 0
sysctl net.ipv4.conf.all.accept_source_route   # set 0
sudo nft add rule inet filter input tcp flags syn limit rate 200/second accept  # SYN rate-limit

Generated from real-life-example.md · 8 Oct 2026 16:36