What Is TCP/IP Fingerprinting? Why Most Proxies Look Like Linux
By Nicholas St. Germain. Published
TCP/IP fingerprinting in short
TCP/IP fingerprinting identifies a device's operating system from the first packet of a TCP connection. Windows, macOS, and Linux each fill in that packet's TTL, window size, TCP options, and source port differently, so a server can tell them apart without running any code on the visitor's machine.
Proxy servers almost all run Linux. Unless the provider changes it, every connection through a proxy reaches the website with a Linux fingerprint, even when the browser behind it says Windows. Every Stat Proxies IP sends a Windows 11 fingerprint instead, on every plan, at no extra cost. The details are on our Windows TCP fingerprint page.
What is in the first packet
Every TCP connection opens with a SYN packet. Your operating system writes it, and a few of its fields depend on which OS you run:
| Field | What it is | Why it differs by OS |
|---|---|---|
| TTL | How many routers the packet may cross before it is dropped | Windows starts at 128, Linux, macOS, and iOS at 64 |
| Window size | How much data the sender can receive before it must acknowledge | Each OS picks its own default |
| Window scale | A multiplier on the window size | Follows from the OS's buffer settings |
| Option order | The sequence of TCP options such as MSS, SACK, and timestamps | Hardcoded in each OS's network stack |
| Timestamps | Whether the TCP timestamp option is present | On for Linux, macOS, and iOS, off for Windows |
| Source port | The local port the connection comes from | Each OS draws from its own range |
None of these fields are secret, and none of them need JavaScript to read. The server receives the SYN packet as part of opening the connection. Reading the fields costs nothing.
How the three common systems compare
These are the values a website sees in the SYN packet from each system with default settings. The Windows and macOS rows come from captures we took on real machines. The Linux row is stock Ubuntu.
| Field | Windows 11 | macOS / iOS | Linux (Ubuntu) |
|---|---|---|---|
| TTL sent | 128 | 64 | 64 |
| Window size | 65535 | 65535 | 64240 |
| Window scale | 8 | 6 | 7 |
| Option order | mss, nop, wscale, nop, nop, sackOK | mss, nop, wscale, nop, nop, ts, sackOK, eol | mss, sackOK, ts, nop, wscale |
| Timestamps | Off | On | On |
| Source ports | 49152-65535 | 49152-65535 | 32768-60999 |
The option order on its own separates all three. TTL separates Windows from everything else, and timestamps do the same.
Who reads these fields
The best-known tool is p0f, a passive fingerprinting program first released in 2000. It watches traffic, matches each SYN against a database of known OS signatures, and prints a guess such as "Windows NT kernel" or "Linux 3.11 and newer". It never sends a packet of its own.
Anti-bot and fraud systems can run the same kind of check on their own servers. The useful signal for them is rarely the OS by itself. It is whether the OS in the packet matches the OS the browser claims. Plenty of real people use Linux. Very few real people send a Chrome on Windows user agent from a machine whose packets say Linux.
Why proxy traffic reads as Linux
When you send a request through a proxy, two separate TCP connections exist. One runs from your machine to the proxy. The other runs from the proxy to the website. The website only ever sees the second one, and the proxy server's operating system writes those packets.
So the fingerprint a website reads through a proxy belongs to the proxy, whatever you run at home:
- Your user agent says Windows, because your browser or automation tool says so.
- Your TLS fingerprint matches Chrome, because HTTPS is encrypted end to end and the TLS handshake still comes from your client.
- Your SYN packet says Linux, because the proxy server wrote it.
That third line is the problem. Nothing in your browser can change it. Stealth plugins, user agent switchers, and browser fingerprint tools all work on your machine, and these packets leave from a different one.
What a Windows fingerprint on the proxy side changes
If the proxy server sends Windows values instead of Linux ones, the layers line up again. A Windows browser through that proxy looks like a Windows machine from the TCP handshake up.
On our network, every connection from every IP now leaves with:
- TTL 128
- A SYN window of 65535 with window scale 8
- The Windows option order: mss, nop, wscale, nop, nop, sackOK
- No TCP timestamps
- A source port between 49152 and 65535
That applies to HTTP, HTTPS, and TCP over SOCKS5. It does not apply to UDP, which has no handshake to fingerprint.
What it does not change
A TCP fingerprint is one signal among several, and it is worth being clear about which ones a proxy controls.
- TLS fingerprint (JA3, JA4). This comes from your HTTP client. Python requests, Go's net/http, and Chrome all produce different ones, and no proxy can change it without breaking HTTPS encryption.
- HTTP/2 fingerprint. Also from your client.
- Browser fingerprint. Canvas, fonts, screen size, and navigator properties come from the browser.
- Your user agent. If it says macOS or iPhone, a Windows TCP fingerprint is now the mismatch. Pair the proxy with a Windows user agent.
- IP reputation. A clean, static IP with a long history still matters more than any packet field.
So a Windows TCP fingerprint will not get an obviously automated client past a site that blocks automation. It removes one easy way for a site to notice that a real-looking browser is behind a proxy.
How to check what your proxy sends
The quickest check is a free echo service. tls.peet.ws returns the TCP, TLS, and HTTP/2 fingerprint of whatever connects to it:
curl -s -x http://user:pass@proxy.statproxies.com:8080 \
https://tls.peet.ws/api/all | jq .tcpip.tcp_syn
Look at ttl, window, window_scale, timestamps, and option_order. A Linux proxy shows a TTL in the 50s, timestamps true, and sackOK near the front of the option order. A Windows fingerprint shows a TTL in the 110s, timestamps false, and wscale second. We walk through this check, plus p0f and tcpdump on your own server, in How to check your proxy's TCP/IP fingerprint.
FAQ
What is TCP/IP fingerprinting?
TCP/IP fingerprinting identifies an operating system from the fields it writes into network packets, mainly the first SYN packet of a TCP connection. The TTL, window size, window scale, TCP option order, timestamps, and source port all differ between Windows, macOS, and Linux.
Can a website see my TCP/IP fingerprint through a proxy?
No. It sees the proxy server's fingerprint, because the proxy opens its own TCP connection to the website. That is why proxy traffic usually reads as Linux, the OS most proxy servers run.
Is TCP/IP fingerprinting the same as TLS fingerprinting?
No. TCP/IP fingerprinting reads the operating system from packet headers. TLS fingerprinting, such as JA3 or JA4, reads the client software from the TLS handshake. Through an HTTPS proxy, the TCP fingerprint comes from the proxy and the TLS fingerprint comes from your own client.
Do Stat Proxies IPs send a Windows TCP/IP fingerprint?
Yes. Every connection from every Stat Proxies IP carries a Windows 11 TCP/IP fingerprint over HTTP, HTTPS, and SOCKS5. It is included free on every plan and needs no configuration.
Can I change my TCP/IP fingerprint from my browser?
No. The TCP/IP fingerprint comes from the operating system that sends the packets. Browser extensions and stealth plugins can change what JavaScript reports, but not the packets your machine or your proxy writes.