# MSS value and VPN detection: what one packet says

> VPN detection by MSS value: a tunnel shrinks the MSS in every SYN. A proxy opens a new connection at the exit, so a site reads the exit's MSS.

Source: https://mosaicbrowser.com/blog/mss-and-mtu-through-a-tunnel

## MSS 1300: what an MSS value says about VPN detection

VPN detection by MSS value: a tunnel shrinks the MSS in every SYN. A proxy opens a new connection at the exit, so a site reads the exit's MSS.

![1300: The segment size belongs to whoever opened the socket](https://mosaicbrowser.com/covers/mss-and-mtu-through-a-tunnel.webp)

An MSS value is the largest TCP payload a machine says it can take, and it travels in the first packet of every connection. A VPN wraps each packet in its own headers, so the MSS drops by that overhead, and a server that reads it can spot the tunnel, which is what MSS-based VPN detection does. An HTTP or SOCKS5 proxy does something else: it opens a fresh TCP connection from the exit, so the MSS a site reads belongs to the exit's network, not to yours.

## Where the number comes from

When a TCP connection starts, each side sends a SYN, and the SYN carries a maximum segment size option. The figure is arithmetic on the link underneath. Ethernet carries 1500 bytes per packet. An IPv4 header takes 20 of them and a TCP header another 20, which leaves 1460. That is the number most of the internet sends. Over IPv6 the IP header is 40 bytes, so the same link gives 1440.

Anything that adds a header in between eats into those 1500 bytes. PPPoE, which plenty of home broadband uses, adds 8, so the MTU becomes 1492 and the MSS 1452. A VPN adds a lot more: an outer IP header, a UDP or TCP header for the tunnel itself, and its own framing and encryption overhead. WireGuard's usual interface MTU of 1420 gives an IPv4 MSS of 1380. OpenVPN and IPsec land lower still, at values that depend on the cipher and the options in use.

Because those values follow from configuration, they are oddly specific. A write-up by ValdikSS showed years ago that a server could tell that a visitor was on OpenVPN, and roughly how it was set up, from the MSS and MTU alone.

Mosaic is a desktop app

Email yourself the link and open it on your computer.

[How it works: Provider minting](https://mosaicbrowser.com/features/proxy-providers)

## Why 1300 matters to VPN detection

PayPal holds two US patents on exactly this, 10038712 and 10659491, filed under the title "dynamic detection of geo-location obfuscation". The method reads the client's MSS from the TCP handshake and looks it up in a table of values known to come from tunnels. The patent gives examples: OpenVPN "will result in an MSS value of 1367", PPTP in 1356.

The striking figure is 1300. In the traffic the patent describes, an MSS of 1300 appeared on about 20.9% of the VPN connections and 0.07% of the ordinary ones. It lists 1300, 1332, 1336, 1367, 1368 and 1369 as the values most likely to mean a tunnel, and it treats 1460 and 1380 as standard.

The MSS is only the first phase. A suspect value sends the connection to a second check, which compares the round-trip time against what is normal for that address range, with a separate threshold for each MSS value. A visitor whose packets claim to start in one city but take far too long to arrive is the case the method scores. Packet size raises the question and latency answers it.

## What a proxy changes

Through a VPN, your computer's own TCP stack builds the connection, and the tunnel's overhead shows up in the SYN the site receives. Through an HTTP or SOCKS5 proxy, it doesn't. The browser's TCP connection ends at the proxy. The proxy then opens its own connection to the site, from the exit machine, with that machine's operating system writing the SYN.

So everything in that first packet is the exit's: its MSS, its window size, its TTL and the order of its TCP options. A residential exit on a household's PPPoE line sends 1452. One on a cable connection sends 1460. A mobile exit sends whatever the carrier's network clamps it to. None of it is set by your computer, and none of it changes if you are on a VPN at home, because the VPN sits between you and the proxy, a hop the site never sees.

The flip side is that this is a fingerprint you rent along with the address. A datacenter exit with a Linux TCP stack sends a Linux-shaped SYN beneath a browser claiming to be Windows. A detector that compares the operating system in the packet with the one in the User-Agent will notice, whatever the browser does. It is the same reason a free proxy that is itself a VPN endpoint can show tunnel values in its SYN: whatever is behind the exit is in the packet.

## What the site can still measure

Changing the source of the SYN does not remove the extra hop. A page that times its own requests in JavaScript measures from the browser to the site through the proxy, while the TCP handshake measures only from the exit. A large gap between the two is the latency half of the patent's method, and a proxy cannot hide it. A nearby exit makes the gap small. One on another continent makes it large.

Traffic that skips the proxy is the other risk, because a packet sent straight from your machine carries your own MSS and your own address. WebRTC is the path that does it if nothing stops it. It can send UDP around the proxy, which is why, by default, Mosaic launches the engine with non-proxied UDP disabled whenever a proxy is attached ([why video calls struggle behind a proxy](https://mosaicbrowser.com/blog/webrtc-calls-behind-a-proxy) is the price of that). QUIC is not a second path of that kind: with an HTTP, HTTPS or SOCKS5 proxy set, Chrome reaches every site over a TCP tunnel and never sends QUIC's UDP at all ([QUIC through a proxy](https://mosaicbrowser.com/blog/chrome-quic-through-a-proxy) has the detail).

## What Mosaic does and does not touch

Mosaic changes what the browser reports, inside Tesseract Chrome, its own Chromium. It does not change the SYN a site receives from a proxy, because that packet is built on the exit's machine. What we can do is make sure every packet a site sees comes from the exit: the proxy is checked before the browser opens, and WebRTC UDP that would go around it is blocked.

So choosing an exit is choosing its MSS. A [residential proxy](https://mosaicbrowser.com/glossary/residential-proxy) brings a household's link and its 1460 or 1452. A datacenter exit brings a server's stack, and a VPN-backed exit brings the tunnel's numbers. Which of those a site will accept is worth checking before an account depends on it, and the checks we run on an address before using it are in [how to check a proxy before you use it](https://mosaicbrowser.com/guides/how-to-check-a-proxy-before-you-use-it).

## Questions

### What MSS value does a normal connection send?

On ordinary Ethernet with a 1500-byte MTU, an IPv4 SYN carries an MSS of 1460: 1500 minus 20 bytes of IP header and 20 of TCP header. Over IPv6 it is 1440, because the IP header is 40 bytes.

### Can a site see my VPN if I also use a proxy in the browser?

Not through the MSS. The VPN sits between your computer and the proxy, and the site's TCP connection starts at the proxy's exit. The site reads the exit's segment size, shaped by the exit's own network.

### Is a low MSS proof of a VPN?

No. PPPoE broadband lowers it to 1452, some mobile networks clamp it, and routers rewrite it. A detector treats an odd value as a reason to look harder, which is how the PayPal patents use it: a first filter, then a latency check.

### Can I change the MSS my proxy's exit sends?

Not from the browser. The segment size is written by the operating system of the machine that opens the connection to the site, which for a proxy is the exit. Mosaic does not touch it, because it is not on your computer.

## Related

[What happens to QUIC when Chrome has a proxy](https://mosaicbrowser.com/blog/chrome-quic-through-a-proxy): With an HTTP, HTTPS or SOCKS5 proxy set, Chrome reaches sites over TCP tunnels, so a page that gets HTTP/3 direct gets HTTP/2 through the proxy.

[What your proxy provider can and cannot see](https://mosaicbrowser.com/blog/what-a-proxy-provider-can-see): Over HTTPS a proxy provider sees each hostname, port, time and byte count, never the pages or passwords. Over plain HTTP it sees everything you send.

[Residential proxy: an exit on a home internet connection](https://mosaicbrowser.com/glossary/residential-proxy): A residential proxy sends your traffic out through an address an ISP assigned to a home connection, so sites see a household rather than a data center.

[Why video calls struggle in a proxied profile](https://mosaicbrowser.com/blog/webrtc-calls-behind-a-proxy): WebRTC sends media over UDP, which an HTTP or SOCKS proxy in Chrome does not carry. With non-proxied UDP blocked, only a TURN relay over TCP is left.

[How to check a proxy before you use it](https://mosaicbrowser.com/guides/how-to-check-a-proxy-before-you-use-it): Check that a proxy answers and tunnels, where its exit really is, whether the address is residential or blocklisted, and that the browser stays behind it.

[Detecting a proxy with two clocks](https://mosaicbrowser.com/blog/proxy-detection-by-latency): A server times the TCP handshake to the exit and a round trip to the browser. Behind a proxy the second is longer, and the gap is the tunnel.

[Through a proxy, your TCP fingerprint is the exit's](https://mosaicbrowser.com/blog/tcp-fingerprint-belongs-to-the-exit): A proxy's exit opens its own TCP connection, so the TTL, window and options a site reads come from the exit's system, not your browser or your computer.

[Pin the country, not the address](https://mosaicbrowser.com/blog/pin-the-country-not-the-address): A residential pool moves your exit whatever you do. The checks that matter compare countries, so pin the country and let the address move inside it.

## Mosaic, on your own computer

The browser this blog is about: its own Chromium, fingerprints from real machines and a proxy exit per profile. Free holds 3 profiles. Pro is $49 a month for any number.

Mosaic is a desktop app

Email yourself the link and open it on your computer.
