SYNCACHE(4)

πŸ“¦ version 15.1, in freebsd 14.5, freebsd 15.1

okay so bestie, welcome to SYNCACHE(4) β€” it lives in the Kernel Interfaces Manual, section 4, and it's literally the glow-up guide for TCP SYN caching. It's an sysctl(8) MIB situation. Let's get into it πŸ’…


πŸ¦‹ NAME πŸ¦‹

syncache, syncookies β€” sysctl(8) MIBs for controlling TCP SYN caching. Yes, both names, they're a package deal ✨


🌸 SYNOPSIS 🌸

sysctl net.inet.tcp.syncookies
sysctl net.inet.tcp.syncookies_only

sysctl net.inet.tcp.syncache.hashsize
sysctl net.inet.tcp.syncache.bucketlimit
sysctl net.inet.tcp.syncache.cachelimit
sysctl net.inet.tcp.syncache.rexmtlimit
sysctl net.inet.tcp.syncache.count
sysctl net.inet.tcp.syncache.see_other
sysctl net.inet.tcp.syncache.rst_on_sock_fail

πŸ’– DESCRIPTION πŸ’–

okay so the syncache sysctl(8) MIB is the thing that controls TCP SYN caching on your system, and its whole main character job is handling SYN flood Denial of Service attacks. no cap πŸ›‘οΈ

Here's the tea: when a TCP SYN segment shows up on a port that corresponds to a listen socket, an entry gets made in the syncache, and a SYN,ACK segment is sent back to the peer. That syncache entry holds onto the TCP options from the initial SYN, keeps enough state to do a SYN,ACK retransmission, and β€” key detail β€” takes up less space than a TCP control block endpoint. Then, when an incoming segment arrives carrying an ACK for the SYN,ACK and it matches a syncache entry, the system creates a TCP control block with the options stored in that syncache entry, and the entry gets released. byeee ✨

So how does the syncache protect you from SYN flood DoS attacks? By minimizing the amount of state kept on the server, and by limiting the overall size of the syncache. lowkey genius.

Syncookies is the other icon here β€” it provides a way to virtually expand the size of the syncache by keeping state regarding the initial SYN in the network 🌈. Enabling syncookies sends a cryptographic value in the SYN,ACK reply to the client machine, which then gets returned in the client's ACK. If the corresponding entry isn't found in the syncache, but the value passes specific security checks, the connection gets accepted. This is only used if the syncache is unable to handle the volume of incoming connections, and a prior entry has been evicted from the cache.

⚠️ bestie, syncookies has a certain number of disadvantages that a paranoid administrator may wish to take note of. Since the TCP options from the initial SYN are not saved, they are not applied to the connection β€” which precludes use of features like window scale, timestamps, or exact MSS sizing 😭. And because the returning ACK establishes the connection, it may be possible for an attacker to ACK flood a machine in an attempt to create a connection. Steps have been taken to mitigate this risk, but this may provide a way to bypass firewalls which filter incoming segments with the SYN bit set. fr fr, be aware.

The toggles, aka the vibes check:

  • To disable the syncache and run only with syncookies, set net.inet.tcp.syncookies_only to 1.
  • To use syncookies to handle bucket overflows in the syncache, set net.inet.tcp.syncookies to 1.
  • The default value for net.inet.tcp.syncookies_only is 0, and the default value for net.inet.tcp.syncookies is 1. slay πŸ’…

πŸŽ€ the net.inet.tcp.syncache branch πŸŽ€

The syncache implements a number of variables in the net.inet.tcp.syncache branch of the sysctl(3) MIB. Several of these may be tuned by setting the corresponding variable in the loader(8). iconic.

  • hashsize β€” Size of the syncache hash table, must be a power of 2. Read-only, tunable via loader(8).
  • bucketlimit β€” Limit on the number of entries permitted in each bucket of the hash table. This should be left at a low value to minimize search time. Read-only, tunable via loader(8).
  • cachelimit β€” Limit on the total number of entries in the syncache. Defaults to (hashsize Γ— bucketlimit), may be set lower to minimize memory consumption. Read-only, tunable via loader(8).
  • rexmtlimit β€” Maximum number of times a SYN,ACK is retransmitted before being discarded. The default of 3 retransmits corresponds to a 45 second timeout; this value may be increased depending on the RTT to client machines. Tunable via sysctl(3).
  • count β€” Number of entries present in the syncache (read-only).
  • see_other β€” If set to true value, all syncache entries will be visible via net.inet.tcp.pcblist sysctl, or via netstat(1), ignoring all of security(7) UID/GID, jail(2) and mac(4) checks. If turned off, the visibility checks are enforced. However, extra ucred(9) referencing is required on every incoming SYN packet processed. The default is off.
  • rst_on_sock_fail β€” Send a TCP RST segment if the socket allocation fails. The default is on.

🫢 the stats, courtesy of netstat(1) 🌟

Statistics on the performance of the syncache may be obtained via netstat(1), which provides the following counts:

  • syncache entries added β€” Entries successfully inserted in the syncache.
  • retransmitted β€” SYN,ACK retransmissions due to a timeout expiring.
  • dupsyn β€” Incoming SYN segment matching an existing entry.
  • dropped β€” SYNs dropped because SYN,ACK could not be sent.
  • completed β€” Successfully completed connections.
  • bucket overflow β€” Entries dropped for exceeding per-bucket size.
  • cache overflow β€” Entries dropped for exceeding overall cache size.
  • reset β€” RST segment received.
  • stale β€” Entries dropped due to maximum retransmissions or listen socket disappearance.
  • aborted β€” New socket allocation failures.
  • badack β€” Entries dropped due to bad ACK reply.
  • unreach β€” Entries dropped due to ICMP unreachable messages.
  • zone failures β€” Failures to allocate new syncache entry.
  • cookies sent β€” SYN cookies sent in SYN ACK segments.
  • cookies received β€” ACK segments with valid syncookies which resulted in TCP connection establishment.
  • spurious cookies rejected β€” Received ACKs, for which the syncache lookup failed and also no syncookie was recently sent.
  • failed cookies rejected β€” Received ACKs for which the syncookie validation failed.

πŸ”₯ SEE ALSO πŸ”₯

netstat(1), jail(2), mac(4), tcp(4), security(7), loader(8), sysctl(8), ucred(9) β€” go read them, they're all connected, iykyk πŸ’œ


🌈 HISTORY 🌈

The existing syncache implementation first appeared in FreeBSD 4.5. The original concept of a syncache originally appeared in BSD/OS, and was later modified by NetBSD, then further extended here. a whole lineage, honestly πŸ‘‘


πŸ‘‘ AUTHORS πŸ‘‘

The syncache code and manual page were written by Jonathan Lemon <jlemon@FreeBSD.org>. thank you for your service 🫢


✨ and that's the whole page, bestie ✨ this cutie is from Debian, dated August 30, 2025 β€” SYNCACHE(4), Kernel Interfaces Manual. go forth and tune your syncache responsibly πŸ’–πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from