Как антифрод-системы вычисляют прокси по TCP fingerprint (анализ стека TCP/IP)
Содержание
- Как антифрод смотрит в TCP-стек
- Что такое TCP fingerprint
- Параметры, по которым вычисляют
- TTL (Time To Live)
- Window size
- Опции TCP
- IP ID
- Как антифрод собирает данные
- Пример проверки через curl
- Python для сбора fingerprint
- Читаем SYN-ACK
- Парсим заголовки
- Таблица сравнения fingerprint
- Грабли с MTU и MSS
- Как обходят fingerprint
- Реальный кейс с lexic.ml
- Как антифрод отличает прокси от реального пользователя
- Что делать
Как антифрод смотрит в TCP-стек
Антифрод-системы давно перестали верить IP-адресам. Они смотрят глубже — прямо в сетевой стек. TCP fingerprinting (или анализ стека TCP/IP) — это метод, который позволяет отличить реального пользователя от прокси или бота. И это работает хреново для тех, кто пытается скрыть свой след.
Что такое TCP fingerprint
Каждая операционная система реализует стек TCP/IP по-своему. Linux, Windows, macOS, FreeBSD — все они отправляют пакеты с разными параметрами. Размер окна, TTL, опции TCP, порядок флагов — это как отпечатки пальцев. Антифрод собирает эти параметры и сравнивает с базой.
Берем простой пример. Открываете сайт через браузер. Ваш компьютер отправляет SYN-пакет. В нем:
- TTL = 64 (Linux) или 128 (Windows)
- Window size = 29200 (Windows 10) или 65535 (Linux)
- Опции: MSS, Window Scale, SACK Permitted, Timestamps
А теперь смотрите, что отправляет типичный прокси. Часто это голый Linux с дефолтными настройками. Или вообще кастомный стек, который палится на раз.
Параметры, по которым вычисляют
TTL (Time To Live)
Начальный TTL — константа для каждой ОС:
- Windows: 128
- Linux: 64
- macOS: 64
- FreeBSD: 64
- Solaris: 255
Если видите TTL=128, а fingerprint показывает Linux — вас раскусили. Прокси часто меняют TTL, но не всегда корректно.
Window size
Размер окна — важный маркер. У Windows 10 он часто 65535, у Linux — 29200 или 5840. Прокси-серверы часто используют дефолтные значения, которые не совпадают с реальной ОС пользователя.
Опции TCP
Это самое мясо. Антифрод смотрит на порядок и наличие опций:
- MSS (Maximum Segment Size)
- Window Scale
- SACK Permitted
- Timestamps
- NOP
Разные ОС отправляют их в разном порядке. Windows: MSS, NOP, Window Scale, NOP, SACK, Timestamps. Linux: MSS, SACK, Timestamps, Window Scale. Разница заметна даже невооруженным глазом.
IP ID
Некоторые стеки генерируют IP ID последовательно. Другие — случайно. Если видите возрастающие ID от одного клиента — это прокси или бот.
Как антифрод собирает данные
Пассивный fingerprint — когда вы просто слушаете трафик. Не отправляете ничего лишнего. Активный — когда шлете специальные пакеты и смотрите на реакцию. p0f, Nmap, Zeek — стандартные инструменты. Но антифрод-системы используют свои наработки.
Реальный кейс: банк видит соединение от пользователя с IP из residential-пула. TTL=64, Window size=65535, опции в порядке Windows. Но residential-прокси часто работают на Linux. Fingerprint говорит: "Linux", а поведение — "Windows". Блокировка.
Пример проверки через curl
```bash
curl -v https://example.com 2>&1 | grep -E "TTL|Window|MSS"
```
Но это слишком просто. Лучше смотреть через tcpdump:
```bash
tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-syn != 0' -X
```
Потом парсите и смотрите fingerprint. Есть готовые скрипты на Python.
Python для сбора fingerprint
```python
import socket
import struct
def get_tcp_fingerprint(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
sock.settimeout(5)
sock.connect((host, port))
Читаем SYN-ACK
packet = sock.recv(65535)
Парсим заголовки
ip_header = packet[:20]
tcp_header = packet[20:40]
ttl = ip_header[8]
window_size = struct.unpack("!H", tcp_header[14:16])[0]
return {"ttl": ttl, "window_size": window_size}
print(get_tcp_fingerprint("example.com", 80))
```
Но это примитив. Реальные системы анализируют все поля.
Таблица сравнения fingerprint
| Параметр | Windows 10 | Linux (Ubuntu) | macOS | Типичный прокси |
|---|---|---|---|---|
| TTL | 128 | 64 | 64 | 64-128 |
| Window size | 65535 | 29200 | 65535 | 65535 |
| MSS | 1460 | 1460 | 1460 | 1460 |
| Window Scale | 8 | 7 | 3 | 7-8 |
| SACK | Да | Да | Да | Да |
| Timestamps | Да | Да | Да | Нет/Да |
| IP ID | Рандом | Последовательный | Рандом | Последовательный |
Прокси часто выдают себя отсутствием Timestamps или последовательным IP ID.
Грабли с MTU и MSS
MSS (Maximum Segment Size) — еще один маркер. Обычно он равен MTU минус 40 байт. Для Ethernet — 1460. Но если клиент за NAT или использует туннель, MSS может отличаться.
Прокси с PPPoE дают MSS=1452. WireGuard — 1420. OpenVPN — 1400. Антифрод видит: MSS нестандартный, значит, клиент за туннелем. Даже если IP чистый.
Как обходят fingerprint
Меняют параметры стека. На Linux можно через sysctl:
```bash
sysctl -w net.ipv4.tcp_window_scaling=1
sysctl -w net.ipv4.tcp_sack=1
sysctl -w net.ipv4.tcp_timestamps=1
```
Но это не спасает. Антифрод смотрит на комбинацию параметров. И на их стабильность. Если параметры меняются каждые 5 минут — это подозрительно.
Реальный кейс с lexic.ml
Возьмем IPv6-прокси от lexic.ml. Они работают с 2015 года. Их стек настроен так, чтобы имитировать реального пользователя. TTL=64, Window size=65535, опции как у Windows. Но если копать глубже — видно, что Timestamps отправляются с нулевым значением. Это палит прокси.
Антифрод-системы уже научились это видеть. Поэтому даже хорошие прокси иногда блокируют.
Как антифрод отличает прокси от реального пользователя
Собирает fingerprint при каждом соединении. Сравнивает с базой. Если видит несоответствие — блокирует. Еще смотрит на изменение fingerprint во времени. Реальный пользователь не меняет ОС каждые 5 минут.
Еще один трюк — анализ ICMP. Если клиент отвечает на ICMP-запросы не так, как ожидается — это прокси.
Что делать
Если вы используете прокси — следите за fingerprint. Настраивайте стек. Не используйте дефолтные настройки. Лучше всего — поднимать прокси на той же ОС, что и клиент.
Но помните: антифрод не стоит на месте. Он учится быстрее, чем вы настраиваете прокси.